float Matrix::matrixDeterminant(Matrix *matrix) { float matrix3x3[9]; float determinant3x3 = 0.0f; float result = 0.0f; /* Remove (i, j) (1, 1) to form new 3x3 matrix. */ matrix3x3[0] = matrix->elements[ 5]; matrix3x3[1] = matrix->elements[ 6]; matrix3x3[2] = matrix->elements[ 7]; matrix3x3[3] = matrix->elements[ 9]; matrix3x3[4] = matrix->elements[10]; matrix3x3[5] = matrix->elements[11]; matrix3x3[6] = matrix->elements[13]; matrix3x3[7] = matrix->elements[14]; matrix3x3[8] = matrix->elements[15]; determinant3x3 = matrixDeterminant(matrix3x3); result += matrix->elements[0] * determinant3x3; /* Remove (i, j) (1, 2) to form new 3x3 matrix. */ matrix3x3[0] = matrix->elements[ 1]; matrix3x3[1] = matrix->elements[ 2]; matrix3x3[2] = matrix->elements[ 3]; matrix3x3[3] = matrix->elements[ 9]; matrix3x3[4] = matrix->elements[10]; matrix3x3[5] = matrix->elements[11]; matrix3x3[6] = matrix->elements[13]; matrix3x3[7] = matrix->elements[14]; matrix3x3[8] = matrix->elements[15]; determinant3x3 = matrixDeterminant(matrix3x3); result -= matrix->elements[4] * determinant3x3; /* Remove (i, j) (1, 3) to form new 3x3 matrix. */ matrix3x3[0] = matrix->elements[ 1]; matrix3x3[1] = matrix->elements[ 2]; matrix3x3[2] = matrix->elements[ 3]; matrix3x3[3] = matrix->elements[ 5]; matrix3x3[4] = matrix->elements[ 6]; matrix3x3[5] = matrix->elements[ 7]; matrix3x3[6] = matrix->elements[13]; matrix3x3[7] = matrix->elements[14]; matrix3x3[8] = matrix->elements[15]; determinant3x3 = matrixDeterminant(matrix3x3); result += matrix->elements[8] * determinant3x3; /* Remove (i, j) (1, 4) to form new 3x3 matrix. */ matrix3x3[0] = matrix->elements[ 1]; matrix3x3[1] = matrix->elements[ 2]; matrix3x3[2] = matrix->elements[ 3]; matrix3x3[3] = matrix->elements[ 5]; matrix3x3[4] = matrix->elements[ 6]; matrix3x3[5] = matrix->elements[ 7]; matrix3x3[6] = matrix->elements[ 9]; matrix3x3[7] = matrix->elements[10]; matrix3x3[8] = matrix->elements[11]; determinant3x3 = matrixDeterminant(matrix3x3); result -= matrix->elements[12] * determinant3x3; return result; }
/* Main method to test math */ int main() { // Test matrix math struct Matrix a; //double valuesa[9] = { 5.0, -2.0, 1.0, 0.0, 3.0, -1.0, 2.0, 0.0, 7.0 }; double valuesa[16] = { 1.0, 3.0, -2.0, 1.0, 5.0, 1.0, 0.0, -1.0, 0.0, 1.0, 0.0, -2.0, 2.0, -1.0, 0.0, 3.0 }; newMatrix(&a, valuesa, 4, 4); struct Matrix b; double valuesb[9] = { 1.0, 2.0, 3.0, 0.0, -4.0, 1.0, 0.0, 3.0, -1.0 }; newMatrix(&b, valuesb, 3, 3); struct Matrix cofa; matrixCofactor(&cofa, a); printf("A Cofactor=\n"); matrixToString(cofa); struct Matrix inva; matrixInverse(&inva, a); printf("A Inverse=\n"); matrixToString(inva); printf("A=\n"); matrixToString(a); printf("B=\n"); matrixToString(b); printf("A is %sa square matrix.\n", matrixIsSquare(a) ? "" : "not "); printf("B is %sa square matrix.\n", matrixIsSquare(b) ? "" : "not "); printf("The determinant of A is %f.\n", matrixDeterminant(a)); printf("A is %sunique.\n", matrixIsUnique(a) ? "" : "not "); printf("The determinant of B is %f.\n", matrixDeterminant(b)); printf("B is %sunique.\n", matrixIsUnique(b) ? "" : "not "); struct Matrix aplusb; matrixAdd(&aplusb, a, b); printf("A+B=\n"); matrixToString(aplusb); struct Matrix asubb; matrixSubtract(&asubb, a, b); printf("A-B=\n"); matrixToString(asubb); struct Matrix ascale; matrixScale(&ascale, a, 5); printf("5A=\n"); matrixToString(ascale); struct Matrix bscale; matrixScale(&bscale, b, 5); printf("5B=\n"); matrixToString(bscale); printf("A and B are %sthe same size.\n", matrixIsSameSize(a, b) ? "" : "not "); printf("A=\n"); matrixToString(a); printf("B=\n"); matrixToString(b); // Test 3D vector math }
/* Calculate the cofactor of a matrix */ void matrixCofactor(struct Matrix *out, const struct Matrix a) { if(!matrixIsSquare(a)) { printf("Error: The matrix is not square."); return; } double *newValues = malloc(a.numValues * sizeof(double)); for(int i = 0; i < a.numRows; i++) { for(int j = 0; j < a.numColumns; j++) { struct Matrix temp; int tempsize = (a.numRows-1) * (a.numColumns-1); double valuestemp[tempsize]; int o = 0; for (int k = 0; k < a.numRows; k++) { for (int l = 0; l < a.numColumns; l++) { if(l == j) l++; if(k == i) k++; if(k == a.numRows || l == a.numColumns) break; valuestemp[o] = a.values[k*a.numColumns+l]; o++; } } newMatrix(&temp, valuestemp, a.numRows-1, a.numRows-1); newValues[j*a.numRows+i] = matrixDeterminant(temp); } } newMatrix(out, newValues, a.numRows, a.numColumns); }
void testMatrixDeterminant(){ int n; double **C; n=3; C=allocateDoubleMatrix(3, 3); C[0][0]=6.0; C[0][1]=1.0; C[0][2]=1.0; C[1][0]=4.0; C[1][1]=-2.0; C[1][2]=5.0; C[2][0]=2.0; C[2][1]=8.0; C[2][2]=7.0; fprintf(stdout,"Matrix Determinant\n"); fprintf(stdout,"%f \n", matrixDeterminant(C,n)); }
double matrixDeterminant(double **A, int n){ int i; double det=0; double **B; B=allocateDoubleMatrix(n-1, n-1); if(n==2){ det=(A[0][0]*A[1][1])-(A[0][1]*A[1][0]); } else{ for(i=0;i<n;i++){ B=minorMatrix(A, n, i, 0); det += pow(-1,i)*A[0][i]*matrixDeterminant(B,n-1); } } return(det); }
/* Check if a matrix has a unique solution */ char matrixIsUnique(const struct Matrix a) { if(matrixDeterminant(a) != 0) return 1; return 0; }
/* Calculate the inverse of a matrix */ void matrixInverse(struct Matrix *out, const struct Matrix a) { struct Matrix temp; matrixCofactor(&temp, a); matrixScale(out, temp, 1/matrixDeterminant(a)); }
Matrix Matrix::matrixInvert(Matrix *matrix) { Matrix result; float matrix3x3[9]; /* Find the cofactor of each element. */ /* Element (i, j) (1, 1) */ matrix3x3[0] = matrix->elements[ 5]; matrix3x3[1] = matrix->elements[ 6]; matrix3x3[2] = matrix->elements[ 7]; matrix3x3[3] = matrix->elements[ 9]; matrix3x3[4] = matrix->elements[10]; matrix3x3[5] = matrix->elements[11]; matrix3x3[6] = matrix->elements[13]; matrix3x3[7] = matrix->elements[14]; matrix3x3[8] = matrix->elements[15]; result.elements[0] = matrixDeterminant(matrix3x3); /* Element (i, j) (1, 2) */ matrix3x3[0] = matrix->elements[ 1]; matrix3x3[1] = matrix->elements[ 2]; matrix3x3[2] = matrix->elements[ 3]; matrix3x3[3] = matrix->elements[ 9]; matrix3x3[4] = matrix->elements[10]; matrix3x3[5] = matrix->elements[11]; matrix3x3[6] = matrix->elements[13]; matrix3x3[7] = matrix->elements[14]; matrix3x3[8] = matrix->elements[15]; result.elements[4] = -matrixDeterminant(matrix3x3); /* Element (i, j) (1, 3) */ matrix3x3[0] = matrix->elements[ 1]; matrix3x3[1] = matrix->elements[ 2]; matrix3x3[2] = matrix->elements[ 3]; matrix3x3[3] = matrix->elements[ 5]; matrix3x3[4] = matrix->elements[ 6]; matrix3x3[5] = matrix->elements[ 7]; matrix3x3[6] = matrix->elements[13]; matrix3x3[7] = matrix->elements[14]; matrix3x3[8] = matrix->elements[15]; result.elements[8] = matrixDeterminant(matrix3x3); /* Element (i, j) (1, 4) */ matrix3x3[0] = matrix->elements[ 1]; matrix3x3[1] = matrix->elements[ 2]; matrix3x3[2] = matrix->elements[ 3]; matrix3x3[3] = matrix->elements[ 5]; matrix3x3[4] = matrix->elements[ 6]; matrix3x3[5] = matrix->elements[ 7]; matrix3x3[6] = matrix->elements[ 9]; matrix3x3[7] = matrix->elements[10]; matrix3x3[8] = matrix->elements[11]; result.elements[12] = -matrixDeterminant(matrix3x3); /* Element (i, j) (2, 1) */ matrix3x3[0] = matrix->elements[ 4]; matrix3x3[1] = matrix->elements[ 6]; matrix3x3[2] = matrix->elements[ 7]; matrix3x3[3] = matrix->elements[ 8]; matrix3x3[4] = matrix->elements[10]; matrix3x3[5] = matrix->elements[11]; matrix3x3[6] = matrix->elements[12]; matrix3x3[7] = matrix->elements[14]; matrix3x3[8] = matrix->elements[15]; result.elements[1] = -matrixDeterminant(matrix3x3); /* Element (i, j) (2, 2) */ matrix3x3[0] = matrix->elements[ 0]; matrix3x3[1] = matrix->elements[ 2]; matrix3x3[2] = matrix->elements[ 3]; matrix3x3[3] = matrix->elements[ 8]; matrix3x3[4] = matrix->elements[10]; matrix3x3[5] = matrix->elements[11]; matrix3x3[6] = matrix->elements[12]; matrix3x3[7] = matrix->elements[14]; matrix3x3[8] = matrix->elements[15]; result.elements[5] = matrixDeterminant(matrix3x3); /* Element (i, j) (2, 3) */ matrix3x3[0] = matrix->elements[ 0]; matrix3x3[1] = matrix->elements[ 2]; matrix3x3[2] = matrix->elements[ 3]; matrix3x3[3] = matrix->elements[ 4]; matrix3x3[4] = matrix->elements[ 6]; matrix3x3[5] = matrix->elements[ 7]; matrix3x3[6] = matrix->elements[12]; matrix3x3[7] = matrix->elements[14]; matrix3x3[8] = matrix->elements[15]; result.elements[9] = -matrixDeterminant(matrix3x3); /* Element (i, j) (2, 4) */ matrix3x3[0] = matrix->elements[ 0]; matrix3x3[1] = matrix->elements[ 2]; matrix3x3[2] = matrix->elements[ 3]; matrix3x3[3] = matrix->elements[ 4]; matrix3x3[4] = matrix->elements[ 6]; matrix3x3[5] = matrix->elements[ 7]; matrix3x3[6] = matrix->elements[ 8]; matrix3x3[7] = matrix->elements[10]; matrix3x3[8] = matrix->elements[11]; result.elements[13] = matrixDeterminant(matrix3x3); /* Element (i, j) (3, 1) */ matrix3x3[0] = matrix->elements[ 4]; matrix3x3[1] = matrix->elements[ 5]; matrix3x3[2] = matrix->elements[ 7]; matrix3x3[3] = matrix->elements[ 8]; matrix3x3[4] = matrix->elements[ 9]; matrix3x3[5] = matrix->elements[11]; matrix3x3[6] = matrix->elements[12]; matrix3x3[7] = matrix->elements[13]; matrix3x3[8] = matrix->elements[15]; result.elements[2] = matrixDeterminant(matrix3x3); /* Element (i, j) (3, 2) */ matrix3x3[0] = matrix->elements[ 0]; matrix3x3[1] = matrix->elements[ 1]; matrix3x3[2] = matrix->elements[ 3]; matrix3x3[3] = matrix->elements[ 8]; matrix3x3[4] = matrix->elements[ 9]; matrix3x3[5] = matrix->elements[11]; matrix3x3[6] = matrix->elements[12]; matrix3x3[7] = matrix->elements[13]; matrix3x3[8] = matrix->elements[15]; result.elements[6] = -matrixDeterminant(matrix3x3); /* Element (i, j) (3, 3) */ matrix3x3[0] = matrix->elements[ 0]; matrix3x3[1] = matrix->elements[ 1]; matrix3x3[2] = matrix->elements[ 3]; matrix3x3[3] = matrix->elements[ 4]; matrix3x3[4] = matrix->elements[ 5]; matrix3x3[5] = matrix->elements[ 7]; matrix3x3[6] = matrix->elements[12]; matrix3x3[7] = matrix->elements[13]; matrix3x3[8] = matrix->elements[15]; result.elements[10] = matrixDeterminant(matrix3x3); /* Element (i, j) (3, 4) */ matrix3x3[0] = matrix->elements[ 0]; matrix3x3[1] = matrix->elements[ 1]; matrix3x3[2] = matrix->elements[ 3]; matrix3x3[3] = matrix->elements[ 4]; matrix3x3[4] = matrix->elements[ 5]; matrix3x3[5] = matrix->elements[ 7]; matrix3x3[6] = matrix->elements[ 8]; matrix3x3[7] = matrix->elements[ 9]; matrix3x3[8] = matrix->elements[11]; result.elements[14] = -matrixDeterminant(matrix3x3); /* Element (i, j) (4, 1) */ matrix3x3[0] = matrix->elements[ 4]; matrix3x3[1] = matrix->elements[ 5]; matrix3x3[2] = matrix->elements[ 6]; matrix3x3[3] = matrix->elements[ 8]; matrix3x3[4] = matrix->elements[ 9]; matrix3x3[5] = matrix->elements[10]; matrix3x3[6] = matrix->elements[12]; matrix3x3[7] = matrix->elements[13]; matrix3x3[8] = matrix->elements[14]; result.elements[3] = -matrixDeterminant(matrix3x3); /* Element (i, j) (4, 2) */ matrix3x3[0] = matrix->elements[ 0]; matrix3x3[1] = matrix->elements[ 1]; matrix3x3[2] = matrix->elements[ 2]; matrix3x3[3] = matrix->elements[ 8]; matrix3x3[4] = matrix->elements[ 9]; matrix3x3[5] = matrix->elements[10]; matrix3x3[6] = matrix->elements[12]; matrix3x3[7] = matrix->elements[13]; matrix3x3[8] = matrix->elements[14]; result.elements[7] = matrixDeterminant(matrix3x3); /* Element (i, j) (4, 3) */ matrix3x3[0] = matrix->elements[ 0]; matrix3x3[1] = matrix->elements[ 1]; matrix3x3[2] = matrix->elements[ 2]; matrix3x3[3] = matrix->elements[ 4]; matrix3x3[4] = matrix->elements[ 5]; matrix3x3[5] = matrix->elements[ 6]; matrix3x3[6] = matrix->elements[12]; matrix3x3[7] = matrix->elements[13]; matrix3x3[8] = matrix->elements[14]; result.elements[11] = -matrixDeterminant(matrix3x3); /* Element (i, j) (4, 4) */ matrix3x3[0] = matrix->elements[ 0]; matrix3x3[1] = matrix->elements[ 1]; matrix3x3[2] = matrix->elements[ 2]; matrix3x3[3] = matrix->elements[ 4]; matrix3x3[4] = matrix->elements[ 5]; matrix3x3[5] = matrix->elements[ 6]; matrix3x3[6] = matrix->elements[ 8]; matrix3x3[7] = matrix->elements[ 9]; matrix3x3[8] = matrix->elements[10]; result.elements[15] = matrixDeterminant(matrix3x3); /* The adjoint is the transpose of the cofactor matrix. */ matrixTranspose(&result); /* The inverse is the adjoint divided by the determinant. */ result = matrixScale(&result, 1.0f / matrixDeterminant(matrix)); return result; }