Lets say, I have a MxN arrays: int *b; and int **c; where
values in b are stored by columns (from c) and I need to put values
from c to b
values in b are stored by rows (from c) and I need to put values
from c to b
I know that basicly I would do it like that:
j = index / N;
i = index - (j * M);
in order to convert a 1D index into a 2D co-ordinate but have a problem
how to implement those 2 cases, 1) and 2)?
Let W be the width of the 2D array, and H its height. Then assuming row-major layout, the 1D index 'ix' relates to the 2D-index [x,y] as such:
ix = y*w + x;
y = ix / w; // implicit floor
x = ix % w;
e.g.:
const int W = 3, H=2;
int m[H][W] = {{1,2,3}, {4,5,6}};
int* oneD = &m[0][0];
assert(oneD[1*W + 2] == m[1][2]); // element 6, y=1, x=2
Related
I am a physicist currently writing a C++ program dealing with multidimensional integration; in particular, the functions I am considering can have up to D=9 dimensions.
From a mathematical perspective, I need to handle a NxNxN...xN (D times) matrix, but from a programming point of view, I was instructed to use an array of NxNxN...xN elements instead. From what I know, an array is better for the sake of generality and for all the ensuing calculations involving pointers.
However, now I am stuck with a problem I cannot solve.
I need to perform some calculations where a single index of my matrix is fixed and all the other ones take all their different values.
If it were a 3x3x3 matrix, the code would be something 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 have an index fixed and cycle through the other ones.
The same process could be extended to the second and the third index as well.
How can I accomplish the same effect with a double test[3*3*3]? Please keep in mind that the three dimensional matrix is just an example; the real matrices I am dealing with are 9-dimensional, and so I need a general way to keep a single index of my matrix fixed and cycle through all the other ones.
TL;DR: I have an array which represents a NxNxN...xN (9 times) matrix.
I need to perform some calculations on the array as if a single index of my matrix were fixed and all the other ones were cycling through all their possible values.
I know there is a simple expression for the case where a 2-D matrix is mapped in a 1-D array; does something similar exist here?
Raster scan is the standard way of ordering elements for two dimensions.
If you have a 2-D array test[3][3], and you access it by test[i][j], the corresponding one-dimensional array would be
double raster[3 * 3];
and you would access it as follows:
raster[i * 3 + j];
This can be generalized to 3 dimensions:
double raster[3 * 3 * 3];
...
raster[a * 9 + b * 3 + c];
Or to 9 dimensions:
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];
Having any of the a ... i index variables constant, and changing the rest in a loop, will access a 8-D slice in your 9-D array.
You might want to define some struct to hold all these indices, for example:
struct Pos
{
int a, b, c, d, e, f, g, h, i;
};
Then you can convert a position to a 1-D index easily:
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;
}
Generally, a flattened array will contain its elements in the following way: the elements of the last dimension will be mapped into repeated groups, the inner-most groups will be the second dimension from the back and so on:
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 my brain.
So, any element access will need to calculate, how many blocks of elements come before it:
Accessing [2][1][3] means, skip 2 blocks of x, each containing y blocks with z elements, then skip another 1 block of y containing z elements and access the 3rd element from the next block:
values[2 * y * z + 1 * z + 3];
So more generally for N dimensions d1, d2, d3 .. dn, and an n-dimensional index i1, i2, .. iN to be accessed:
[i1 * d2 * ... * dN + i2 * d3 * ... * dN + ... + iN]
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;
}
}
If the matrix has the same size for all dimensions, then you can access them like this:
m[x + y*N + z*N*N + w*N*N*N ...]
In the case that the sizes are different, it is a little bit more complicated:
m[x + y*N1 + z*N1*N2 + w*N1*N2*N3 ...]
I need a 3 dimensional array which supports negative indices.
Something similar to boost::multi_array, where I could specify bounds for each dimension, ie:
int xMin = -5; int xMax = 7;
int yMin = 3; int yMax = 10;
int zMin = -8; int zMax = -2;
SuperArray<float> ar;
ar.setBounds(xMin, xMax, yMin, yMax, zMin, zMax);
ar[-3][5][-5] = 1.0f;
Basically, it's indexing voxel subspace in 3D :)
Is there anything ready outthere, or am I to create this by myself ?
thanks !
Why don't you just do a translation?
Lets say the array size is:
d1 = 100
d2 = 100
d3 = 100
[d1][d2][d3]
// where index 0 = -50 and index 99 = 50
//Pseudo code
// x = -1; y = 2; z = 2;
value = array[d1/2+x][d2/2 + y][d3/2 +z];
Set the size of each dimension to Max-Min. Then when you want to access an array element, add -Min to each index. So for your dimensions, you would declare:
float ar[12][7][6];
Then to access the element you want, you do:
ar[-3-(-5)][5-3][-5-(-8)] = 1.0f;
You should be able to write a class that hides all these transformations (which is what the Boost library is doing).
I've got a question. I'm writing a simple application in C++ and I have the following problem:
I want to use a two-dimensional array to specify the position of an object (x and y coordinates). But when I created such an array, I got many access violation problems, when I accessed it. I'm not pretty sure, where that violations came from, but I think, my stack is not big enough and I shuld use pointers. But when I searched for a solution to use a multidimensional array in heap and point on it, the solutions where too complicated for me.
So I remembered there's a way to use a "normal" one-dimensional array as an multidimensional array. But I do not remember exactly, how I can access it the right way. I declared it this way:
char array [SCREEN_HEIGHT * SCREEN_WIDTH];
Then I tried to fill it this way:
for(int y = 0; y < SCREEN_HEIGHT; y++) {
for(int x = 0; x < SCREEN_WIDTH; x++) {
array [y + x * y] = ' ';
}
}
But this is not right, because the char that is at position y + x * y is not exactly specified (because y + y * x points to the same position)
But I am pretty sure, there was a way to do this. Maybe I am wrong, so tell it to me :D
In this case, a solution to use multidimensional array would be great!
You don't want y + x*y, you want y * SCREEN_WIDTH + x. That said, a 2D array declared as:
char array[SCREEN_HEIGHT][SCREEN_WIDTH];
Has exactly the same memory layout, and you could just access it directly the way you want:
array[y][x] = ' ';
char array2D[ROW_COUNT][COL_COUNT] = { {...} };
char array1D[ROW_COUNT * COL_COUNT];
for (int row = 0; row < ROW_COUNT; row++)
{
for (int col = 0; col < COL_COUNT; col++)
{
array1D[row * COL_COUNT + col] = array2D[row][col];
}
}
You access the correct element for your 1D array by taking "current row * total columns + current column," or vice-versa if you're looping through columns first.
Ive been recently reading Matrix Tutorials with openGL and stumbled upon an optimized method for Matrix Multiplication that I cannot understand.
//Create an allias type for a Matrix Type
typedef struct Matrix
{
float m[16];
} Matrix;
//default matrix
static const Matrix IDENTITY_MATRIX = { {
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
} };
Matrix MultiplyMatrices(const Matrix* m1, const Matrix* m2)
{
Matrix out = IDENTITY_MATRIX;
unsigned int row, column, row_offset;
for (row = 0, row_offset = row * 4; row < 4; ++row, row_offset = row * 4)
for (column = 0; column < 4; ++column)
out.m[row_offset + column] =
(m1->m[row_offset + 0] * m2->m[column + 0]) +
(m1->m[row_offset + 1] * m2->m[column + 4]) +
(m1->m[row_offset + 2] * m2->m[column + 8]) +
(m1->m[row_offset + 3] * m2->m[column + 12]);
return out;
}
These are the questions I have:
In the method MultiplyMatrices why is there a pointer to params m1 and m2? If your just copying their values and returning a new matrix why use a pointer?
Why is the for loop condition identical to its increment?
for (row = 0, row_offset = row * 4; row < 4; ++row, row_offset = row *
4)
The MultiplyMatrices function calculates the product of two matrices. So that's why you need two matrices as the input arguments of this function. Note that the definition of the matrix
typedef struct Matrix
{
float m[16];
} Matrix;
defines a 4 by 4 matrix with a 1-D array. So the offset is 4 for each row. This is just to simulate a 2-D matrix with 1-D array. You need to pass in pointers to two input matrices so that you can get their element values inside the function.
The reason why you see two identical statements in the for loop is:
for (row = 0, row_offset = row * 4; row < 4; ++row, row_offset = row * 4)
Initially the row_offset is set to 0. When the loop is going through each row in the matrix, the row_offset is increasing with row. This is because in the 1-D array representation of 2-D matrix, the a[i][j] element can be written as:
a[i][j] = a[i*num_col+j]
And here num_col is 4. So these two statements are not the same. The first is to initialize. The second is to reset the row_offset when the row index increases by 1.
In the method MultiplyMatrices why is there a pointer to m1 and m2? If your just copying their values why use a pointer?
Maybe I don't understand your question, but how would you propose to do it differently? You're outputting the product into a third memory location out which is the product of m1 and m2. This is the most efficient way..
Why is the for loop condition identical to its increment?
It's not - the ++row increments row before the assignment on each loop. The "condition" is row < 4 which you did not bold - maybe that's the confusion.
As in my previous question, I'm working loading a 1D array with volumetric data of a .raw file. The answer by Jonathan Leffler proved helpful, but now I'm working with a volume dataset of different dimensions (X,Y,Z aren't the same). How would the formula be generalized?
pVolume[((x * 256) + y) * 256 + z] // works when all dims are 256
int XDIM=256, YDIM=256, ZDIM=256; // I want this sizes to be arbitrary
const int size = XDIM*YDIM*ZDIM;
bool LoadVolumeFromFile(const char* fileName) {
FILE *pFile = fopen(fileName,"rb");
if(NULL == pFile) {
return false;
}
GLubyte* pVolume=new GLubyte[size]; //<- here pVolume is a 1D byte array
fread(pVolume,sizeof(GLubyte),size,pFile);
fclose(pFile);
Access in strides follows a simple principle:
A[i][j][k] = B[k + j * Dim3 + i * Dim3 * Dim2];
// k = 1..Dim3, (or 0 <= k < Dim3, as one does in C)
// j = 1..Dim2,
// i = 1..Dim1.
Here B is a 1D array of size Dim1 * Dim2 * Dim3. The formula obviously generalizes to arbitrarily many dimensions. If you want a mnemonic, start the sum with the fasted index, and in each summand you multiply further by the extent of the previous dimension.