# How to make this "for loop"

• 09-22-2008
kurko82
How to make this "for loop"
Hi. I made a function in Matlab for image processing (with 256x256 arrays), but it contains a "for loop" that make it slow. So I think it'd be faster in c++, but i'm just a beginner and i don't know how to work with 2D arrays.

My Matlab code is:
Code:

```[data2]=functionx(data,fx,fy) //data2 is an output array 256x256; data,fx,fy are 256x256 inputs [Lx,Ly]=size(data); //Lx is number of rows, Ly columns data2 = zeros(Lx,Ly); //preallocate an array 2D for x = 1:Lx-1   for y = 1:Ly-1                  dx = x + fx(x,y);       dy = y + fy(x,y);             ix = floor(dx); //floor rounds the element dx to the nearest integer towards minus infinity       iy = floor(dy);             ax = 1 - (dx - ix);       ay = 1 - (dy - iy);                   if ix>0 & iy>0 & ix<Lx & iy<Ly         data2(x,y) = ax*ay*data(ix,iy) + (1-ax)*ay*data(ix+1,iy) + ax*(1-ay)*data(ix,iy+1) + (1-ax)*(1-ay)*data(ix+1,iy+1);       end   end end```
Well, it isn't a difficult code and i don't ask for all it, only how to work with 2D arrays (create 2D arrays, arrays sum, access to a value). Thanks a lot for your time.
• 09-22-2008
EOP
This doesn't really look like C++ imho. :confused:
• 09-22-2008
matsp
No, the original post says that it's "matlab", which has somewhat different syntax. I believe the following:
Code:

`for x = 1:Lx-1`
translates to C (or C++) as:
Code:

```int x; for(x = 1; x <= Lx-1; x++)```
Code:

`ax*ay*data(ix,iy)`
would be:
ax*ay*data[ix][iy];
[/code]

And you would declare data[] and data2[] as this:
Code:

```double data[Lx][Ly]; double data2[Lx][Ly];```
--
Mats
• 09-22-2008
kurko82
Quote:

Originally Posted by matsp

And you would declare data[] and data2[] as this:
Code:

```double data[Lx][Ly]; double data2[Lx][Ly];```
--
Mats

Hi Mats. Thanks for your answer. The problem is that data is an input array, so I have to put their values to a new array, or do i have to use a pointer to this array?
• 09-22-2008
matsp
Quote:

Originally Posted by kurko82
Hi Mats. Thanks for your answer. The problem is that data is an input array, so I have to put their values to a new array, or do i have to use a pointer to this array?

Depends on whether you want the original data to remain the same, or it's ok to write back the result to the old array. Looking at this:
Code:

`data2(x,y) = ax*ay*data(ix,iy) + (1-ax)*ay*data(ix+1,iy) + ax*(1-ay)*data(ix,iy+1) + (1-ax)*(1-ay)*data(ix+1,iy+1);`
, it looks like you MAY use the same positions in data[x][y] more than once, so you have to retain the old value until you are completely finished.

--
Mats
• 09-22-2008
C_ntua
Here are some basic things you might want to know:
Create:
1) You create the array by declaring it (like mastp noted). You should keep in mind that you might need to dynamically allocate it (with new), but that is a different story, which I don't think you mind at the moment.
Assign:
2) You access a value with the [][] symbols. Like array[10][2] is the element on the 11th line and 3nd row. Note that arrays in C/C++ start from ZERO!
Sum:
3) To sum the values of an array you just have to make a function. If you want something particular ask. I don't know exactly what you mean by sum array (sum every value, sum every value of each line and return a vector?). In any case here is a function that sums every value and returns a double (floating number with double precision) with the result
Code:

```double sum2DArray(double **array, int rows, int columns) {   double sum = 0;   for (int i=0; i<rows; ++i)       for (int j=0; j<columns; ++j)             sum += array[i][j];   return sum; } //Use it like this double data[100][10]; //declare the 2D array double sum; //declare the integer that holds the sum sum = sum2DArray9(data, 100, 10); //assign to sum the sum of the array```
• 09-22-2008
kurko82
Quote:

Originally Posted by matsp
Depends on whether you want the original data to remain the same, or it's ok to write back the result to the old array. Looking at this:
Code:

`data2(x,y) = ax*ay*data(ix,iy) + (1-ax)*ay*data(ix+1,iy) + ax*(1-ay)*data(ix,iy+1) + (1-ax)*(1-ay)*data(ix+1,iy+1);`
, it looks like you MAY use the same positions in data[x][y] more than once, so you have to retain the old value until you are completely finished.

--
Mats

lol, thanks for your answer and for your correction (have to -> may, i may improve my english).
Well, data2 is an output array and its values are added each "for loop" iteration, and data is only for reading values. So, how could I write this line code?

Another question. I'm writing a Mexfile, so code works with MxArray. To pass the values of an input MxArray to an array2D, is it possible this code?

Code:

```typedef double TIPO;      // macros before main typedef TIPO** IMAGEN; //rowsT and columnsT are the size data2 = new TIPO* [rowsT];      // It creates output array for (i = 0; i < rowsT; ++i)      data2[i] = new TIPO [columnsT]; //Write mxArray data to array2D data2 salida = mxGetPr(Tu_ptr); //I think this isn't correct, because i'm very bad with pointers```
• 09-22-2008
kurko82
Quote:

Originally Posted by C_ntua
Here are some basic things you might want to know:
Create:
1) You create the array by declaring it (like mastp noted). You should keep in mind that you might need to dynamically allocate it (with new), but that is a different story, which I don't think you mind at the moment.
Assign:
2) You access a value with the [][] symbols. Like array[10][2] is the element on the 11th line and 3nd row. Note that arrays in C/C++ start from ZERO!
Sum:
3) To sum the values of an array you just have to make a function. If you want something particular ask. I don't know exactly what you mean by sum array (sum every value, sum every value of each line and return a vector?). In any case here is a function that sums every value and returns a double (floating number with double precision) with the result
Code:

```double sum2DArray(double **array, int rows, int columns) {   double sum = 0;   for (int i=0; i<rows; ++i)       for (int j=0; j<columns; ++j)             sum += array[i][j];   return sum; } //Use it like this double data[100][10]; //declare the 2D array double sum; //declare the integer that holds the sum sum = sum2DArray9(data, 100, 10); //assign to sum the sum of the array```

OK, you are right, I explained it better last message. My problem with arrays come when I try to write in array2D all MxArray values. MxArray is a double matrix(array2D). And thanks for your sum code, it will be useful for me ;)
• 09-22-2008
C_ntua
Just to add that you still need to declare data2 (if you hadn't already). You could do both the allocation and declaration in one line like this:
Code:

```double** data2 = new TIPO* [rowsT]; //or IMAGEN data2 = new TIPO* [rowsT]; //or in two lines double** data2; data2 = new TIPO* [rowsT];```
As for your question the way you do it is fine. Just replace data2(x,y) with data2[x][y] etc etc and your code is fine.

• 09-22-2008
C_ntua
So mxArray is a 2D array of doubles. And data2 is a 2D array of doubles. Correct? In order to copy one array to another you just assign each individual value with a double for loop. That is the only way. Now, I ll give you a function for that, since I have some minutes to kill :)
Code:

```void copy2DArray (double** input, double** output, int rows, int columns) {   for (int i=0; i<rows; ++i)       for (int j=0; j<columns; ++j)         output[i][j] = input[i][j]; }```
The above code copies the array input to the array output. So copy2DArray(data, data2, rowsT, columnsT) will copy each value of data to data2. More specific it will copy the subarray defined by the rows, columns parameters of the function.
Now. If you want a function that creates a copy (thus,also allocates) then here is one:
Code:

```double** copy2DArray (double** input, int rows, int columns) {   double** output = new double* [rows];   double* temp = new double[rows*columns];   for (int i=0; i<rows; ++i)       output[i] = temp+i*columns;   for (int i=0; i<rows; ++i)       for (int j=0; j<columns; ++j)         output[i][j] = input[i][j];   return output; }```
Now, you can create a 2D array like this. It will be initialized with the values of data[][]
Code:

`double** data2 = copy2DArray(data, rowsT, columnsT);`
Note: I used another method of dynamically allocating ouput inside copy2DArray. A bit more complicated but it should be a bit more efficient (details details).

EDIT: You might have some problems with the above code if the input data is not allocated with the new operator, since the type of double** and double[][] will conflict. I ll see into this if that is the kind of function you want
• 09-23-2008
kurko82

Code:

```for (int x = 0; x < rows; x++){     for(int y = 0; y < cols; y++){       data2[x * cols + y] = ax*ay*data[x * cols + y] + .....   } }```
• 09-23-2008
C_ntua
Nice :) A little better way is to use a macro to do this. Adding this code, preferably under the declaration of data2:
Code:

`#define data2(x,y)  data2[(x) *cols + (y)]`
will let you use the index as in matlab. This is actually a common "trick" in order to define multidimensional arrays in the form of a fucntion (parenthesis instead of []). data2 will actually be a 1D array, but you will use it, like data(x,y), with a 2D indexing. This will make simpler also the allocation for example, as it is actually a 1D array than a 2D.
It is exactly the same as your code, it will just help you right faster the indexing and be far more undertandable than [x*cols +y].

Just to add, even though I said this before, that in C the index starts from 0, but in matlab it starts from 1. For just the for-loop is fine, but since you use the x,y in your matlab code, make sure that you get the desired results for x = 0 and y = 0. The same for the upper bounds that might be one less.

In any case, you can pretend that the arrays start from 1 also in C and just ignore the very first element. That will guarantee that you won't have a bug by changing the index.
• 09-23-2008
kurko82
Quote:

Originally Posted by C_ntua
Nice :) A little better way is to use a macro to do this. Adding this code, preferably under the declaration of data2:
Code:

`#define data2(x,y)  data2[(x) *cols + (y)]`
will let you use the index as in matlab. This is actually a common "trick" in order to define multidimensional arrays in the form of a fucntion (parenthesis instead of []). data2 will actually be a 1D array, but you will use it, like data(x,y), with a 2D indexing. This will make simpler also the allocation for example, as it is actually a 1D array than a 2D.
It is exactly the same as your code, it will just help you right faster the indexing and be far more undertandable than [x*cols +y].

Just to add, even though I said this before, that in C the index starts from 0, but in matlab it starts from 1. For just the for-loop is fine, but since you use the x,y in your matlab code, make sure that you get the desired results for x = 0 and y = 0. The same for the upper bounds that might be one less.

In any case, you can pretend that the arrays start from 1 also in C and just ignore the very first element. That will guarantee that you won't have a bug by changing the index.

You are right. In fact, I have just made a function to do the index:

Code:

```int coord(int i, int j, int cols) { return (j-1) * cols + (i-1); } for (int x = 1; x < filas; x++){     for(int y = 1; y < cols; y++){       data2[coord(x,y,cols)] = ......     } }```
And macro is a good idea, but might I define a macro to each array? Because I use 4 arrays.
• 09-23-2008
matsp
Or, since it's a C++ function, you could make your data and data2 into an object, and make a function operator(int x, int y) which gives a reference to the relevant entry.

--
Mats
• 09-23-2008
CornedBee
And finally, there's Boost.MultiArray, which does exactly this.