int gsl_linalg_cholesky_decomp (gsl_matrix * A) { int status; status = gsl_linalg_cholesky_decomp1(A); if (status == GSL_SUCCESS) { gsl_matrix_transpose_tricpy('L', 0, A, A); } return status; }
int gsl_linalg_cholesky_decomp_unit(gsl_matrix * A, gsl_vector * D) { const size_t N = A->size1; size_t i, j; /* initial Cholesky */ int stat_chol = gsl_linalg_cholesky_decomp1(A); if(stat_chol == GSL_SUCCESS) { /* calculate D from diagonal part of initial Cholesky */ for(i = 0; i < N; ++i) { const double C_ii = gsl_matrix_get(A, i, i); gsl_vector_set(D, i, C_ii*C_ii); } /* multiply initial Cholesky by 1/sqrt(D) on the right */ for(i = 0; i < N; ++i) { for(j = 0; j < N; ++j) { gsl_matrix_set(A, i, j, gsl_matrix_get(A, i, j) / sqrt(gsl_vector_get(D, j))); } } /* Because the initial Cholesky contained both L and transpose(L), the result of the multiplication is not symmetric anymore; but the lower triangle _is_ correct. Therefore we reflect it to the upper triangle and declare victory. */ for(i = 0; i < N; ++i) for(j = i + 1; j < N; ++j) gsl_matrix_set(A, i, j, gsl_matrix_get(A, j, i)); } return stat_chol; }
int gsl_linalg_cholesky_decomp2(gsl_matrix * A, gsl_vector * S) { const size_t M = A->size1; const size_t N = A->size2; if (M != N) { GSL_ERROR("cholesky decomposition requires square matrix", GSL_ENOTSQR); } else if (N != S->size) { GSL_ERROR("S must have length N", GSL_EBADLEN); } else { int status; /* compute scaling factors to reduce cond(A) */ status = gsl_linalg_cholesky_scale(A, S); if (status) return status; /* apply scaling factors */ status = gsl_linalg_cholesky_scale_apply(A, S); if (status) return status; /* compute Cholesky decomposition of diag(S) A diag(S) */ status = gsl_linalg_cholesky_decomp1(A); if (status) return status; return GSL_SUCCESS; } }