Correct Subscript Ordering for Two Dimensional Arrays - c

I am talking about a zero-indexed matrix of integers denoted by a pointer to pointer, i.e.
int **mat;
Then what is the correct way to represent the mat[m][n] element? Is it
*(*(mat+m)+n)
or is it
*(*(mat+n)+m)
Also, visually speaking, between m and n, which one is the row index or which one is the column index? Or do terms like row and column make any sense here? I am sure I have some conceptual gap here, and some help will be great.

The expression
mat[m][n]
is parsed as
(mat[m])[n]
which is equivalent to
(*(mat + m))[n]
which is in turn equivalent to
*(*(mat + m) + n)
so your initial guess is correct.
As for which of these mean rows and which of these mean columns - in some sense, this is up to you to decide. You're the one creating the array and you can assign it any semantics that you'd like.
On the other hand, if you create a 2D array like this:
int mat[A][B];
then in memory this will be laid out as
[0, 0][0, 1][0, 2]...[0, B-1][1, 0][1, 1][1, 2]... ... [A-1][B-1]
Because of locality of reference, if you read across this in the order shown above (do all of mat[0], then all of mat[1], etc.) than it is to iterate in the reverse order (do mat[0][0], then mat[1][0], then mat[2][0], etc.). In that sense, it's common to treat 2D arrays as having the first component select a row and the second select a column, since that more naturally aligns with how the memory is laid out.

Related

Two dimensional array column major order

This question is given in my assignment, but I am very confused about the notation of array declaration. Any idea what that is supposed to express?
Given a two dimensional array A[2:3, 9:18] stored in column major order with base address 100 and size of each element is 4 bytes. Find the address of A[4,12].
When you're calculating addresses of 2D array elements, you need to know how they're organized. Column-major ordering tells you that the 2D array is arranged as a list of columns. So that means each successive element is the next one in a column, which wraps around to the next adjacent column.
If you know the dimensions of this array, the base address, and the element size, you can calculate the address of an element at a specific row and column. Here's the formula for calculating the address of an element in a row-major ordered array. If you can understand that, you could modify it to work for column-major arrays.
addr = base_addr + row * num_cols * elem_size + col * elem_size;

1 dimensional array for indexing a 3D matrix

I'm trying to write a linear index for 3D matrix. Is there a formula to determine what is the linear index of (i,j,k) th element in a matrix with (nx,ny,nz) dimensions?
Is there any difference whether I'm using C of FORTRAN or something else?
I searched for similar questions but nothing was founded .
Thanks for any guide.
Actually, Fortran is column major order. That means that when linearly indexing a multidimensional array the first index grows faster, i.e.
ind(i,j,k) = i + (j-1)*nx + (k-1)*ny*nx
where I assume indexing from 1. The function ind gives an index the element (i,j,k) would have when looking at the same as a one-dimensional array (e.g., in sequence association).
Most other languages, including C derivatives, use the row-major order, so that the last index grows the fastest. They also index from 0.
ind(i,j,k) = k + j*nz + i*ny*nz
There are also other differences — the multidimensional arrays are actually arrays of arrays (similar to pointers to pointers) in C.

Which piece of code is more efficient?

For initialising all the elements of a 100×100 two-dimensional array, we can do it in two ways:
Method 1:
int a[100][100];
for(i=0; i<100; i++){
for(j=0; j<100; j++){
a[i][j] = 10;
}
}
Method 2:
int a[100][100];
for(j=0; j<100; j++){
for(i=0; i<100; i++){
a[i][j] = 10;
}
}
Now my question is which of the method is more efficient and why?
The first method, since that will access the array sequentially.
C stores 2-dimensional arrays in row-major order, meaning that a[i][j] will be adjacent to a[i][j+1] but not adjacent to a[i+1][j].
Yet another way to say the same thing (that generalizes to >2 dimensions) is that the rightmost index is adjacent in memory. Or that incrementing an index means that you have to jump past all the dimensions to the right of the index you're incrementing.
The C11 standard, section 6.5.2.1.3 indicates that arrays are stored row-major. This means that the first method is accessing memory sequentially, while the second one not. Depending on your CPU's caching mechanism, RAM access mechanism and the dimensions of the array, either could be faster. Generally though, I would say the first method is faster.
When you declare an array like int a[100][100] its memory is laid out the same that if you declared int a[10000] which means that you can access all you cells successively if you just iterate on a.
The standard indicate that the array are stored by rows, which means your first hundred cells in memory will be a[0][0] to a[0][99] then a[1][0] to a[1][99].
On most CPUs, the first method will be faster since the CPU will be able to load (most of) your array into the CPU cache and therefore accessing it quickly. Note that this may vary between different CPUs.
I would suspect both loops to be the same speed, and in fact for the generated code to be identical. Unless the array is volatile, the compiler has the freedom to switch the loops, and it should switch them to whichever order is better for the target machine.
It depends whether the language you are using is a row-major or a column-major. Anything in the memory is laid out always in one dimensional manner, so all the 2D stuff also get converted in 1D way.
Now note that there are two ways to do so.
i*(no. of elements in a row) + j
where i is the row no. and j is the column no.
i*(no. of elements in a column) + j
where i is the column number and j is the row number.
So here first one is a row-major way of converting 2D array into 1D way and second one is a column major way. Languages like C/C++ are row-major so they follow the first way.
Now observe that in the first way, you have point, (0,0) and (1,0) very very far depending upon the number of elements in the row, but (0,0) and (0,1) are adjacent.
So as a final answer, your question depends on programming language whether it is a row-major programming language or column-major.
In C/C++ as they are row-major so the first one will be faster.

algorithm to sort elements of three arrays

Here's the stumper:
Start with three arrays A, B and C with a total of 2n+1 entries.
Write an algorithm to sort all of the entries from all of the arrays
using only the following two methods:
X = sort(X) replaces the array X with the sorted version.
(X , Y) = doubleUp(X , Y) does nothing if X has more elements
than Y, otherwise it removes the first length(X) entries from Y
and appends them to the end of X.
Here's what I've tried so far. If two of the arrays are empty, then just use sort on the nonempty array.
If one of the arrays is empty, then I think I can use doubleUp to get one array to have just one thing and the other array to have everything else, and if that singleton array has the smallest (or largest) element, then that works. So I can use sort after I use doubleUp each time to make sure this happens. I coded this up in Maple and it worked for all the cases I checked.
I have no idea how to do it with 3 arrays though. Anyone have any ideas?
Sounds like nonsense. The total number of entries is odd. The only way to increase the length of an array is to make it the smaller first argument of doubleUp, in which case it ends up with an even number of elements. So unless all the elements are in one array to begin with there's no way to make one array contain all the elements, sorted or otherwise.
So, the desired final result is not a single array containing all the elements in order. Or if it is, then the answer to the question is "it cannot be done".

passing a column out of a matrix to a function in c

I want to pass a particular column of the matrix that I have in my program to a function.
If I use the call <function_name>(<matrix_name>[][<index>]); as the call
then I get the error
error: expected expression before ‘]’
token
So please help me in finding the suitable way
Thanks
The syntax you used doesn't exist.
Matrices are stored in memory by row (or better, by the second dimension, to which you give the semantics of rows), so you cannot natively. You could copy all your column elements in a vector (a single dimension array) and pass it.
If you need to work only by column (and never by row) you could change the semantics you give to the first and to the second dimension: think of your matrix as matrix[row][column] instead of matrix[column][row].
Otherwise, if you need to do this often, look for a better data structure, instead of a simple array.
Because of the way addressing works, you can't simply pass the 'column' since, the 'column' values are actually stored in your 'rows'. This is why your compiler will not allow you to pass no value in your 'row' reference, ie: '[]'.
An easy solution would be to pass the entire matrix, and pass the column index as a seperate integer, and the number of rows. Your function can then iterate through every row to access all members of that column.
ie:
functionName(matrixType** matrixRef, int colIndex, int numRows)
{
for(int i=0; i< numRows; ++i)
matrixType value = matrixRef[i][colIndex]; //Do something
}
You are going to have to reformat the data. The column is not contiguous in memory. If for example you have an array:
arr[5][4]
Then trying to pass a 'column' would be like trying to pass every 5th element in the array. Think of it as one giant array.
There's a few things you need to keep in mind about C here.
I'm assuming your matrix is stored as a 2D array, like this:
float mat[4][4];
What you need to remember is that this is just 16 floats stored in memory consecutively; the fact that you can access mat[3][2] is just a shortcut that the compiler gives you. Unfortunately, it doesn't actually pass any of that metadata on to other function calls. Accessing mat[3][2] is actually a shortcut for:
mat[ (3*4 + 2) ]
When you pass this into a function, you need to specify the bounds of the matrix you're passing in, and then the column number:
void do_processing(float* mat, int columns, int rows, int column_idx)
Inside this function, you'll have to calculate the specific entries yourself, using the formula:
mat[ (column_idx * rows) + row_idx ]

Resources