Dane Parchment Dane Parchment - 12 days ago 7
C Question

C: (Working But Not As Intended) My determinate method is editing the provided matrix (as a parameter) but I just want it to provide the determinate

Here is my code for the determinate function:

double getDeterminate(Matrix m) {
//We don't want to change the given matrix, just
//find it's determinate so use a temporary matrix
//instead for the calculations
double **temp = m.matrix;
int rows = m.rows, cols = m.cols;
//If the matrix is not square then the derminate does not exist
if(rows == cols) {
//If the matrix is 2x2 matrix then the
//determinate is ([0,0]x[1,1]) - ([0,1]x[1,0])
if(rows == 2 && cols == 2) {
return (temp[0][0] * temp[1][1]) - (temp[0][1] * temp[1][0]);
}
//Otherwise if it is n*n...we do things the long way
//we will be using a method where we convert the
//matrix into an upper triangle, and then the det
//will simply be the multiplication of all diagonal
//indexes
int i, j, k;
double ratio;
for(i = 0; i < rows; i++){
for(j = 0; j < cols; j++){
if(j>i){
ratio = temp[j][i]/temp[i][i];
for(k = 0; k < rows; k++) {
temp[j][k] -= ratio * temp[i][k];
}
}
}
}
double det = 1; //storage for determinant
for(i = 0; i < rows; i++) {
det *= temp[i][i];
}
return det;
}
return 0;
}


And here is my struct for the Matrix (in an external header file):

#ifndef MATRIX_H
#define MATRIX_H

typedef struct Matrix {
int rows;
int cols;
double ** matrix;
} Matrix;

/** Build/Destroy/Display Methods
-------------------------------------------*/
Matrix buildMatrix(int r, int c);

Matrix displayMatrix(Matrix m);

/** Matrix Get and Set
-------------------------------------------*/
void setValue(Matrix m, double val, int r, int c);

double getValue(Matrix m, int r, int c);

/** Matrix Multiplication
-------------------------------------------*/
Matrix multByValue(double val, Matrix m);

Matrix multByMatrix(Matrix mat1, Matrix mat2);

/** Matrix Inversion
-------------------------------------------*/
Matrix invertMatrix(Matrix m);

/** Matrix Determinate
-------------------------------------------*/
double getDeterminate(Matrix m);

/** Matrix Transpose
-------------------------------------------*/
Matrix transpose(Matrix m);

#endif


Currently it is doing exactly what I want it to do, finding the determinate by turning the matrix into an upper triangle. However, when I run the determinate method, it still changes the matrix I provided as a parameter, even though I believe I used temporary variables to do the calculations without messing with given Matrix.

Example In my main.c I have this:

Matrix mat2 = buildMatrix(3, 3);
setValue(mat2, 12, 0, 0); setValue(mat2, 4, 0, 1); setValue(mat2, 3, 0, 2);
setValue(mat2, 4, 1, 0); setValue(mat2, 13, 1, 1); setValue(mat2, 25, 1, 2);
setValue(mat2, 78, 2, 0); setValue(mat2, 8, 2, 1); setValue(mat2, 9, 2, 2);
displayMatrix(mat2);
printf("Determinate of mat2 is %4.2f", getDeterminate(mat2));
Matrix mat4 = transpose(mat2);
displayMatrix(mat4);


And when I run it I get:

Mat2 Before Transpose
| 12.00 4.00 3.00|
| 4.00 13.00 25.00|
| 78.00 8.00 9.00|

Determinate of mat2 is 3714.00

Mat4 After Transpose of Mat2
| 12.00 0.00 0.00|
| 4.00 11.67 0.00|
| 3.00 24.00 26.53|


As you can see the transpose function is doing it's job correctly, but mat2 has been changed by the determinate method. I don't want that to occur, so what have I done to cause this to happen, and what can I do to fix it? I think it has something to do with pointer, I am new to C, so I don't really know what to do.

Answer

What you did is called shallow copy. Here: double **temp = m.matrix; you just assigned pointer to memory that hold your matrix's elements to the temp matrix, so when you edit it, it edits the data that your original matrix holds as well. That's because the original elements only exist a t one place, and poth temp and m pointers are pointed to it.

In order to do it the way you want it, you have to create a deep copy. You have to allocate new memory for the temp matrix and copy every single element from the original one into it. Don't forget to free() the memory, if you will allocate it dynamically, once you are done with it.

Comments