static int pcholesky_decomp (const int copy_uplo, gsl_matrix * A, gsl_permutation * p) { const size_t N = A->size1; if (N != A->size2) { GSL_ERROR("LDLT decomposition requires square matrix", GSL_ENOTSQR); } else if (p->size != N) { GSL_ERROR ("permutation length must match matrix size", GSL_EBADLEN); } else { gsl_vector_view diag = gsl_matrix_diagonal(A); size_t k; if (copy_uplo) { /* save a copy of A in upper triangle (for later rcond calculation) */ gsl_matrix_transpose_tricpy('L', 0, A, A); } gsl_permutation_init(p); for (k = 0; k < N; ++k) { gsl_vector_view w; size_t j; /* compute j = max_idx { A_kk, ..., A_nn } */ w = gsl_vector_subvector(&diag.vector, k, N - k); j = gsl_vector_max_index(&w.vector) + k; gsl_permutation_swap(p, k, j); cholesky_swap_rowcol(A, k, j); if (k < N - 1) { double alpha = gsl_matrix_get(A, k, k); double alphainv = 1.0 / alpha; /* v = A(k+1:n, k) */ gsl_vector_view v = gsl_matrix_subcolumn(A, k, k + 1, N - k - 1); /* m = A(k+1:n, k+1:n) */ gsl_matrix_view m = gsl_matrix_submatrix(A, k + 1, k + 1, N - k - 1, N - k - 1); /* m = m - v v^T / alpha */ gsl_blas_dsyr(CblasLower, -alphainv, &v.vector, &m.matrix); /* v = v / alpha */ gsl_vector_scale(&v.vector, alphainv); } } return GSL_SUCCESS; } }
int penalty_df (CBLAS_TRANSPOSE_t TransJ, const gsl_vector * x, const gsl_vector * u, void * params, gsl_vector * v, gsl_matrix * JTJ) { struct model_params *par = (struct model_params *) params; const size_t p = x->size; size_t j; /* store 2*x in last row of J */ for (j = 0; j < p; ++j) { double xj = gsl_vector_get(x, j); gsl_spmatrix_set(par->J, p, j, 2.0 * xj); } /* compute v = op(J) u */ if (v) gsl_spblas_dgemv(TransJ, 1.0, par->J, u, 0.0, v); if (JTJ) { gsl_vector_view diag = gsl_matrix_diagonal(JTJ); /* compute J^T J = [ alpha*I_p + 4 x x^T ] */ gsl_matrix_set_zero(JTJ); /* store 4 x x^T in lower half of JTJ */ gsl_blas_dsyr(CblasLower, 4.0, x, JTJ); /* add alpha to diag(JTJ) */ gsl_vector_add_constant(&diag.vector, par->alpha); } return GSL_SUCCESS; }
// f = -log(det(X)) void prox_neg_log_det(gsl_matrix *X, const double rho) { int n = X->size1; gsl_vector *d = gsl_vector_alloc(n); gsl_matrix *V = gsl_matrix_alloc(n,n); gsl_eigen_symmv_workspace *w = gsl_eigen_symmv_alloc(n); gsl_eigen_symmv(X, d, V, w); gsl_eigen_symmv_free(w); int i; double d_i; gsl_matrix_set_zero(X); for (i = 0; i < n; i++) { d_i = gsl_vector_get(d, i); d_i = (d_i + sqrt(pow(d_i,2) + 4*rho))/(2*rho); gsl_vector_set(d, i, d_i); gsl_vector_view V_i = gsl_matrix_column(V, i); gsl_blas_dsyr(CblasLower, d_i, &V_i.vector, X); } gsl_vector_free(d); gsl_matrix_free(V); }
// f = I(X >= 0) void project_sdc(gsl_matrix *X) { int n = X->size1; gsl_vector *d = gsl_vector_alloc(n); gsl_matrix *V = gsl_matrix_alloc(n,n); gsl_eigen_symmv_workspace *w = gsl_eigen_symmv_alloc(n); gsl_eigen_symmv(X, d, V, w); gsl_eigen_symmv_free(w); int i; double d_i; gsl_matrix_set_zero(X); for (i = 0; i < n; i++) { d_i = gsl_vector_get(d, i); if (d_i > 0) { gsl_vector_view V_i = gsl_matrix_column(V, i); gsl_blas_dsyr(CblasLower, d_i, &V_i.vector, X); } } gsl_vector_free(d); gsl_matrix_free(V); }
/** * C++ version of gsl_blas_dsyr(). * @param Uplo Upper or lower triangular * @param alpha A constant * @param X A vector * @param A A matrix * @return Error code on failure */ int dsyr( CBLAS_UPLO_t Uplo, double alpha, vector const& X, matrix& A ){ return gsl_blas_dsyr( Uplo, alpha, X.get(), A.get() ); }