/* *----------------------------------------------------------------------------- * funct: mat_lsolve * desct: solve linear equations * given: a = square matrix A * b = column matrix B * retrn: column matrix X (of AX = B) *----------------------------------------------------------------------------- */ MATRIX mat_lsolve(MATRIX a,MATRIX b,MATRIX X) { MATRIX A, B, P; int n; n = MatCol(a); if ( ( A = mat_creat(n, n, UNDEFINED) ) == NULL ) return (NULL); if ( ( B = mat_creat(n, 1, UNDEFINED) ) == NULL ) return (NULL); mat_copy(a,A); mat_copy(b,B); if ( ( P = mat_creat(n, 1, UNDEFINED) ) == NULL ) return (NULL); // if dimensions of C is wrong if ( MatRow(X) != n || MatCol(X) != 1 ) { printf("mat_lsolve error: incompatible output matrix size\n"); _exit(-1); // if dimensions of C is correct } else { mat_lu( A, P ); mat_backsubs1( A, B, X, P, 0 ); } mat_free(A); mat_free(B); mat_free(P); return(X); }
/* *----------------------------------------------------------------------------- * funct: mat_det * desct: find determinant * given: A = matrix * retrn: the determinant of A * comen: *----------------------------------------------------------------------------- */ double mat_det( MATRIX a ) { MATRIX A, P; int j; int i, n; double result; n = MatRow(a); A = mat_creat(MatRow(a), MatCol(a), UNDEFINED); A = mat_copy(a, A); P = mat_creat(n, 1, UNDEFINED); /* * take a LUP-decomposition */ i = mat_lu(A, P); switch (i) { /* * case for singular matrix */ case -1: result = 0.0; break; /* * normal case: |A| = |L||U||P| * |L| = 1, * |U| = multiplication of the diagonal * |P| = +-1 */ default: result = 1.0; for (j=0; j<MatRow(A); j++) { result *= A[(int)P[j][0]][j]; } result *= signa[i%2]; break; } mat_free(A); mat_free(P); return (result); }
/* *----------------------------------------------------------------------------- * funct: mat_inv * desct: find inverse of a matrix * given: a = square matrix a * retrn: square matrix Inverse(A) * NULL = fails, singular matrix, or malloc() fails * 1 = success *----------------------------------------------------------------------------- */ MATRIX mat_inv(MATRIX a, MATRIX C) { MATRIX A, B, P; int i, n; n = MatCol(a); if ( ( A = mat_creat( n, n, UNDEFINED ) ) == NULL ) return (NULL); mat_copy(a,A); if ( ( B = mat_creat( n, 1, UNDEFINED ) ) == NULL ) return (NULL); if ( ( P = mat_creat( n, 1, UNDEFINED ) ) == NULL ) return (NULL); // if dimensions of C is wrong if ( MatRow(a) != MatRow(C) || MatCol(a) != MatCol(C) ) { printf("mat_inv error: incompatible output matrix size\n"); _exit(-1); // if dimensions of C is correct } else { /* * - LU-decomposition - * also check for singular matrix */ if (mat_lu(A, P) == -1) { mat_free(A); mat_free(B); mat_free(C); mat_free(P); printf("mat_inv error: failed to invert\n"); return (NULL); } for (i=0; i<n; i++) { mat_fill(B, ZERO_MATRIX); B[i][0] = 1.0; mat_backsubs1( A, B, C, P, i ); } } mat_free(A); mat_free(B); mat_free(P); if (C==NULL) { printf("mat_inv error: failed to invert\n"); return(NULL); } else { return (C); } }
/* *----------------------------------------------------------------------------- * funct: mat_inv * desct: find inverse of a matrix * given: a = square matrix a, and C, return for inv(a) * retrn: square matrix Inverse(A), C * NULL = fails, singular matrix *----------------------------------------------------------------------------- */ MATRIX mat_inv( MATRIX a , MATRIX C) { MATRIX A, B, P; int i, n; #ifdef CONFORM_CHECK if(MatCol(a)!=MatCol(C)) { error("\nUnconformable matrices in routine mat_inv(): Col(A)!=Col(B)\n"); } if(MatRow(a)!=MatRow(C)) { error("\nUnconformable matrices in routine mat_inv(): Row(A)!=Row(B)\n"); } #endif n = MatCol(a); A = mat_creat(MatRow(a), MatCol(a), UNDEFINED); A = mat_copy(a, A); B = mat_creat( n, 1, UNDEFINED ); P = mat_creat( n, 1, UNDEFINED ); /* * - LU-decomposition - * also check for singular matrix */ if (mat_lu(A, P) == -1) { mat_free(A); mat_free(B); mat_free(P); return (NULL); } else { /* Bug??? was still mat_backsubs1 even when singular??? */ for (i=0; i<n; i++) { mat_fill(B, ZERO_MATRIX); B[i][0] = 1.0; mat_backsubs1( A, B, C, P, i ); } mat_free(A); mat_free(B); mat_free(P); return (C); } }