Put a multidimensional array into a one-dimensional array - c++

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.

Related

understanding Matrix multiplication in CUDA

I am trying to learn CUDA. I started to try matrix multiplication with the help of this article based on GPU.
My main problem is that I am unable too understand how to access 2D array in Kernel since accessing a 2D array is a bit different than the conventional method (matrix[i][j]).
This is the part where i am stuck:
for (int i = 0; i < N; i++) {
tmpSum += A[ROW * N + i] * B[i * N + COL];
}
C[ROW * N + COL] = tmpSum;
I could understand how ROW and COLUMN were derived.
int ROW = blockIdx.y*blockDim.y+threadIdx.y;
int COL = blockIdx.x*blockDim.x+threadIdx.x;
Any explanation with an example is highly appreciated. Thanks!
Matrices are stored contiguously, i.e. every row after the other at consecutive locations. What you see here is called flat adressing, i.e turning the two element index to an offset from the first element.

Reorganizing a vector in c++

I'd like to preface this question with the fact that I am very inexperienced when it comes to coding, so the solution to this problem could be much easier than what I have been trying. I have a vector 'phas' defined as vector<float> phase; that has 7987200 elements and I want to rearrange this vector into 133120 vectors of 60 elements (called line2 defined as vector<long double> line2;). Each vector of 60 should then be placed one after the other in a vector of vectors 'RFlines2' defined as vector< vector<long double> > RFlines2;and RFlines2.resize(7987200);. I want to fill each of the 60 element vectors with elements of 'phas' separated by 128. for example, the first vector of 60 elements would be filled with phas[0], phas[128], phas[256], ... phas[7680]. The second vector of 60 would then be filled with phas[1], phas[129], phas[257], ... phas[7681],...etc. My current code is as follows:
for(int x = 0; x<133120; x++){
if((x == 128 || x == 7680+128 || x == (7680*a)+128)){
x = 7680*a;
a = a + 1;
}
int j = x;
for(int i = 0; i<60;i++){
line2.pushback(i);
line2[i] = phas[j];
j = j + 128;
}
cout<<"This is x: "<<x<<endl;
RFlines2[x] = line2;
line2.clear();
}
however, after 128 iterations of the outter loop (128 vectors of 60 have been created and 7680 elements from phas have been used), I would need the x value to jump to 7680 to avoid putting elements from phas that have already been used into the next vector of 60 since when x = 128 the first element of the next vector of 60 would be phase[128], which was already used as the 2nd element of the first vector of 60. And then after another 128 x iterations, I would need the x value to jump to 15,360 and so on. The code above is my latest attempt, but when I try to do the fftw on each vector of 60 in RFlines2 as follows:
int c = 0;
for(int x = 0; x < 133120; x++){
//cout<<x<<endl;
fftw_plan p2;
inter = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * W);
outter = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * W);
/* cast elements in line to type fftw_complex */
for (int i = 0; i <60; i++) {
//cout<<i<<endl;
//inter[i][0] = phas[i];
//inter[x][0] = zlines[x];
inter[i][0] = RFlines2[x][i];
inter[i][1] = 0;
}
p2 = fftw_plan_dft_1d(60, inter, outter, FFTW_FORWARD, FFTW_ESTIMATE);
fftw_execute(p2);
//inter[x][0].clear();
for(int u = 0; u<60;u++){
if(u == 0){
cout<<' '<<outter[0][0]<<' '<<c++<<endl;
}
}
fftw_free(inter);
fftw_free(outter);
fftw_destroy_plan((p2));
}
the program crashes after displaying outer[0][0] 128 times. Any ideas how to fix this? Also, let me know if anything that I said doesn't make sense and I'll try to clarify. Thanks in advance!
-Mike
I don't know why your code crashes, because I can't see the whole code here. But I'm going to suggest a way to scatter your data and manage your vectors.
(There is an important caveat though: you should not be using vectors (at least not vectors of vectors) for this task; you are better off using 1D vectors and managing the 2D indexing yourself. But this is a performance thing, and does not impact correctness.)
This is how I suggest you fill your RFLines2: (I have not tried this code, so it may not work.)
// first, build the memory for RFLines2...
vector<vector<long double>> RFLines2 (133120, vector<long double>(60));
// assuming a "phase" vector...
for (unsigned i = 0; i < 7987200; ++i)
{
unsigned const row = (i / (128 * 60)) * 128 + (i % (128 * 60)) % 128;
unsigned const col = (i % (128 * 60)) / 128;
RFLines[row][col] = phase[i];
}
You won't need the line2 intermediate this way.
The rest of the code "should" work. (BTW, I don't understand the inner for loop on u at all. What were you trying to do there?)

Iterate through 2D Array block by block in C++

I'm working on a homework assignment for an image shrinking program in C++. My picture is represented by a 2D array of pixels; each pixel is an object with members "red", "green" and "blue." To solve the problem I am trying to access the 2D array one block at a time and then call a function which finds the average RGB value of each block and adds a new pixel to a smaller image array. The size of each block (or scale factor) is input by the user.
As an example, imagine a 100-item 2D array like myArray[10][10]. If the user input a shrink factor of 3, I would need to break out mini 2D arrays of size 3 by 3. I do not have to account for overflow, so in this example I can ignore the last row and the last column.
I have most of the program written, including the function to find the average color. I am confused about how to traverse the 2D array. I know how to cycle through a 2D array sequentially (one row at a time), but I'm not sure how to get little squares within an array.
Any help would be greatly appreciated!
Something like this should work:
for(size_t bx = 0; bx < width; bx += block_width)
for(size_t by = 0; by < height; by += block_height) {
float sum = 0;
for(size_t x = 0; x < block_width; ++x)
for(size_t y = 0; y < block_height; ++y) {
sum += array[bx + x][by + y];
}
average = sum / (block_width * block_height);
new_array[bx][by] = average;
}
width is the whole width, block_width is the length of your blue squares on diagram
This is how you traverse an array in C++:
for(i=0; i < m; i++) {
for(j=0; j < n; j++) {
// do something with myArray[i][j] where i represents the row and j the column
}
}
I'll leave figuring out how to cylcle through the array in different ways as an exercise to the reader.
you could use two nested loops one for x and one for y and move the start point of those loops across the image. As this is homework I wont put any code up but you should be able to work it out.

C++ Filling an 1D array to represent a n-dimensional object based on a straight line segment

READ FIRST: I have rewritten this question with the help of a friend to be hopefully more specific in what is required. It can be found here
I'm not very clear on n-cubes, but I believe they are what I am referring to as the square family.
New Question Wording:
Perhaps I wasn't clear enough. What I'm asking, is how to set a 1D array to hold data for a cloud of a number of evenly-spaced points that form the most complete representation of the space occupied by an n-cube of n dimensions.
In 1D this would simply fill the array with a series of 1D co-ordinates creating a line segment. A 1-cube.
In 2D however this would fill every first co-ordinate to the x value and the every second to the y, generating the most complete square possible for that spacing and number of particles. The most complete possible 2-cube.
In 3D, this would fill ever first with x, every second with y and every third with z, generating the most complete possible cube for that spacing and number of particles. The most complete possible 3-cube.
I wish to be able to do this for any reasonable combination of number of particles, spacing and dimensions. Ideally I could do at least up to a 4-cube using a generic fill algorithm for all n-cubes initialised to double * parts_
Yet another definition of what kind of object I'm trying to represent:
In 1D its a line. Sweep it through the second dimension it becomes a square. Sweep that square through the third, it becomes a cube. I presume this behaviour extends past three dimensions and wish to store a cloud of points representing the space taken up by one of these objects of any reasonable dimension, spacing and number of points in a 1D array.
The original wording of the question:
I'm struggling to find a good way to put this question but here goes. I'm making a system that uses a 1D array implemented as double * parts_ = new double[some_variable];. I want to use this to hold co-ordinates for a particle system that can run in various dimensions.
What I want to be able to do is write a generic fill algorithm for filling this in n-dimensions with a common increment in all direction to a variable size. Examples will serve best I think.
Consider the case where the number of particles stored by the array is 4
In 1D this produces 4 elements in the array because each particle only has one co-ordinate.
1D:
{0, 25, 50, 75};
In 2D this produces 8 elements in the array because each particle has two co-ordinates..
2D:
{0, 0, 0, 25, 25, 0, 25, 25}
In 3D this produces 12 elements in the array because each particle now has three co-ordinates
{0, 0, 0, 0, 0, 25, 0, 0, 50, ... }
These examples are still not quite accurate, but they hopefully will suffice.
The way I would do this normally for two dimensions:
int i = 0;
for(int x = 0; x < parts_size_ / dims_ / dims_ * 25; x += 25) {
for(int y = 0; y < parts_size_ / dims_ / dims_ * 25; y += 25) {
parts_[i] = x;
parts_[i+1] = y;
i+=2;
}
}
How can I implement this for n-dimensions where 25 can be any number?
The straight line part is because it seems to me logical that a line is a somewhat regular shape in 1D, as is a square in 2D, and a cube in 3D. It seems to me that it would follow that there would be similar shapes in this family that could be implemented for 4D and higher dimensions via a similar fill pattern. This is the shape I wish to set my array to represent.
EDIT: Apparently I'm trying to fill this array to represent the n-cube with the fewest missing elements for the given n, spacing and number of elements. If that makes my goal any clearer.
As I understand it, you aren't sure how to process every element in multi-dimensional array (stored as 1D array), where N is arbitrary number of dimensions.
Processing of multidimensional array with arbitrary number of dimensions goes like this:
#include <stdio.h>
#include <vector>
using std::vector;
int main(int argc, char** argv){
int index = 0;
const int numDimensions = 10;
vector<int> counters;
vector<int> dimensionSizes;
counters.resize(numDimensions);
dimensionSizes.resize(numDimensions);
for (int i = 0; i < numDimensions; i++){
counters[i] = 0;
dimensionSizes[i] = 13;
}
long long arraySize = 1;
for (int i = 0; i < numDimensions; i++)
arraySize *= dimensionSizes[i];
printf("%d\n", arraySize);
for (int elementIndex = 0; elementIndex < arraySize; elementIndex++){
fprintf(stderr, "element %08d: ", elementIndex);
for (int i = 0; i < numDimensions; i++)
fprintf(stderr, "%04d ", counters[i]);
fprintf(stderr, "\n");
//at this point you have 1D element index
//AND all n-dimensional coordinates stored in counters array.
//Just use them to for your data
//"counters" is N-dimensional coord. XYZW etc.
for (int i = 0; i < numDimensions; i++){
counters[i] = counters[i] + 1;
if (counters[i] < dimensionSizes[i])
break;
else
counters[i] = 0;
}
}
return 0;
}
Just make an array of structs you need to access in N dimensions, and access them using calculated index somewhere after comment. It is better to use array of structs representing the data you want to be stored in N dimensionals. If you don't want to do that, you'll have to multiply elementIndex by number of doubles per element.

How do you multiply a matrix by itself?

This is what i have so far but I do not think it is right.
for (int i = 0 ; i < 5; i++)
{
for (int j = 0; j < 5; j++)
{
matrix[i][j] += matrix[i][j] * matrix[i][j];
}
}
Suggestion: if it's not a homework don't write your own linear algebra routines, use any of the many peer reviewed libraries that are out there.
Now, about your code, if you want to do a term by term product, then you're doing it wrong, what you're doing is assigning to each value it's square plus the original value (n*n+n or (1+n)*n, whatever you like best)
But if you want to do an authentic matrix multiplication in the algebraic sense, remember that you had to do the scalar product of the first matrix rows by the second matrix columns (or the other way, I'm not very sure now)... something like:
for i in rows:
for j in cols:
result(i,j)=m(i,:)·m(:,j)
and the scalar product "·"
v·w = sum(v(i)*w(i)) for all i in the range of the indices.
Of course, with this method you cannot do the product in place, because you'll need the values that you're overwriting in the next steps.
Also, explaining a little bit further Tyler McHenry's comment, as a consecuence of having to multiply rows by columns, the "inner dimensions" (I'm not sure if that's the correct terminology) of the matrices must match (if A is m x n, B is n x o and A*C is m x o), so in your case, a matrix can be squared only if it's square (he he he).
And if you just want to play a little bit with matrices, then you can try Octave, for example; squaring a matrix is as easy as M*M or M**2.
I don't think you can multiply a matrix by itself in-place.
for (i = 0; i < 5; i++) {
for (j = 0; j < 5; j++) {
product[i][j] = 0;
for (k = 0; k < 5; k++) {
product[i][j] += matrix[i][k] * matrix[k][j];
}
}
}
Even if you use a less naïve matrix multiplication (i.e. something other than this O(n3) algorithm), you still need extra storage.
That's not any matrix multiplication definition I've ever seen. The standard definition is
for (i = 1 to m)
for (j = 1 to n)
result(i, j) = 0
for (k = 1 to s)
result(i, j) += a(i, k) * b(k, j)
to give the algorithm in a sort of pseudocode. In this case, a is a m x s matrix and b is an s x n, the result is a m x n, and subscripts begin with 1..
Note that multiplying a matrix in place is going to get the wrong answer, since you're going to be overwriting values before using them.
It's been too long since I've done matrix math (and I only did a little bit of it, on top), but the += operator takes the value of matrix[i][j] and adds to it the value of matrix[i][j] * matrix[i][j], which I don't think is what you want to do.
Well it looks like what it's doing is squaring the row/column, then adding it to the row/column. Is that what you want it to do? If not, then change it.