Delete a column from a double array - c

I'm stuck here. I've got a matrix of size NxN stored in a double array. Then I want to delete a given column, lets say the first column. So I created a new double array of size NxN-1 and copy the values from the first matrix to the second one, except the 1st column of course. But then I want to set the first array to be the second array. I am blanking here.
double matrix[N][N]
//fill up the matrix code here...
// remove first column of array
double newMatrix[N][N-1];
for(i = 0; i < N; i++){
for(j = 1; j < N; j++){
newMatrix[i][j-1] = matrix[i][j];
}
}
matrix = newMatrix; // how do I set this correctly? Do I need to realloc the first array?

You cannot assign arrays in C, which I assume that your compiler tells you. To do such dynamic memory management, you will need to use pointers instead of arrays. I suggest you read up on how malloc() and free() work so that you can do what you want.
Edit:
Another solution comes to mind if you are only removing columns (or rows): keep track of the number of rows and columns used in the array. Then you can remove a row or column within the original array without creating a copy first. Just move the data past the delete column (or row) to the left (or up) then decrement your size counters. (I hope this make sense. If not let me know and I'll elaborate.)

like Code-guru said malloc() and free() should help alot, but if u simply wanted to delete the last column the you wouldn't need two arrays:
double matrix[2][3] = {1,2,3,4,5,6}; //declaring a 2 by 3 matrix
for (i=0;i<2;i++) //rows
{
for (j=0;j<3-1;j++) //columns - 1
{
printf("%.1f ",matrix[i][j]); //I chose to display matrix...
}
printf("\n");
}

Instead of accessing elements from array[i][j], one might opt to access elements from array + stride_x[x] + stride_y[y]; where array is originally introduced as double matrix[N*N]; or double *matrix = malloc(sizeof(double)*N*N);.
The stride_y[x] would originally contain offsets of columns for all rows: 0 1 2 3 4 ... N-1 and stride_y[y] would contain similar offsets multiplied with original row width 0 N 2*N 3*N..
From these 1-D arrays one can more effortlessly delete or exchange complete rows and columns, which may come handy in eg. recursive implementation of determinant calculation / Gauss Jordan elimination.

Related

Fnd max float number in 2d array (whitout knowing the size of it) on C

I am trying to find a solution in a C programming
I have a 2d array, but i dont know its size
I can only access the array with a array view of [11][11]
The main idea is to find the peak of a mountain (max element)
So basically my 2d array is a map where each index is a float number, corresponding to the height of the mountain
I know i am out of the map when my float number is -1
That is what i was thinking to do, but i cant put it onto a code in a proper way
My solution is based on brute force approach
my basic idea was getting one 2d array formed by myview
what would give me a [11][11] array
then get a max value on that [11][11] array and store it.
next step i would generate another myview array using a loop.
i would apply same process here, to get a max value on that new array
then i would compare myfirst Max value with that second Max value
the value who have the biggest value would be stored on my max variable, with the location as well (point x and point y).
then i would run a loop again to create another myview array, and so on.
My plan to run on all possible [11][11]arrays is:
starting from running a loop for all the columns, but always keeping the rows 1-11
i know there is no more columns when all the values inside of my array [11][11] are -1.0
so when i find that array i would jump for next section of rows (12-23) for example
and again run for all columns.
i also could set a max value per set of a row (so at set of rows 1-11 the max value (peak) is 197.15 , then at set of rows 12-23 the max value (peak) is 397.15, for example)
i know will not be more rows when in my first set of columns i get the values inside of my array [11][11] -1.0000
so i would just need to get my biggest value on all set of rows, then i would get my solution.
You mean you have a two-dimensional array with two lines of eleven elements each, as you would get if you ran int array[11][11];? Then you can have two nested loops, one for (int i = 0; i < 2; i++) and for (int j = 0; j < 11; j++) nested inside each other to loop over the individual elements of the two lines. You have a buffer variable that holds the maximum so far. In your loop you compare each element you're looping over against the buffer variable, and the new element becomes the new buffer variable if it's bigger than the existing one:
void main(void) {
int array[11][11];
int buffer = 0;
for (int i = 0; i < 2; i++) {
for (int j = 0; 11 < 2; j++) {
if (array[i][j] > buffer) {buffer = array[i][j];}
}
}
}

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.

accessing unallocatted memory after changing matrix size

I won't bother you with all the dry details of what is the assignment and the problem I'm trying to solve, I'll cut right to the chase.
I need to fill a matrix with data. the matrix is square and everything is zero except the first 2 diagonals (meaning M[i][i] for i between 0 and n-1 and M[i][i+1] for i between 0 and n-2 are already filled)
We want to fill the matrix using this a bit complex formula.
M[i][j]=max(a+min(M[i+2][j],M[i+1][j-1]) , b+min(M[i+1][j-1],M[i][j-2]))
The result is an upper triangular matrix. You can see from the above formula that to compute the k'th diagonal, we need the k-2 diagonal. And I said the first 2 are given.
I wrote a code to fill the matrix and it is working as intended.
Here is my problem:
Since it is an upper triangular matrix, the lower half is all zero. so there is no point in wasting memory and saving it. So I thought to myself instead of allocating an n by n matrix, I will allocate n rows, and to the first row ill allocate n spaces, to the second n-1, to the third n-2 and so on...
But since we changed the dimensions of the matrix, the formula I wrote above to compute M[i][j] is different now. In my opinion, we moves all the values in the i'th row, i columns to the left. in row 0 nothing changed. in row 1, we pulled all the values 1 column to the left, etc. So if I understand correctly:
M[i][j]=M'[i][j-i]
Where M' is our new matrix. And so plugging that in the formula above:
M'[i][j]=max(a+min(M'[i+2][j-i],M'[i+1][j-1-i]) , b+min(M'[i+1][j-1-i],M'[i][j-2-i]))
However now the program to fill the matrix is not working correctly. It is filling the matrix with garbage.
Here is the code to fill the matrix:
void fill_matrix() //fills the matrix with data of optimal path, we use memoization rather than recursion, so this step is necessary.
{ //first step is to allocate the matrix. we can assume right_index==size-1 since this is the first thing we do after generating the array
int i,j;
optimum_matrix=(int**)malloc((right_index+1)*sizeof(int**));
for(j=0;j<=right_index;j++)
optimum_matrix[j]=(int*)malloc((right_index+1-j)*sizeof(int*)); //matrix allocated. upper triangular matrix. no need to allocate n^2 spaces. //to fix indices, M[i][j]=M'[i][j-i+1]. subtract i and add 1 to each column, since we moved each entry in row i, i-1 columns back.
for(i=0;i<=right_index;i++) //first diagonal
optimum_matrix[i][0]=data_array[i];
for(i=0;i<right_index;i++) //second diagonal
optimum_matrix[i][1]=get_max(data_array[i],data_array[i+1]);
for(i=0;i<=right_index;i++)
{
for(j=2;j<=right_index-i;j++)
optimum_matrix[i][j]=get_max(data_array[i]+get_min(optimum_matrix[i+2][j-i],optimum_matrix[i+1][j-i-1]),data_array[j]+get_min(optimum_matrix[i+1][j-i-1],optimum_matrix[i][j-i-2])); //here is the problem
}
}
And this is the code to print the matrix
void print_matrix()
{
int i,j,k;
for(i=0;i<=right_index;i++)
{
for(k=0;k<i;k++)
printf("0 ");
for(j=0;j<=right_index-i;j++)
printf("%d ",optimum_matrix[i][j]);
printf("\n");
}
}
Even on the first iteration of filling the third diagonal, when it enters the for loop where it says "here is the problem", if i type printf("%d",optimum_matrix[i+2][j-i]); it will print garbage. And I don't understand why since the formula agrees.
Would appreciate help. Thank you.
optimum_matrix=(int**)malloc((right_index+1)*sizeof(int**));
That isn't the right way to allocate a double array. It's allocating only one dimension of the double array. It's hard for me to follow your logic on how big you want each row and column to be. So below may not be the exact right dimensions you want. But hopefully it does illustrate how to more correctly allocate the double array.
int **optimum_matrix = malloc((right_index+1)*sizeof(int*));
for (i = 0; i < (right_index+1); i++) {
optium_matrix[i] = malloc((right_index+1)*sizeof(int));
}
BTW, I left out the check of the malloc return value for brevity. And your original code also doesn't check the return value of malloc. That should always be done.

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

Resources