How to handle indices of a 9-dimensional matrix

I am a physicist currently writing a C ++ program on multidimensional integration; in particular, the functions I am considering can have up to D = 9 dimensions.

Mathematically, I need to process an NxNxN ... xN matrix (D times), but from a programming perspective, I was tasked with using an array of NxNxN ... xN elements. From what I know, an array is better for generality and for all subsequent calculations using pointers.

However, I am now stuck with a problem that I cannot solve.

I need to do some calculations when one index of my matrix is โ€‹โ€‹fixed and all the others take all their different values.

If it were a 3x3x3 matrix, the code would be similar to the following:

double test[3][3][3];
for(int i=0;i<3;i++) {
    for(int j=0;j<3;j++) {
    test[0][i][j]=i*j;
    }
}

      

i.e. I could fix the index and loop through the others. The same process can be extended to the second and third indexes.

How can I achieve the same effect using double test[3*3*3]

? Keep in mind that the 3D matrix is โ€‹โ€‹just an example; the real matrices I am dealing with are 9-dimensional and so I need a general way of keeping the single index of my matrix and cycling all the others.

TL; DR : I have an array that represents an NxNxN ... xN matrix (9 times). I need to do some calculations on the array, as if one index of my matrix were fixed, and all the others were looped through all possible values.

I know there is a simple expression for the case where a 2D matrix is โ€‹โ€‹displayed in a 1-D array; does something like this exist here?

+3


source to share


3 answers


Raster scanning is the standard way to arrange items for two dimensions.

If you have a 2-D array test[3][3]

and you are accessing it test[i][j]

, then the corresponding one-dimensional array would be

double raster[3 * 3];

      

and you will access it like this:

raster[i * 3 + j];

      

This can be summarized in 3 dimensions:

double raster[3 * 3 * 3];
...
raster[a * 9 + b * 3 + c];

      

Or up to 9 measurements:



double raster[3 * 3 * 3 * 3 * 3 * 3 * 3 * 3 * 3];
...
raster[a * 6561 + b * 2187 + c * 729 + d * 243 + e * 81 + f * 27 + g * 9 + h * 3 + i];

      

If any of the constant index variables are a ... i

constant and change the rest in the loop, you will access the 8-D slice in your 9-D array.


You might want to define some struct

to hold all of these indices, for example:

struct Pos
{
    int a, b, c, d, e, f, g, h, i;
};

      

Then you can easily convert the position to index from 1-D:

int index(Pos p)
{
    return p.a * 6561 + p.b * 2187 + p.c * 729 + p.d * 243 + p.e * 81 + p.f * 27 + p.g * 9 + p.h * 3 + p.i;
}

      

+3


source


Typically, a flattened array will contain its elements as follows: the elements of the last dimension will be mapped into repeating groups, with the innermost groups being the second dimension from the back, etc .:

values[x][y][z] => { x0 = { y0_0 = { z0_0_0, z0_0_1, ..., z0_0_N }, y0_1 = { z0_1_0, z0_1_1, ... }, ... y0_N }, x1 = ... }
values[x*y*z] => { z0_0_0, z0_0_1, ..., z0_0_N, z0_1_0, z0_0_1, ... }

      

I hope this makes sense outside of my brain.

So any access to an element will have to calculate how many blocks of elements are in front of it:

Access to [2][1][3]

means, skip 2 blocks x

, each containing y

blocks with elements z

, then pass another block y

containing elements z

, and access the 3rd element from the following block:



values[2 * y * z + 1 * z + 3];

      

More generally for N dimensions d1, d2, d3 .. dn

and an n-dimensional index i1, i2, .. iN

for access:

[i1 * d2 * ... * dN + i2 * d3 * ... * dN + ... + iN]

      

Let's go back to your example:

double test[3*3*3];
for(int i = 0; i < 3; i++)
{
    for(int j = 0; j < 3; j++)
    {
        // test[0*3*3 + i*3 + j] = i * j;
        test[i*3 + j] = i * j;
    }
}

      

+3


source


If the matrix is โ€‹โ€‹the same size for all dimensions, you can access it like this:

m[x + y*N + z*N*N + w*N*N*N ...]

      

In case the sizes are different, this is a little more complicated:

m[x + y*N1 + z*N1*N2 + w*N1*N2*N3 ...]

      

+1


source







All Articles