/******************************************************************************* * matrix_t invert_matrix(matrix_t A) * * Invert Matrix function based on LUP decomposition and then forward and * backward substitution. *******************************************************************************/ matrix_t invert_matrix(matrix_t A){ int i,j,k,m; matrix_t L,U,P,D,temp; matrix_t out = create_empty_matrix(); if(!A.initialized){ printf("ERROR: matrix not initialized yet\n"); return out; } if(A.cols != A.rows){ printf("ERROR: matrix is not square\n"); return out; } if(matrix_determinant(A) == 0){ printf("ERROR: matrix is singular, not invertible\n"); return out; } m = A.cols; LUP_decomposition(A,&L,&U,&P); D = create_identity_matrix(m); temp = create_square_matrix(m); for(j=0;j<m;j++){ for(i=0;i<m;i++){ for(k=0;k<i;k++){ D.data[i][j] -= L.data[i][k] * D.data[k][j]; } } for(i=m-1;i>=0;i--){ // backwards.. last to first temp.data[i][j] = D.data[i][j]; for(k=i+1;k<m;k++){ temp.data[i][j] -= U.data[i][k] * temp.data[k][j]; } temp.data[i][j] = temp.data[i][j] / U.data[i][i]; } } // multiply by permutation matrix out = multiply_matrices(temp, P); // free allocation destroy_matrix(&temp); destroy_matrix(&L); destroy_matrix(&U); destroy_matrix(&P); destroy_matrix(&D); return out; }
int LUP_decomposition__alloc(int length, double **A, double ***LU, int **p) { *p = (int*)malloc(sizeof(int) * length); new_matrix(LU, length, length); return LUP_decomposition(length, A, *LU, *p); }
int main(){ printf("Let's test some linear algebra functions....\n\n"); // create a random nxn matrix for later use matrix_t A = create_random_matrix(DIM,DIM); printf("New Random Matrix A:\n"); print_matrix(A); // also create random vector vector_t b = create_random_vector(DIM); printf("\nNew Random Vector b:\n"); print_vector(b); // do an LUP decomposition on A matrix_t L,U,P; LUP_decomposition(A,&L,&U,&P); printf("\nL:\n"); print_matrix(L); printf("U:\n"); print_matrix(U); printf("P:\n"); print_matrix(P); // do a QR decomposition on A matrix_t Q,R; QR_decomposition(A,&Q,&R); printf("\nQR Decomposition of A\n"); printf("Q:\n"); print_matrix(Q); printf("R:\n"); print_matrix(R); // get determinant of A float det = matrix_determinant(A); printf("\nDeterminant of A : %8.4f\n", det); // get an inverse for A matrix_t Ainv = invert_matrix(A); if(A.initialized != 1) return -1; printf("\nAinverse\n"); print_matrix(Ainv); // multiply A times A inverse matrix_t AA = multiply_matrices(A,Ainv); if(AA.initialized!=1) return -1; printf("\nA * Ainverse:\n"); print_matrix(AA); // solve a square linear system vector_t x = lin_system_solve(A, b); printf("\nGaussian Elimination solution x to the equation Ax=b:\n"); print_vector(x); // now do again but with qr decomposition method vector_t xqr = lin_system_solve_qr(A, b); printf("\nQR solution x to the equation Ax=b:\n"); print_vector(xqr); // If b are the coefficients of a polynomial, get the coefficients of the // new polynomial b^2 vector_t bb = poly_power(b,2); printf("\nCoefficients of polynomial b times itself\n"); print_vector(bb); // clean up all the allocated memory. This isn't strictly necessary since // we are already at the end of the program, but good practice to do. destroy_matrix(&A); destroy_matrix(&AA); destroy_vector(&b); destroy_vector(&bb); destroy_vector(&x); destroy_vector(&xqr); destroy_matrix(&Q); destroy_matrix(&R); printf("DONE\n"); return 0; }