Arrays of pointer to matrices initialized with arrays - c++

I want to cycle between different matrices using an array of pointer to matrices.I want those matrices' rows initialized using array variables. For different reasons, I can't create a new class.
More specifically I want somethng like that:
First point
#define SIZE size-value
int row1MatrixM [SIZE]= {1,2,3,4,5,1,2,3,4,5};
int row2MatrixM [SIZE] = {2,4,5,7,8,9,10,11,12};
...
Then:
matrixM= {row1MatrixM, row2MatrixM, row3MatrixM .... };
But the complier says I can't initialize a matrix this way.
Now I have:
matrixM, matrixY, matrixX, matrixZ, etc.
Then I would like to access them using pointers, so I would need an array of pointers (a pointer to M, one to Y, etc.)
So I tried to write something like that:
#define NUMBER_OF_MATRICES number-of-matrices-value
int[SIZE][SIZE]* arrayOfPointersToMatrices[NUMBER_OF_MATRICES] = {&matrixM,&matrixY,&matrixX, &matrixZ};
I tried different combinations of [] and ** but no one seems working. I was looking for a type that would allow me to access to the array of pointers (3D array) with brackets:
arrayOfPointersToMatrices[x][y][z]

To get your code working:
Declare the arrays like:
int row1 [NUM_COLS]= {1,2,3,4,5,1,2,3,4,5};
int row2 [NUM_COLS] = {2,4,5,7,8,9,10,11,12};
Declare the 2d matrices like:
int *matrix2d1[NUM_ROWS] = {row1, row2};
int *matrix2d2[NUM_ROWS] = {row3, row4};
Declare the 3d matrices like:
int **matrix3d[NUM_MATRICES] = {matrix2d1, matrix2d2};
An alternative (the "right" way)
I would highly highly highly suggest using vectors. They're baked into the C++ language and infinitely easier than all this array/pointer work.

Related

How to pass dynamic and static 2d arrays as void pointer?

for a project using Tensorflow's C API I have to pass a void pointer (void*) to a method of Tensorflow. In the examples the void* points to a 2d array, which also worked for me. However now I have array dimensions which do not allow me to use the stack, which is why I have to use a dynamic array or a vector.
I managed to create a dynamic array with the same entries like this:
float** normalizedInputs;//
normalizedInputs = new float* [noCellsPatches];
for(int i = 0; i < noCellsPatches; ++i)
{
normalizedInputs[i] = new float[no_input_sizes];
}
for(int i=0;i<noCellsPatches;i++)
{
for(int j=0;j<no_input_sizes;j++)
{
normalizedInputs[i][j]=inVals.at(no_input_sizes*i+j);
////
////
//normalizedInputs[i][j]=(inVals.at(no_input_sizes*i+j)-inputMeanValues.at(j))/inputVarValues.at(j);
}
}
The function call needing the void* looks like this:
TF_Tensor* input_value = TF_NewTensor(TF_FLOAT,in_dims_arr,2,normalizedInputs,num_bytes_in,&Deallocator, 0);
In argument 4 you see the "normalizedInputs" array. When I run my program now, the calculated results are totally wrong. When I go back to the static array they are right again. What do I have to change?
Greets and thanks in advance!
Edit: I also noted that the TF_Tensor* input_value holds totally different values for both cases (for dynamic it has many 0 and nan entries). Is there a way to solve this by using a std::vector<std::vector<float>>?
Respectively: is there any valid way pass a consecutive dynamic 2d data structure to a function as void*?
In argument 4 you see the "normalizedInputs" array. When I run my program now, the calculated results are totally wrong.
The reason this doesn't work is because you are passing the pointers array as data. In this case you would have to use normalizedInputs[0] or the equivalent more explicit expression &normalizedInputs[0][0]. However there is another bigger problem with this code.
Since you are using new inside a loop you won't have contiguous data which TF_NewTensor expects. There are several solutions to this.
If you really need a 2d-array you can get away with two allocations. One for the pointers and one for the data. Then set the pointers into the data array appropriately.
float **normalizedInputs = new float* [noCellsPatches]; // allocate pointers
normalizedInputs[0] = new float [noCellsPatches*no_input_sizes]; // allocate data
// set pointers
for (int i = 1; i < noCellsPatches; ++i) {
normalizedInputs[i] = &normalizedInputs[i-1][no_input_sizes];
}
Then you can use normalizedInputs[i][j] as normal in C++ and the normalizedInputs[0] or &normalizedInputs[0][0] expression for your TF_NewTensor call.
Here is a mechanically simpler solution, just use a flat 1d array.
float * normalizedInputs = new float [noCellsPatches*no_input_sizes];
You access the i,j-th element by normalizedInputs[i*no_input_sizes+j] and you can use it directly in the TF_NewTensor call without worrying about any addresses.
C++ standard does its best to prevent programmers to use raw arrays, specifically multi-dimensional ones.
From your comment, your statically declared array is declared as:
float normalizedInputs[noCellsPatches][no_input_sizes];
If noCellsPatches and no_input_sizes are both compile time constants you have a correct program declaring a true 2D array. If they are not constants, you are declaring a 2D Variable Length Array... which does not exist in C++ standard. Fortunately, gcc allow it as an extension, but not MSVC nor clang.
If you want to declare a dynamic 2D array with non constant rows and columns, and use gcc, you can do that:
int (*arr0)[cols] = (int (*) [cols]) new int [rows*cols];
(the naive int (*arr0)[cols] = new int [rows][cols]; was rejected by my gcc 5.4.0)
It is definitely not correct C++ but is accepted by gcc and does what is expected.
The trick is that we all know that the size of an array of size n in n times the size of one element. A 2D array of rows rows of columnscolumns if then rows times the size of one row, which is columns when measured in underlying elements (here int). So we ask gcc to allocate a 1D array of the size of the 2D array and take enough liberalities with the strict aliasing rule to process it as the 2D array we wanted. As previously said, it violates the strict aliasing rule and use VLA in C++, but gcc accepts it.

Does an array of vectors form a 2D vector?

Does the following statements form a 2D vector?
Also mention the dimensions of the vector if it does. Is there another way of declaring a global 2D vector?
Statements:
vector<int> *adj;
adj = new vector<int>[number_of_nodes];
The above statements have been used for declaration of a global adjacency matrix for a graph.
It seems the question isn't clear to much of you. I want to declare a global adjacency list using vectors such that I can use direct addition of edges in graph like v[a].push_back(b). For that, I have to specify first dimension of vector while declaring which I don't have until the main is executed.
No, but it gives similar behaviour. So what you have created is a pointer to an array of vectors. So you will end up with this:
adj[0] = []
adj[1] = []
...
adj[number_nodes] = []
and doing a push_back is a legitimate way to add to the vectors:
adj[0].push_back(some_num) --> adj[0] = [some_num]
But this is a terrible way to approach this! Why?
You are using raw memory that you will have to manage and make sure you delete.
You cant use any of the awesome std::vector functionality on the first dimension of the matrix.
There is no good way to figure out the size of the vector unless you know about the variable number_of_nodes.
... A long list, but you get it.
You can already see that a std::vector can be used as a 1D matrix. So use 2 vectors:
std::vector<std::vector<int>> Matrix2D;
If you need an initial size in some dimension then you can do this:
std::vector<std::vector<int>> Matrix2D(number_of_nodes, std::vector<int>());
Or this:
Matrix2D.resize(number_of_nodes);
Or if that size is fixed at compile time then you could even do this:
const int number_of_nodes = 10;
std::array<std::vector<int>, number_of_nodes> Matrix2D;
Or go extra big and get a library for Matrix use like Eigen.

Trouble with initializing multidimensional array

We usually initialize a 2D array like this:
int a[2][3] = {{2,3,4},{5,6,7}};
I need to initialize the 2D array like this:
int a[2][3];
a[0] = {2,3,4};
a[1] = {5,6,7};
i.e. I want initialize it array by array. Why does this method fail? What should I do? Or can I define a as array of array?
The idea of an array is to keep all the data in memory contiguous, this would not be achieved with the approach you are using, I would recommend using a C style memory management with RAW memory for a low level fast, thigh and possibly dangerous solution, or change to a different data container like the vector (or others) where you can add elements similar to what you want and the memory will still be contagious like the simple array. Although depending on the size of your problem it might be an overkill to use a vector.

How to give names of 2D arrays dynamically in C++?

I want to create few 2D arrays of the same size. e.g. table1[80][3], table2[80][3], table3[80][3], ..., tableN[80][3]. But the number(N) of arrays to create, will be provided by the user.
So, how can I create those arrays dynamically?
Thanks in advance.. :)
You can't have dynamic symbol names of variables or functions in c++. These only matter during compilation of the code, and there's no way to generate them at run time of your program.
As mentioned in my comment, the closest thing you can get is to map those tables with certain std::string values like
std::map<std::string,std::array<std::array<int,3>,80>> tables;
and manipulate values like this
tables["table1"][20][1] = 0;
tables["table2"][10][0] = 42;
// etc. ...
Sounds like a 3d array:
typedef int T[80][3]; // T is your 2d array type
T* tables = new T[N]; // an array of N T's.
Or an amusing mixture of arrays and vectors:
std::vector<T> tables(N); // the same, but safer
Sure, these aren't named... but is table1 really better than tables[0]? Your mileage may vary.

Passing a 3-dimensional variable size array by reference in C++

I've been working off of Passing a 2D array to a C++ function , as well as a few other similar articles. However, I'm running into a problem wherein the array I'm creating has two dimensions of variable size.
The initialization looks like:
int** mulePosition;
mulePosition = new int *[boardSize][boardSize][2];
The function looks like:
int moveMule (int boardSize, int ***mulePosition)
And the references look like
moveMule (boardSize, mulePosition)
Boardsize is defined at the beginning of the function, but may change per execution.
The array, properly sized, would be int [boardSize][boardSize][2].
Either use a plain '3-dimensional' array via
int* mulePosition = new int[boardsize*boardsize*2];
and address its elements calculating the offset from the beginning: mulePosition[a][b][c] is mulePosition[boardSize*2*a + 2*b + c],
or use array of arrays of arrays (which would correspond to your int*** declaration) or better (and simpler) vector of vectors of vectors, although the initialization would be a little more complex (you would need to initialize every array/vector).
Either use a std::vector<std::vector<int>> if boardSize is not a const or std::array<std::array<boardSize>, boardSize> (see Multidimensional std::array for how to initialize the std::array).
That being said, it looks like a good idea to hide this in a class Board which provides a nice interface.