Dane Parchment - 8 months ago 45

C Question

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 Source

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.