How to convert ILArray into double[,] array?

寵の児 提交于 2019-12-04 04:29:46

问题


How convert ILArray into double[,] array

I have ILArray<double> A want to use A.ToArray(), but don't know how to use it

I need to get a double[,] System.Array.


回答1:


There is no natural support for converting an ILArray<double> into an multi dimensional System.Array double[,] in ILNumerics currently. So let's write it!

private static System.Array ToSystemMatrix<T>(ILInArray<T> A) {
    using (ILScope.Enter(A)) {
        // some error checking (to be improved...)
        if (object.Equals(A, null)) throw new ArgumentException("A may not be null");
        if (!A.IsMatrix) throw new ArgumentException("Matrix expected");

        // create return array
        System.Array ret = Array.CreateInstance(typeof(T), A.S.ToIntArray().Reverse().ToArray());
        // fetch underlying system array
        T[] workArr = A.GetArrayForRead();
        // copy memory block 
        Buffer.BlockCopy(workArr, 0, ret, 0, Marshal.SizeOf(typeof(T)) * A.S.NumberOfElements);
        return ret;
    }
}

This function should work on arbitrary ILArray<T> of arbitrary element type and arbitrary sizes / dimensions. (However, as always, you should do extensive testing before going productive!) It creates a new System.Array of the desired size and type and copies all elements in their natural (storage layout) order. The System.Array returned can get cast to the true multidimensional array afterwards.

We use Buffer.BlockCopy in order to copy the elements. Keep in mind, System.Array stores its elements in row major order. ILNumerics (just like FORTRAN, Matlab and others) prefers column major order! So, since we just copy the elements quickly and do no efforts to reorder them in memory, the outcoming array will appear as having the dimensions flipped in comparison to the input array:

ILArray<double> C = ILMath.counter(4, 3);
var exp = ToSystemMatrix<double>(C); 

exp will be of size [3 x 4]. For matrices, this can easily be circumvented by transposing the input array:

var exp = ToSystemMatrix<double>(C.T); 

@Edit: bugfix: used Marshal.Sizeof(T) instead of sizeof(double) @Edit: bugfix: now fixed the fix: used Marshal.Sizeof(typeof(T))



来源:https://stackoverflow.com/questions/19608356/how-to-convert-ilarray-into-double-array

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!