SciSharp/Numpy.NET

Array of structs to NDarray

Laur-Ivan opened this issue · 2 comments

Hello!
I have somewhat of a weird question. I am using Numpy.NET with the Unity game engine. Most of it works fine, but I am trying to convert an Array of Vector3 to NDarray, but I had no success yet.
Since that's an Unity specific class, I get why it might not work. But might I define a struct as a wrapper and transform an array of structs to the NDarray? The struct would be very simple, holding three floats (x,y,z).

henon commented

Numpy always usees one dimensional arrays under the hood, in your case a float[]. With that you create your NDArray and then you reshape it to reflect your multi-dimensional data. Check out reshape documentation and try it on a python console to find out more.
Or you create the NDArray with a two dimensional float[,], but Numpy.NET will internally copy that into a 1D array again as you can see in the code of that constructor.

Nucs commented

If you would agree to store the values in a (n, 3) dimension where n is the number of items in the array and 3 is x,y,z in that order.
It seems that Vector3 answers to the constraint 'T : unmanaged' so it can be treated as binary data within unsafe code.
So I'm proposing something like that

struct Vector3 {
    public float x;
    public float y;
    public float z;
}

static unsafe void Main(string[] args) {
    Vector3[] myVectors = new Vector3[100];
    fixed (Vector3* ptr_vector = myVectors) {
        var nd = new Numpy.NDarray(new IntPtr(ptr_vector), (3 * myVectors.Length * sizeof(float)), np.float32);
        nd = nd.reshape(myVectors.Length, 3);
        //TODO: w/e i wanted to do with 'nd'
    }

    //do not use 'nd' outside the fixed block
}

If you are looking to use myVectors outside the fixed block then use GCHandle.Alloc(bytesBuffer, GCHandleType.Pinned).AddrOfPinnedObject to prevent GC from moving it and then use the same NDarray constructor.