Difficulty copying multi dimensional static array to dynamic array.

Bill Baxter dnewsgroup at billbaxter.com
Sun Feb 24 16:48:21 PST 2008


Spacen Jasset wrote:
> I have more than one problem in this class (errors below), but my focus 
> it to return a dynamic array of float[4][4] which is copied from a 
> static array of float[4][4]. I am having trouble finding how to do this.
> 
> class Matrix
> {
>     float[][] toFloatArray4x4()
>     {
>         float f[4][4] = matrix.dup;
>         return f;
>     }
>     
>     void toFloatArray16(float flat[16])
>     {
>         flat[]=matrix_flat[];
>     }
> private:
>     union
>     {
>         float matrix[4][4];
>         float matrix_flat[16];
>     }
> }
> 
> matrix.d(74): Error: cannot implicitly convert expression 
> (_adDupT(&_D14TypeInfo_G4G4f6__initZ,cast(float[4u][])(this.matrix))) of 
> type float[4u][] to float[]
> matrix.d(75): Error: cannot implicitly convert expression (f) of type 
> float[4u][4u] to float[][]
> matrix.d(75): Error: escaping reference to local f


matrix.dup is going to only copy the pointers to the 4 sub-arrays. 
Those sub-arrays are float[4u] static arrays.
So you get back a dynamic array of static arrays.
float[4u][] just like the compiler is telling you.

I think if you really want to make a dynamic array of dynamic arrays 
that still points to the same memory as the original you're going to 
have to do something like:

    float f[][] ret;
    ret.length = 4;
    foreach(i,ref v; matrix) {
       ret[i] = matrix[i][0..4];
    }
    return ret;

If you intend that to be a copy, then make it matrix[i].dup

But is it something you really need to be able to do?
You will get back a dynamic array that isn't really dynamic.  Resizing 
it will cause it to become distinct from the original static array's 
memory.  Double indexed arrays aren't really a great representation for 
matrices anyway, since every access requires a double indirection. 
Furthermore, the float[][] interface allows you to make ragged arrays, 
that is, if you have a "float[][] M" you can't really be sure if every 
row has the same length as M[0] unless you check them all because some 
silly user might have changed the length of just the 3rd row or 
something.  Finally, for many purposes (OpenGL and and calling Fortran 
numeric routines) column-major ordering is needed.  With column major 
ordering M[i][j] is the i'th column, j'th row, which just looks wrong to 
anyone who's done much linear algebra.

If you're interested I can point you to two other matrix classes where 
you can probably find answers most other issues you'll run across:

http://www.dsource.org/projects/openmeshd/browser/trunk/Helix/helix/linalgebra.d
http://www.dsource.org/projects/openmeshd/browser/trunk/OpenMeshD/OpenMesh/Core/Geometry/MatrixT.d
And here are some others I found but can't vouch for because I've never 
used 'em:
http://www.dsource.org/projects/arclib/browser/trunk/arclib/arc/math/matrix.d
http://www.dsource.org/projects/yage/browser/trunk/src/yage/core/matrix.d
http://www.dsource.org/projects/mathematics/browser/trunk/mathematics/numerical/Matrix.d
--bb


More information about the Digitalmars-d-learn mailing list