int GMRFLib_gsl_spd_inverse(gsl_matrix * A) { /* * replace SPD matrix A with its inverse */ gsl_matrix *L; gsl_vector *x; size_t i, n; assert(A->size1 == A->size2); n = A->size1; x = gsl_vector_calloc(n); L = GMRFLib_gsl_duplicate_matrix(A); gsl_linalg_cholesky_decomp(L); for (i = 0; i < n; i++) { gsl_vector_set_basis(x, i); gsl_linalg_cholesky_svx(L, x); gsl_matrix_set_col(A, i, x); } gsl_vector_free(x); gsl_matrix_free(L); return GMRFLib_SUCCESS; }
int gsl_linalg_cholesky_solve (const gsl_matrix * LLT, const gsl_vector * b, gsl_vector * x) { if (LLT->size1 != LLT->size2) { GSL_ERROR ("cholesky matrix must be square", GSL_ENOTSQR); } else if (LLT->size1 != b->size) { GSL_ERROR ("matrix size must match b size", GSL_EBADLEN); } else if (LLT->size2 != x->size) { GSL_ERROR ("matrix size must match solution size", GSL_EBADLEN); } else { int status; /* copy x <- b */ gsl_vector_memcpy (x, b); status = gsl_linalg_cholesky_svx(LLT, x); return status; } }
CAMLprim value ml_gsl_linalg_cholesky_svx(value CHO, value X) { _DECLARE_MATRIX(CHO); _DECLARE_VECTOR(X); _CONVERT_MATRIX(CHO); _CONVERT_VECTOR(X); gsl_linalg_cholesky_svx(&m_CHO, &v_X); return Val_unit; }
//inverse of real (symmetric) positive defined matrix //as a by-product we may obtain the square root of the determinant of A int InvRPD(Matrix &R, Matrix &A, double *LogDetSqrt, Matrix *ExternChol) { assert(A.nRow() == A.nCol()); assert(R.nRow() == R.nCol()); assert(A.nRow() == R.nCol()); Matrix *Chol; //Make the auxiliar matrix equal to A if (ExternChol == NULL) Chol = new Matrix( A.nRow(), A.nCol()); else Chol = ExternChol; R.Iden(); //Make R the identity Chol->copy(A); //Chol->print("A=\n"); gsl_error_handler_t *hand = gsl_set_error_handler_off (); int res = gsl_linalg_cholesky_decomp(Chol->Ma()); gsl_set_error_handler(hand); if (res == GSL_EDOM) { //printf("Matrix::InvRPD: Warning: Non positive definite matrix.\n"); //exit(0); return 0; } assert(res != GSL_EDOM); //Check that everything went well //solve for the cannonical vectors to obtain the inverse in R for (int i=0; i<R.nRow(); i++) { //R.print("R=\n"); gsl_linalg_cholesky_svx( Chol->Ma(), R.AsColVec(i)); } if (LogDetSqrt != NULL) { *LogDetSqrt = 0.0; for (int i=0; i<Chol->nRow(); i++) { *LogDetSqrt += log(Chol->ele( i, i)); //multiply the diagonal elements } } if (ExternChol == NULL) delete Chol; return 1; }
/** * C++ version of gsl_linalg_cholesky_svx(). * @param cholesky A Cholesky decomposition matrix * @param x A vector * @return Error code on failure */ inline int cholesky_svx( matrix const& cholesky, vector& x ){ return gsl_linalg_cholesky_svx( cholesky.get(), x.get() ); }