Size of a Matrix declared dynamically on C - c

I've declared a matrix dynamically as follows
double **y;
y = (double **)malloc(n*sizeof(double *));
for(i=0;i<n;i++)
y[i]=(double*)malloc(m*sizeof(double));
Where m and n are integers declared before.
Then, I need to compute a function that multiplies two different matrix, and I need to check if the number of rows on the first matrix coincides with the number of columns on the second matrix. So I need to know the numbers of columns and rows.
So I computed what follows:
int k=sizeof(M[0])/sizeof(double);
But this integer k returns me 1. And no matther how long n and m are...
What am I doing wrong?
Thanks and sorry for my english.

You cannot use sizeof operator on dynamically created array to get array size. If array is created dynamically the only option to know it's size is to store it somewhere.

Using sizeof(M[0]) only gets you the type size of M[0] which is double * which in your case identical to size of double
So in your case you have to save the size of the allocated array (n, m).
Another solution would be to use stack allocation where sizeof can actually get the size of types like double[]

Related

Multidimensional array from text file

Im looking for a way to fill up a multi-d array with numbers gotten from a text file.
I have an array(?) dynamically created, but im not sure how to make it multidimensional.
basically the text document has a set of numbers, user input decides the amount of columns and rows of a matrix, and i need to fill that matrix with numbers from the text document. Any help is appreciated
ptrm2 = (int*)malloc(size2 *sizeof(int));
You can allocate a two-dimensional array in two stages, as follows (I'm assuming that the base data type is int here, but it could be almost anything):
int** my2dArray = malloc(sizeof(int*) * n_rows); // Makes one INTEGER POINTER for each of n_rows
for (int n = 0; n < n_rows; ++n) my2dArray[n] = malloc(sizeof(int) * n_cols); // Makes one INTEGER for each column
You can then access any element of the 2-D array, given its row and column with, for example:
int value = my2dArray[row][column];
Here, I've assumed the conventional (standard) approach of using "row priority" (so that the first index is the row).

Efficiently sort a column of a two-dimensional array in C

I create a 2-dimensional Array in C via malloc like this:
double **x;
x = malloc(rows * sizeof(double*));
for (n = 0; n < rows; n++){
x[n] = malloc(columns * sizeof(double));
memset(x[n], 0, columns * sizeof(double));
}
I also check if malloc failed but for better readibility I posted that version. It actually works fine.
Now I have a function which is qsorting the elements row-wise:
double qsort_row_wise(double points[], int points_count)
Which I can call for a specific row(number 3 / 4th row) with 4+1 columns by:
my_qsort(x[3], 4);
This function is receiving a normal array and is also working well.
Now I want to use this function to qsort a column. That's why I am searching for something like this(which is not working):
my_qsort(x[][3], 4);
x[][3] here means a vector of all elements of the column 3.
If possible I would like to do a "vector"-like operation, not selecting everything step by step(for loop) for best performance.
Since you want a 2D array, it is better to allocate it as a single contiguous block:
double *x = calloc(rows * columns, sizeof(double)); // does zero init
Now you can index using arithmetic, so your my_qsort function should be declared like this:
void my_qsort(double *start, size_t count, size_t stride);
Now to sort row 3 you can do this:
my_qsort(x + 3 * columns, columns, 1);
And to sort column 5 you can do this:
my_qsort(x + 5, rows, columns);
During the sort, the elements you need to access are start[ii * stride], where ii goes from 0 to count. And start of course is simply the first cell in the 2D array that you wish to sort--typically either the leftmost cell in a row or the top cell in a column. It is also possible to use the same function to sort part of a row or column, or to sort an arbitrary "line" through the matrix, e.g. the diagonal of a square matrix:
my_qsort(x, rows, columns + 1);
Having a single allocation to store your 2D array not only makes "strided" operations easier, it is also more efficient, because it reduces the number of allocations, improves spatial locality, and on Linux, increases the chances that the memory will be instantly reclaimed when you free it, because "large" allocations are done via mmap rather than sbrk.
Well, you need to create an array the size of how many rows you have since a columns consists of n rows.
double *cols = malloc(nofrows * sizeof(double));
then loop through the 2 dimensional array over the rows and use the column index as a constant:
int whichcolumn = 1;
for (int i = 0; i < rows; i++)
cols[i] = x[i][whichcolumn];
then pass cols to the qsort function
qsort_row_wise(cols, nofrows);
If possible I would like to do a vector-operation, not selecting everything step by step(for loop) for best performance.
This is not possible.
What your 1st code snippet creates isn't a 2D-array, but one 1D-array of pointers, with each element pointing to a 1D-array of doubles. Such a construct sometimes is called a "scattered" array, as it consists of "number of rows"+1 not necessarily continuous blocks of memory.
Concluding from the latter fact, you cannot extract a column, as the elements are distributed throughout the memory and cannot be addressed by a single operation.

C extract an array from a matrix using pointers

I wrote a code and I have some data stored in a 2d matrix:
double y[LENGTH][2];
I have a function that take as input a 1D array:
double function(double* data)
I am interested in passing the data stored in the first column of this matrix to this function. How can I do that using pointers?
My function is something like (where the array data is an array of double containing LENGTH elements:
double data[LENGTH];
):
double function(double* data){
double result=0;
for(int i=0; i<LENGTH; i++){
result+=data[i];
}
return result;
}
And I want to pass to this function a row of a matrix as data input.
Thanks to everyone in advance!
If you pass a pointer to the first element of your 2D matrix, you can access it as a 1 D matrix since the elements are stored contiguously:
double y[LENGTH][2];
x = function(y[0]);
...
double function(double* p) {
int ii;
double sum=0;
for(ii=0; ii<2*LENGTH; ii++) sum += p[ii];
return sum;
}
Note that in this case the order of accessing the elements is
y[0][0]
y[0][1]
y[1][0]
y[1][1]
y[2][0]
... etc
update - you just clarified your question a little bit. If you want to access just one column of data, you need to skip through the array. This means you need to know the size of the second dimension. I would recommend something like this:
double function(double* p, int D2) {
int ii;
double sum=0;
for(ii=0; ii<D2*LENGTH; ii+=D2) sum += p[ii];
return sum;
}
And you would call it with
x = function(y[colNum], numCols);
Now we start at a certain location, then, skip forward D2 elements to access the next element in the column.
I have to say that this is rather ugly - this is not really how C is intended to be used. I would recommend wrapping things into a class that handles these things for you cleanly - in other words, switch to C++ (although it's possible to write pure C functions that "hide" some of this complexity). You could of course copy the data to another memory block to make it contiguous, but that's usually considered a last recourse.
Be careful that you don't end up with code that is unreadable / unmaintainable...
further update
Per your comment, the above is still not what you wanted. Then I recommend the following:
double *colPointer(double *p, int rowCount, int colCount) {
double *cp;
int ii;
cp = malloc(rowCount * sizeof *cp);
for(ii=0; ii<rowCount; ii++) cp[ii] = *(p + ii * colCount);
return cp;
}
This will return a pointer to a newly created copy of the column. You call it with
double *cc;
cc = colPointer(y[colNum], LENGTH, 2);
answer = function(cc);
And now you can use cc in the way you wanted. If you have to do this many times you might be better off transposing the entire array just once - that way you can pass a pointer to a row of the transpose and achieve your result. You can adapt the code above to generate such a transpose.
Note that there is a risk of memory leaks if you don't clean up after yourself with this method.
the question is that do you consider to be the row-dimension.
usually the first one is rows and the second one cols.
that means that your double y[LENGTH][2]; is a matrix with LENGTH rows ans 2 cols.
if that is also your interpretation then the answer to your question is "you can't" since the memory is layed out like this:
r0c0 r0c1 r1c0 r1c1 r2c0 r2c1 ...
you can retrieve pointer to a row but not to a column.
matrix classes are usually designed in a way, that row and column step length is stored so that by carefully setting them you can build sub matrices on a big data chunk.
you may look for opencv matrix implementation if you plan to perform complexer tasks.
if you can change the implementation of the function you want to call. you can change it to accept the row step (number of your columns), so that it does not joust increment the pointer by one to reach the next element but to increment the pointer by row step.
as an alternative there is the obvious way to copy the required column to a new array.
edit:
fixed stupid error on memory layout diagram

Mex sparse matrix

I created a sparse matrix in MEX using mxCreateSparse.
mxArray *W;
W=mxCreateSparse(n*n,n*n,xsize,mxREAL);
double *wpoint;
wpoint=mxGetPr(W);
for(p=0;p<xsize;p++)
{
Wpoint[(returnindex1(xi[p][0],xi[p][1])-1)*n*n + (returnindex1(xj[p][0],xj[p][1]))]= exp(-df[p]/(SIGMAI*SIGMAI)) * exp(-dx[p]/(SIGMAJ*SIGMAJ));
}
the maximum value which comes from (returnindex1(xi[p][0],xi[p][1])-1)*n*n + (returnindex1(xj[p][0],xj[p][1])) is n*n*n*n and I have created the sparse matrix of dimension (n*n)X(n*n)
When I display the whole matrix, some of the zero elements come as junk.
Also for large values of n, segmentation fault occurs at wpoint.
The pr array holds xsize elements and you accessing the array with out of bounds indices . Hence the seg violation.
I think your fundamental problem is that you have not fully grasped how sparse matrices are stored in MATLAB. I'm not an expert on the MATLAB implementation details but my recollection is that it uses compressed column storage.
In essence there are 3 arrays as follows:
double pr[NZMAX] which contains the NZMAX non-zero values.
int ir[NZMAX] which contains the row number of each value in pr.
int jc[m] which indexes into pr and ir identifying the first item in each of the m columns.
That's the executive summary, but I recommend that you read up on the details more carefully.

C Programming : Sum of third upper anti-diagonal a squared matrix , help badly needed please

im doing a short course in c programming and i have been so busy lately with my other classes and and helping my bother prepare for his wedding (as im his best man)that I have fallen behind and need help. any help towards this short assignment would be much appreciated as im not familiar at all with matrixs and its due in a few days.
the assignment is to Sum of third upper anti-diagonal a squared matrix .
i have been given this information:
The matrix should be a square, integer matrix of size N. In this assignment the matrix will be stored
in a 1d block of memory. You will have to convert between the conceptual 2d matrix addressing and
1d block addressing with pointer arithmetic.
Note on random numbers:
rand() function returns the next integer a sequence of pseudo-random integers in the range
[0, RAND_MAX]. RAND_MAX is a very large number and varies from system to system. To get an
integer in the range [min, max]:
(int)((min)+rand()/(RAND_MAX+1.0) * ((max)-(min)+1))
srand(SEED) is used to set the seed for rand. If srand() is called with the same seed value, the
sequence of pseudo-random numbers is repeated. To get different random numbers each time a
programme runs use time(NULL) as the seed. Rand is in stdlib.h, which needs to be included.
The program should be structured as follows.
#define N 32 // Matrix size
#define MYSEED 1234 // Last 4 digits of your student number.
int *initialise( ) // Allocate memory for the matrix using malloc
// Initialise the matrix with random integers x, 1≤ x ≤ 9
// Use 'MYSEED' as the seed in the random generator.
// Return a pointer to the matrix
void print_matrix(int *) // Print matrix on screen
int compute_diagonal(int *) // Compute your required calculation using pointer arithmetic.
// (square bracket [ ] array indexes shouldn't be used)
// Return the solution.
void finalise(int *) //free the allocated memory.
int main() // The main function should print the solution to screen.
Without doing your homework assignment for you, here's a tip:
Make a functions that abstract storing and retrieving values out of the matrix. One of the signatures should look a lot like this:
int retrieve(int* matrix, int row, int col);
Ok since this is homework and you still have a few days I will not give you an exact answer here. But I will give you some thoughts with which it should be pretty easy to come to your answer.
Indexing a matrix 1D-way: You are not allowed to use matrix[x][y] here, but only a one-dimensional array. So just take a minute and think of how the index (x,y) can be computed within a 1D array. Keep in mind that C stores elements rowwise (i.e. the elements matrix[0][0], matrix[0][1], matrix[0][2] refer to matrix[0], matrix[1], matrix[2]). It is a simply forumla in terms of X, Y and N
Filling the matrix randomly is easy, the function to create a random int is already given, just walk the matrix along and fill every element
Adding the third anti-upper diagonal. This isn really a programming question. Just sketch a small matrix on a piece of paper and see what elements you have to add. Look at their indices and than combine your newly gained knowledge with your result from my point 1 and you will know what to add up
Edit: Since you are not allowed to use the bracket operator, keep in mind that matrix[5] is the same as *(matrix+5).
I think it's fair to tell you this ;)

Resources