示例#1
0
文件: lls_complex.c 项目: pa345/lib
int
lls_complex_solve(const double lambda, gsl_vector_complex *c, lls_complex_workspace *w)
{
  if (c->size != w->p)
    {
      fprintf(stderr, "lls_complex_solve: coefficient vector has wrong size\n");
      return GSL_EBADLEN;
    }
  else
    {
      int s = 0;

      /* solve (AHA + lambda^2 I) c = AHb and estimate condition number */
      s = lls_lapack_zposv(lambda, c, w);

      /* compute residual || AHA c - AHb || */
      gsl_vector_complex_memcpy(w->work_b, w->AHb);
      gsl_blas_zhemv(CblasUpper, GSL_COMPLEX_ONE, w->AHA, c, GSL_COMPLEX_NEGONE, w->work_b);
      w->residual = gsl_blas_dznrm2(w->work_b);

      /* compute chi^2 = b^H b - 2 c^H A^H b + c^H A^H A c */
      {
        gsl_complex negtwo = gsl_complex_rect(-2.0, 0.0);
        gsl_complex val;

        /* compute: AHA c - 2 AHb */
        gsl_vector_complex_memcpy(w->work_b, w->AHb);
        gsl_blas_zhemv(CblasUpper, GSL_COMPLEX_ONE, w->AHA, c, negtwo, w->work_b);

        /* compute: c^H ( AHA c - 2 AHb ) */
        gsl_blas_zdotc(c, w->work_b, &val);

        w->chisq = w->bHb + GSL_REAL(val);
      }

      /* save coefficient vector for future robust iterations */
      gsl_vector_complex_memcpy(w->c, c);

      ++(w->niter);

      return s;
    }
} /* lls_complex_solve() */
示例#2
0
    /**
     * C++ version of gsl_blas_zhemv().
     * @param Uplo Upper or lower triangular
     * @param alpha A constant
     * @param A A matrix
     * @param X A vector
     * @param beta Another constant
     * @param Y A vector
     * @return Error code on failure
     */
    int zhemv( CBLAS_UPLO_t Uplo, complex const& alpha, matrix_complex const& A,
	       vector_complex const& X, complex const& beta, vector_complex& Y ){
      return gsl_blas_zhemv( Uplo, alpha.get(), A.get(), X.get(), beta.get(), Y.get() ); }
示例#3
0
文件: lls_complex.c 项目: pa345/lib
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() */
示例#4
0
int 
gsl_linalg_hermtd_decomp (gsl_matrix_complex * A, gsl_vector_complex * tau)  
{
  if (A->size1 != A->size2)
    {
      GSL_ERROR ("hermitian tridiagonal decomposition requires square matrix",
                 GSL_ENOTSQR);
    }
  else if (tau->size + 1 != A->size1)
    {
      GSL_ERROR ("size of tau must be (matrix size - 1)", GSL_EBADLEN);
    }
  else
    {
      const size_t N = A->size1;
      size_t i;
  
      const gsl_complex zero = gsl_complex_rect (0.0, 0.0);
      const gsl_complex one = gsl_complex_rect (1.0, 0.0);
      const gsl_complex neg_one = gsl_complex_rect (-1.0, 0.0);

      for (i = 0 ; i < N - 1; i++)
        {
          gsl_vector_complex_view c = gsl_matrix_complex_column (A, i);
          gsl_vector_complex_view v = gsl_vector_complex_subvector (&c.vector, i + 1, N - (i + 1));
          gsl_complex tau_i = gsl_linalg_complex_householder_transform (&v.vector);
          
          /* Apply the transformation H^T A H to the remaining columns */

          if ((i + 1) < (N - 1) 
              && !(GSL_REAL(tau_i) == 0.0 && GSL_IMAG(tau_i) == 0.0)) 
            {
              gsl_matrix_complex_view m = 
                gsl_matrix_complex_submatrix (A, i + 1, i + 1, 
                                              N - (i+1), N - (i+1));
              gsl_complex ei = gsl_vector_complex_get(&v.vector, 0);
              gsl_vector_complex_view x = gsl_vector_complex_subvector (tau, i, N-(i+1));
              gsl_vector_complex_set (&v.vector, 0, one);
              
              /* x = tau * A * v */
              gsl_blas_zhemv (CblasLower, tau_i, &m.matrix, &v.vector, zero, &x.vector);

              /* w = x - (1/2) tau * (x' * v) * v  */
              {
                gsl_complex xv, txv, alpha;
                gsl_blas_zdotc(&x.vector, &v.vector, &xv);
                txv = gsl_complex_mul(tau_i, xv);
                alpha = gsl_complex_mul_real(txv, -0.5);
                gsl_blas_zaxpy(alpha, &v.vector, &x.vector);
              }
              
              /* apply the transformation A = A - v w' - w v' */
              gsl_blas_zher2(CblasLower, neg_one, &v.vector, &x.vector, &m.matrix);

              gsl_vector_complex_set (&v.vector, 0, ei);
            }
          
          gsl_vector_complex_set (tau, i, tau_i);
        }
      
      return GSL_SUCCESS;
    }
}