Multidimensional Matrix

Hi everyone,

First of all, sorry my english (I am spanish and I don't know writing english very well).

I have a doubt about how to go through a multidimensional matrix generically.

Examples of how to go through in particular cases:

-> 1 dimension:

1
2
3
4
5
unsigned int d0 = 3;
double m[d0];
for (unsigned int i = 0; i < d0; i++){
     m[i] = 0;
}


-> 2 dimensions:

1
2
3
4
5
6
7
8
unsigned int d0 = 3;
unsigned int d1 = 4;
double m[d0][d1];
for (unsigned int i = 0; i < d0; i++){
     for (unsigned int j = 0; j < d1; j++){
          m[i][j] = 0;
     }
}


-> 3 dimensions:

1
2
3
4
5
6
7
8
9
10
11
unsigned int d0 = 3;
unsigned int d1 = 4;
unsigned int d2 = 5;
double m[d0][d1][d2];
for (unsigned int i = 0; i < d0; i++){
     for (unsigned int j = 0; j < d1; j++){
          for (unsigned int k = 0; k < d2; k++){
               m[i][j][k] = 0;
          }
     }
}


-> 4 dimensions:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
unsigned int d0 = 3;
unsigned int d1 = 4;
unsigned int d2 = 5;
unsigned int d3 = 6;
double m[d0][d1][d2][d3];
for (unsigned int i = 0; i < d0; i++){
     for (unsigned int j = 0; j < d1; j++){
          for (unsigned int k = 0; k < d2; k++){
               for (unsigned int l = 0; l < d3; l++){
                    m[i][j][k][l] = 0;
               }
          }
     }
}


How you can see, it is necesary so many for loops as matrix's dimensions.

I want to do an algorithm that go through a multidimensional matrix generically, that is, knowing the number of dimensions and the dimensions of one multidimensional matrix, go through all its elements. For example, it would be to implement this function:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
  * Go through the multidimensional matrix given, assigning zero to all its
  * elements
  * @param dimensionsNumber The number of dimensions of the multidimensional
  * matrix
  * @param dimensions A pointer to the first element of one array of
  * unsigned ints who size is the same as the number of dimensions given, so
  * the ith element is the ith dimension of the multidimensional matrix
  * @param multidimensionalMatrix A pointer to the first element of the
  * multidimensional matrix
  */
void assignZeros(unsigned int dimensionsNumber,
                 unsigned int* dimensions,
                 double* multidimensionalMatrix){

     // How to go through the multidimensional matrix?
}


This function must be used thus, for example:

1
2
3
4
5
6
// 1 dimension //

unsigned int dimensionsNumber = 1;
unsigned int dimensions[1] = {3};
double multidimensionalMatrix[3];
assignZeros(dimensionsNumber, dimensions, multidimensionalMatrix);


1
2
3
4
5
6
7
// 2 dimensions //

unsigned int dimensionsNumber = 2;
unsigned int dimensions[2] = {3, 4};
double multidimensionalMatrix[3][4];
assignZeros(dimensionsNumber, dimensions,
            reinterpret_cast<double*>(multidimensionalMatrix));


1
2
3
4
5
6
7
// 3 dimensions //

unsigned int dimensionsNumber = 3;
unsigned int dimensions[3] = {3, 4, 5};
double multidimensionalMatrix[3][4][5];
assignZeros(dimensionsNumber, dimensions,
            reinterpret_cast<double*>(multidimensionalMatrix));


1
2
3
4
5
6
7
// 4 dimensions //

unsigned int dimensionsNumber = 4;
unsigned int dimensions[4] = {3, 4, 5, 6};
double multidimensionalMatrix[3][4][5][6];
assignZeros(dimensionsNumber, dimensions,
            reinterpret_cast<double*>(multidimensionalMatrix));


Some idea about how implement the function assignZeros?

Thanks.
Last edited on
You could see how this problem was solved in existing libraries, such as boost: http://www.boost.org/doc/libs/release/libs/multi_array/doc/index.html

incidentally, your function calls do not match the prototype, as the third parameter is declared pointer to double, but it's not how it is called in the 2-4 dimensional examples.
I have added a type casting to double* with reinterpret_cast operator to solve the compile time error.

I have been seeying the boost library docs from your link but there go through multidimensional matrix using for loops (so many loops as matrix's dimensions).

It is posible to design an algorithm that go through a multidimensional matrix generically (without writting so many loops as matrix's dimensions)?
how's this ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void assignZeros(unsigned int dimensionsNumber,
                 unsigned int* dimensions,
                 double* multidimensionalMatrix){
   
   if(dimensionsNumber==0) return;
   unsigned int dim = *dimensions;
   
   for(unsigned int i=1;i<dimensionsNumber;++i)
   {
      dim *= *(dimensions + i);
   }
   
   for(unsigned int i=0;i<dim;++i)
   {
      *(multidimensionalMatrix + i) = 0.0;
   }
}
Last edited on
Yes it works.

But what if I like print to standard output all the elements of the multidimensional matrix with the indexs of each element?

The prototype of the function would be:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <iostream>               // Object cout, manipulator endl

using std::cout;
using std::endl;

/**
  * Print all the elements of the multidimensional matrix given, with the indexs of each
  * element
  * @param dimensionsNumber The number of dimensions of the multidimensional
  * matrix
  * @param dimensions A pointer to the first element of one array of
  * unsigned ints who size is the same as the number of dimensions given, so
  * the ith element is the ith dimension of the multidimensional matrix
  * @param multidimensionalMatrix A pointer to the first element of the
  * multidimensional matrix
  */
void print(unsigned int dimensionsNumber,
           unsigned int* dimensions,
           double* multidimensionalMatrix){
     if (dimensionsNumber == 0){
          cout << "Null multidimensional matrix" << endl;
          return;
     }

     // Calculate the size of the multidimensional matrix (the total number of elements).
     // It is the product of all the dimensions
     unsigned long size = 1;
     for (unsigned int i = 0; i < dimensionsNumber; i++){
          size *= dimensions[i];
     }

     for (unsigned long i = 0; i < size; i++){
          // Send to cout the indexes of multidimensionalMatrix[i]
          // How to obtein the indexes of the element multidimensionalMatrix[i] ?
          cout << multidimensionalMatrix[i] << endl;
     }
}


How to obtain the indexes of each elemento of the multidimensional matrix?

Thanks.
Last edited on
You'll need to #include <sstream> and <stdlib.h>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
void print(unsigned int dimensionsNumber,
           unsigned int* dimensions,
           double* multidimensionalMatrix){
     if (dimensionsNumber == 0){
          cout << "Null multidimensional matrix" << endl;
          return;
     }

     // Calculate the size of the multidimensional matrix (the total number of elements).
     // It is the product of all the dimensions
     unsigned long size = 1;
     for (unsigned int i = 0; i < dimensionsNumber; i++){
          size *= dimensions[i];
     }
     
     unsigned int* dim = (unsigned int*)malloc(dimensionsNumber*sizeof(unsigned int));
     
     for(unsigned int i=0;i<dimensionsNumber;++i)
     {
        dim[i]=0;
     }

     for (unsigned long i = 0; i < size; i++){
          // Send to cout the indexes of multidimensionalMatrix[i]
          // How to obtein the indexes of the element multidimensionalMatrix[i] ?
          stringstream ss;
          ss << "[" << dim[0] << "]";
          for(unsigned int j=1;j<dimensionsNumber;++j)
            ss << "[" << dim[j] << "]";
            
          cout << "matrix" << ss.str() << " = " << multidimensionalMatrix[i] << endl;
          
          for(int j=dimensionsNumber-1;j>=0;--j)
          {
            if(dim[j]==dimensions[j]-1)
            {
                dim[j]=0;
            }
            else
            {
                dim[j]++;
                break;
            }
          }
     }
	 
     free(dim);
}
Last edited on
Thanks a lot !!

It works !

Nice algorithm.
I have been seeying the boost library docs from your link but there go through multidimensional matrix using for loops (so many loops as matrix's dimensions).

You must have looked at the tutorial, which doesn't show how to do it, but to zero out a boost.multi-array called A, regardless of the number of dimensions, you'd write (assuming default index_bases()),
std::fill_n(A.origin(), A.num_elements(), 0);
online demo: http://coliru.stacked-crooked.com/a/552cfe51e1652e8d

under the hood, it does more or less the same thing ac517's code does

Topic archived. No new replies allowed.