bool Matrix_Transpose(gsl_matrix_complex *A, gsl_matrix_complex *B){ gsl_matrix_complex_transpose_memcpy(A,B); return true; }
int lls_complex_lcurve(gsl_vector *reg_param, gsl_vector *rho, gsl_vector *eta, lls_complex_workspace *w) { const size_t N = rho->size; /* number of points on L-curve */ if (N != reg_param->size) { GSL_ERROR("size of reg_param and rho do not match", GSL_EBADLEN); } else if (N != eta->size) { GSL_ERROR("size of eta and rho do not match", GSL_EBADLEN); } else { int s; const gsl_complex negtwo = gsl_complex_rect(-2.0, 0.0); /* smallest regularization parameter */ const double smin_ratio = 16.0 * GSL_DBL_EPSILON; double s1, sp, ratio, tmp; size_t i; /* compute eigenvalues of A^H A */ gsl_matrix_complex_transpose_memcpy(w->work_A, w->AHA); s = gsl_eigen_herm(w->work_A, w->eval, w->eigen_p); if (s) return s; /* find largest and smallest eigenvalues */ gsl_vector_minmax(w->eval, &sp, &s1); /* singular values are square roots of eigenvalues */ s1 = sqrt(s1); if (sp > GSL_DBL_EPSILON) sp = sqrt(fabs(sp)); tmp = GSL_MAX(sp, s1*smin_ratio); gsl_vector_set(reg_param, N - 1, tmp); /* ratio so that reg_param(1) = s(1) */ ratio = pow(s1 / tmp, 1.0 / (N - 1.0)); /* calculate the regularization parameters */ for (i = N - 1; i > 0 && i--; ) { double rp1 = gsl_vector_get(reg_param, i + 1); gsl_vector_set(reg_param, i, ratio * rp1); } for (i = 0; i < N; ++i) { double r2; double lambda = gsl_vector_get(reg_param, i); gsl_complex val; lls_complex_solve(lambda, w->c, w); /* store ||c|| */ gsl_vector_set(eta, i, gsl_blas_dznrm2(w->c)); /* compute: A^H A c - 2 A^H b */ gsl_vector_complex_memcpy(w->work_b, w->AHb); gsl_blas_zhemv(CblasUpper, GSL_COMPLEX_ONE, w->AHA, w->c, negtwo, w->work_b); /* compute: c^T A^T A c - 2 c^T A^T b */ gsl_blas_zdotc(w->c, w->work_b, &val); r2 = GSL_REAL(val) + w->bHb; gsl_vector_set(rho, i, sqrt(r2)); } return GSL_SUCCESS; } } /* lls_complex_lcurve() */