static int test_COD_lssolve2(gsl_rng * r) { int s = 0; gsl_matrix *m; gsl_vector *b; size_t M, N; const double lambda = 2.3; M = 100; N = 50; m = gsl_matrix_alloc(M, N); b = gsl_vector_alloc(M); create_rank_matrix(26, m, r); create_random_vector(b, r); test_COD_lssolve2_eps(lambda, m, b, 1.0e2 * M * GSL_DBL_EPSILON, "COD_lssolve2 rank 26"); gsl_matrix_free(m); gsl_vector_free(b); M = 500; N = 450; m = gsl_matrix_alloc(M, N); b = gsl_vector_alloc(M); create_rank_matrix(278, m, r); create_random_vector(b, r); test_COD_lssolve2_eps(lambda, m, b, 1.0e4 * M * GSL_DBL_EPSILON, "COD_lssolve2 rank 278"); gsl_matrix_free(m); gsl_vector_free(b); return s; }
static void test_random(const size_t N, const gsl_rng *r, const int compress) { const gsl_splinalg_itersolve_type *T = gsl_splinalg_itersolve_gmres; const double tol = 1.0e-8; int status; gsl_spmatrix *A = create_random_sparse(N, N, 0.3, r); gsl_spmatrix *B; gsl_vector *b = gsl_vector_alloc(N); gsl_vector *x = gsl_vector_calloc(N); /* these random matrices require all N iterations to converge */ gsl_splinalg_itersolve *w = gsl_splinalg_itersolve_alloc(T, N, N); const char *desc = gsl_splinalg_itersolve_name(w); create_random_vector(b, r); if (compress) B = gsl_spmatrix_compcol(A); else B = A; status = gsl_splinalg_itersolve_iterate(B, b, tol, x, w); gsl_test(status, "%s random status s=%d N=%zu", desc, status, N); /* check that the residual satisfies ||r|| <= tol*||b|| */ { gsl_vector *res = gsl_vector_alloc(N); double normr, normb; gsl_vector_memcpy(res, b); gsl_spblas_dgemv(CblasNoTrans, -1.0, A, x, 1.0, res); normr = gsl_blas_dnrm2(res); normb = gsl_blas_dnrm2(b); status = (normr <= tol*normb) != 1; gsl_test(status, "%s random residual N=%zu normr=%.12e normb=%.12e", desc, N, normr, normb); gsl_vector_free(res); } gsl_spmatrix_free(A); gsl_vector_free(b); gsl_vector_free(x); gsl_splinalg_itersolve_free(w); if (compress) gsl_spmatrix_free(B); } /* test_random() */
/* create a matrix of a given rank */ static int create_rank_matrix(const size_t rank, gsl_matrix * m, gsl_rng * r) { const size_t M = m->size1; const size_t N = m->size2; size_t i; gsl_vector *u = gsl_vector_alloc(M); gsl_vector *v = gsl_vector_alloc(N); gsl_matrix_set_zero(m); /* add several rank-1 matrices together */ for (i = 0; i < rank; ++i) { create_random_vector(u, r); create_random_vector(v, r); gsl_blas_dger(1.0, u, v, m); } gsl_vector_free(u); gsl_vector_free(v); return GSL_SUCCESS; }
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; }