Exemple #1
0
static VALUE rb_gsl_blas_zdotc(int argc, VALUE *argv, VALUE obj)
{
  gsl_complex *r;
  int status;
  gsl_vector_complex *x = NULL, *y = NULL;
  get_vector_complex2(argc, argv, obj, &x, &y);
  r = ALLOC(gsl_complex);
  status = gsl_blas_zdotc(x, y, r);
  return Data_Wrap_Struct(cgsl_complex, 0, free, r);
}
Exemple #2
0
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() */
Exemple #3
0
 /**
  * C++ version of gsl_blas_zdotc().
  * @param X First vector
  * @param Y Second vector
  * @param dotc Vector product
  * @return Error code on failure
  */
 int zdotc( vector_complex const& X, vector_complex const& Y, complex* dotc ){
   return gsl_blas_zdotc( X.get(), Y.get(), &dotc->get() ); }
Exemple #4
0
void
test_eigen_herm_results (const gsl_matrix_complex * A, 
                         const gsl_vector * eval, 
                         const gsl_matrix_complex * evec, 
                         size_t count,
                         const char * desc,
                         const char * desc2)
{
  const size_t N = A->size1;
  size_t i, j;

  gsl_vector_complex * x = gsl_vector_complex_alloc(N);
  gsl_vector_complex * y = gsl_vector_complex_alloc(N);

  /* check eigenvalues */

  for (i = 0; i < N; i++)
    {
      double ei = gsl_vector_get (eval, i);
      gsl_vector_complex_const_view vi =
        gsl_matrix_complex_const_column(evec, i);
      gsl_vector_complex_memcpy(x, &vi.vector);
      /* compute y = m x (should = lambda v) */
      gsl_blas_zgemv (CblasNoTrans, GSL_COMPLEX_ONE, A, x, 
                      GSL_COMPLEX_ZERO, y);
      for (j = 0; j < N; j++)
        {
          gsl_complex xj = gsl_vector_complex_get (x, j);
          gsl_complex yj = gsl_vector_complex_get (y, j);
          gsl_test_rel(GSL_REAL(yj), ei * GSL_REAL(xj), 1e8*GSL_DBL_EPSILON, 
                       "%s, eigenvalue(%d,%d), real, %s", desc, i, j, desc2);
          gsl_test_rel(GSL_IMAG(yj), ei * GSL_IMAG(xj), 1e8*GSL_DBL_EPSILON, 
                       "%s, eigenvalue(%d,%d), imag, %s", desc, i, j, desc2);
        }
    }

  /* check eigenvectors are orthonormal */

  for (i = 0; i < N; i++)
    {
      gsl_vector_complex_const_view vi = gsl_matrix_complex_const_column(evec, i);
      double nrm_v = gsl_blas_dznrm2(&vi.vector);
      gsl_test_rel (nrm_v, 1.0, N * GSL_DBL_EPSILON, "%s, normalized(%d), %s", 
                    desc, i, desc2);
    }

  for (i = 0; i < N; i++)
    {
      gsl_vector_complex_const_view vi = gsl_matrix_complex_const_column(evec, i);
      for (j = i + 1; j < N; j++)
        {
          gsl_vector_complex_const_view vj 
            = gsl_matrix_complex_const_column(evec, j);
          gsl_complex vivj;
          gsl_blas_zdotc (&vi.vector, &vj.vector, &vivj);
          gsl_test_abs (gsl_complex_abs(vivj), 0.0, 10.0 * N * GSL_DBL_EPSILON, 
                        "%s, orthogonal(%d,%d), %s", desc, i, j, desc2);
        }
    }

  gsl_vector_complex_free(x);
  gsl_vector_complex_free(y);
} /* test_eigen_herm_results() */
Exemple #5
0
int
gsl_linalg_complex_cholesky_decomp(gsl_matrix_complex *A)
{
  const size_t N = A->size1;
  
  if (N != A->size2)
    {
      GSL_ERROR("cholesky decomposition requires square matrix", GSL_ENOTSQR);
    }
  else
    {
      size_t i, j;
      gsl_complex z;
      double ajj;

      for (j = 0; j < N; ++j)
        {
          z = gsl_matrix_complex_get(A, j, j);
          ajj = GSL_REAL(z);

          if (j > 0)
            {
              gsl_vector_complex_const_view aj =
                gsl_matrix_complex_const_subrow(A, j, 0, j);

              gsl_blas_zdotc(&aj.vector, &aj.vector, &z);
              ajj -= GSL_REAL(z);
            }

          if (ajj <= 0.0)
            {
              GSL_ERROR("matrix is not positive definite", GSL_EDOM);
            }

          ajj = sqrt(ajj);
          GSL_SET_COMPLEX(&z, ajj, 0.0);
          gsl_matrix_complex_set(A, j, j, z);

          if (j < N - 1)
            {
              gsl_vector_complex_view av =
                gsl_matrix_complex_subcolumn(A, j, j + 1, N - j - 1);

              if (j > 0)
                {
                  gsl_vector_complex_view aj =
                    gsl_matrix_complex_subrow(A, j, 0, j);
                  gsl_matrix_complex_view am =
                    gsl_matrix_complex_submatrix(A, j + 1, 0, N - j - 1, j);

                  cholesky_complex_conj_vector(&aj.vector);

                  gsl_blas_zgemv(CblasNoTrans,
                                 GSL_COMPLEX_NEGONE,
                                 &am.matrix,
                                 &aj.vector,
                                 GSL_COMPLEX_ONE,
                                 &av.vector);

                  cholesky_complex_conj_vector(&aj.vector);
                }

              gsl_blas_zdscal(1.0 / ajj, &av.vector);
            }
        }

      /* Now store L^H in upper triangle */
      for (i = 1; i < N; ++i)
        {
          for (j = 0; j < i; ++j)
            {
              z = gsl_matrix_complex_get(A, i, j);
              gsl_matrix_complex_set(A, j, i, gsl_complex_conjugate(z));
            }
        }

      return GSL_SUCCESS;
    }
} /* gsl_linalg_complex_cholesky_decomp() */
Exemple #6
0
int
gsl_linalg_complex_cholesky_invert(gsl_matrix_complex * LLT)
{
  if (LLT->size1 != LLT->size2)
    {
      GSL_ERROR ("cholesky matrix must be square", GSL_ENOTSQR);
    }
  else
    {
      size_t N = LLT->size1;
      size_t i, j;
      gsl_vector_complex_view v1;

      /* invert the lower triangle of LLT */
      for (i = 0; i < N; ++i)
        {
          double ajj;
          gsl_complex z;

          j = N - i - 1;

          { 
            gsl_complex z0 = gsl_matrix_complex_get(LLT, j, j);
            ajj = 1.0 / GSL_REAL(z0); 
          }

          GSL_SET_COMPLEX(&z, ajj, 0.0);
          gsl_matrix_complex_set(LLT, j, j, z);

          {
            gsl_complex z1 = gsl_matrix_complex_get(LLT, j, j);
            ajj = -GSL_REAL(z1);
          }

          if (j < N - 1)
            {
              gsl_matrix_complex_view m;
              
              m = gsl_matrix_complex_submatrix(LLT, j + 1, j + 1,
                                       N - j - 1, N - j - 1);
              v1 = gsl_matrix_complex_subcolumn(LLT, j, j + 1, N - j - 1);

              gsl_blas_ztrmv(CblasLower, CblasNoTrans, CblasNonUnit,
                             &m.matrix, &v1.vector);

              gsl_blas_zdscal(ajj, &v1.vector);
            }
        } /* for (i = 0; i < N; ++i) */

      /*
       * The lower triangle of LLT now contains L^{-1}. Now compute
       * A^{-1} = L^{-H} L^{-1}
       *
       * The (ij) element of A^{-1} is column i of conj(L^{-1}) dotted into
       * column j of L^{-1}
       */

      for (i = 0; i < N; ++i)
        {
          gsl_complex sum;
          for (j = i + 1; j < N; ++j)
            {
              gsl_vector_complex_view v2;
              v1 = gsl_matrix_complex_subcolumn(LLT, i, j, N - j);
              v2 = gsl_matrix_complex_subcolumn(LLT, j, j, N - j);

              /* compute Ainv[i,j] = sum_k{conj(Linv[k,i]) * Linv[k,j]} */
              gsl_blas_zdotc(&v1.vector, &v2.vector, &sum);

              /* store in upper triangle */
              gsl_matrix_complex_set(LLT, i, j, sum);
            }

          /* now compute the diagonal element */
          v1 = gsl_matrix_complex_subcolumn(LLT, i, i, N - i);
          gsl_blas_zdotc(&v1.vector, &v1.vector, &sum);
          gsl_matrix_complex_set(LLT, i, i, sum);
        }

      /* copy the Hermitian upper triangle to the lower triangle */

      for (j = 1; j < N; j++)
        {
          for (i = 0; i < j; i++)
            {
              gsl_complex z = gsl_matrix_complex_get(LLT, i, j);
              gsl_matrix_complex_set(LLT, j, i, gsl_complex_conjugate(z));
            }
        } 

      return GSL_SUCCESS;
    }
} /* gsl_linalg_complex_cholesky_invert() */
int main(void) {
  gsl_matrix *TS; /* the training set of real waveforms */
  gsl_matrix_complex *cTS; /* the training set of complex waveforms */

  size_t TSsize;  /* the size of the training set (number of waveforms) */
  size_t wl;      /* the length of each waveform */
  size_t k = 0, j = 0, i = 0, nbases = 0, cnbases = 0;

  REAL8 *RB = NULL;        /* the real reduced basis set */
  COMPLEX16 *cRB = NULL;   /* the complex reduced basis set */
  LALInferenceREALROQInterpolant *interp = NULL;
  LALInferenceCOMPLEXROQInterpolant *cinterp = NULL;

  gsl_vector *freqs;

  double tolerance = TOLERANCE; /* tolerance for reduced basis generation loop */

  TSsize = TSSIZE;
  wl = WL;

  /* allocate memory for training set */
  TS = gsl_matrix_calloc(TSsize, wl);
  cTS = gsl_matrix_complex_calloc(TSsize, wl);

  /* the waveform model is just a simple chirp so set up chirp mass range for training set */
  double fmin0 = 48, fmax0 = 256, f0 = 0., m0 = 0.;
  double df = (fmax0-fmin0)/(wl-1.); /* model time steps */
  freqs = gsl_vector_alloc(wl); /* times at which to calculate the model */
  double Mcmax = 2., Mcmin = 1.5, Mc = 0.;

  gsl_vector_view fweights = gsl_vector_view_array(&df, 1);

  /* set up training sets (one real and one complex) */
  for ( k=0; k < TSsize; k++ ){
    Mc = pow(pow(Mcmin, 5./3.) + (double)k*(pow(Mcmax, 5./3.)-pow(Mcmin, 5./3.))/((double)TSsize-1), 3./5.);

    for ( j=0; j < wl; j++ ){
      f0 = fmin0 + (double)j*(fmax0-fmin0)/((double)wl-1.);

      gsl_complex gctmp;
      COMPLEX16 ctmp;
      m0 = real_model(f0, Mc);
      ctmp = imag_model(f0, Mc);
      GSL_SET_COMPLEX(&gctmp, creal(ctmp), cimag(ctmp));
      gsl_vector_set(freqs, j, f0);
      gsl_matrix_set(TS, k, j, m0);
      gsl_matrix_complex_set(cTS, k, j, gctmp);
    }
  }

  /* create reduced orthonormal basis from training set */
  if ( (RB = LALInferenceGenerateREAL8OrthonormalBasis(&fweights.vector, tolerance, TS, &nbases)) == NULL){
    fprintf(stderr, "Error... problem producing basis\n");
    return 1;
  }

  if ( (cRB = LALInferenceGenerateCOMPLEX16OrthonormalBasis(&fweights.vector, tolerance, cTS, &cnbases)) == NULL){
    fprintf(stderr, "Error... problem producing basis\n");
    return 1;
  }

  /* free the training set */
  gsl_matrix_free(TS);
  gsl_matrix_complex_free(cTS);

  gsl_matrix_view RBview = gsl_matrix_view_array(RB, nbases, wl);
  gsl_matrix_complex_view cRBview = gsl_matrix_complex_view_array((double*)cRB, cnbases, wl);

  fprintf(stderr, "No. nodes (real)  = %zu, %zu x %zu\n", nbases, RBview.matrix.size1, RBview.matrix.size2);
  fprintf(stderr, "No. nodes (complex)  = %zu, %zu x %zu\n", cnbases, cRBview.matrix.size1, cRBview.matrix.size2);

  /* get the interpolant */
  interp = LALInferenceGenerateREALROQInterpolant(&RBview.matrix);
  cinterp = LALInferenceGenerateCOMPLEXROQInterpolant(&cRBview.matrix);

  /* free the reduced basis */
  XLALFree(RB);
  XLALFree(cRB);

  /* now get the terms for the likelihood with and without the reduced order quadrature
   * and do some timing tests */

  /* create the model dot model weights */
  REAL8 varval = 1.;
  gsl_vector_view vars = gsl_vector_view_array(&varval, 1);

  gsl_matrix *mmw = LALInferenceGenerateREALModelModelWeights(interp->B, &vars.vector);
  gsl_matrix_complex *cmmw = LALInferenceGenerateCOMPLEXModelModelWeights(cinterp->B, &vars.vector);

  /* let's create some Gaussian random data */
  const gsl_rng_type *T;
  gsl_rng *r;

  gsl_rng_env_setup();

  T = gsl_rng_default;
  r = gsl_rng_alloc(T);

  REAL8 *data = XLALCalloc(wl, sizeof(REAL8));
  COMPLEX16 *cdata = XLALCalloc(wl, sizeof(COMPLEX16));
  for ( i=0; i<wl; i++ ){
    data[i] = gsl_ran_gaussian(r, 1.0);                               /* real data */
    cdata[i] = gsl_ran_gaussian(r, 1.0) + I*gsl_ran_gaussian(r, 1.0); /* complex data */
  }

  /* create the data dot model weights */
  gsl_vector_view dataview = gsl_vector_view_array(data, wl);
  gsl_vector *dmw = LALInferenceGenerateREAL8DataModelWeights(interp->B, &dataview.vector, &vars.vector);

  gsl_vector_complex_view cdataview = gsl_vector_complex_view_array((double*)cdata, wl);
  gsl_vector_complex *cdmw = LALInferenceGenerateCOMPLEX16DataModelWeights(cinterp->B, &cdataview.vector, &vars.vector);

  /* pick a chirp mass and generate a model to compare likelihoods */
  double randMc = 1.873; /* a random frequency to create a model */

  gsl_vector *modelfull = gsl_vector_alloc(wl);
  gsl_vector *modelreduced = gsl_vector_alloc(nbases);
  gsl_vector_complex *cmodelfull = gsl_vector_complex_alloc(wl);
  gsl_vector_complex *cmodelreduced = gsl_vector_complex_alloc(cnbases);

  /* create models */
  for ( i=0; i<wl; i++ ){
    /* models at all frequencies */
    gsl_vector_set(modelfull, i, real_model(gsl_vector_get(freqs, i), randMc));

    COMPLEX16 cval = imag_model(gsl_vector_get(freqs, i), randMc);
    gsl_complex gcval;
    GSL_SET_COMPLEX(&gcval, creal(cval), cimag(cval));
    gsl_vector_complex_set(cmodelfull, i, gcval);
  }

  /* models at interpolant nodes */
  for ( i=0; i<nbases; i++ ){ /* real model */
    gsl_vector_set(modelreduced, i, real_model(gsl_vector_get(freqs, interp->nodes[i]), randMc));
  }
  for ( i=0; i<cnbases; i++ ){ /* complex model */
    COMPLEX16 cval = imag_model(gsl_vector_get(freqs, cinterp->nodes[i]), randMc);
    gsl_complex gcval;
    GSL_SET_COMPLEX(&gcval, creal(cval), cimag(cval));
    gsl_vector_complex_set(cmodelreduced, i, gcval);
  }

  /* timing variables */
  struct timeval t1, t2, t3, t4;
  double dt1, dt2;

  /* start with the real model */
  /* get the model model term with the full model */
  REAL8 mmfull, mmred;
  gettimeofday(&t1, NULL);
  XLAL_CALLGSL( gsl_blas_ddot(modelfull, modelfull, &mmfull) );        /* real model */
  gettimeofday(&t2, NULL);

  /* now get it with the reduced order quadrature */
  gettimeofday(&t3, NULL);
  mmred = LALInferenceROQREAL8ModelDotModel(mmw, modelreduced);
  gettimeofday(&t4, NULL);

  dt1 = (double)((t2.tv_sec + t2.tv_usec*1.e-6) - (t1.tv_sec + t1.tv_usec*1.e-6));
  dt2 = (double)((t4.tv_sec + t4.tv_usec*1.e-6) - (t3.tv_sec + t3.tv_usec*1.e-6));
  fprintf(stderr, "Real Signal:\n - M dot M (full) = %le [%.9lf s], M dot M (reduced) = %le [%.9lf s], time ratio = %lf\n", mmfull, dt1, mmred, dt2, dt1/dt2);

  /* get the data model term with the full model */
  REAL8 dmfull, dmred;
  gettimeofday(&t1, NULL);
  XLAL_CALLGSL( gsl_blas_ddot(&dataview.vector, modelfull, &dmfull) );
  gettimeofday(&t2, NULL);

  /* now get it with the reduced order quadrature */
  gettimeofday(&t3, NULL);
  dmred = LALInferenceROQREAL8DataDotModel(dmw, modelreduced);
  gettimeofday(&t4, NULL);

  dt1 = (double)((t2.tv_sec + t2.tv_usec*1.e-6) - (t1.tv_sec + t1.tv_usec*1.e-6));
  dt2 = (double)((t4.tv_sec + t4.tv_usec*1.e-6) - (t3.tv_sec + t3.tv_usec*1.e-6));
  fprintf(stderr, " - D dot M (full) = %le [%.9lf s], D dot M (reduced) = %le [%.9lf s], time ratio = %lf\n", dmfull, dt1, dmred, dt2, dt1/dt2);

  /* check difference in log likelihoods */
  double Lfull, Lred, Lfrac;

  Lfull = mmfull - 2.*dmfull;
  Lred = mmred - 2.*dmred;
  Lfrac = 100.*fabs(Lfull-Lred)/fabs(Lfull); /* fractional log likelihood difference (in %) */

  fprintf(stderr, " - Fractional difference in log likelihoods = %lf%%\n", Lfrac);

  XLALFree(data);
  gsl_vector_free(modelfull);
  gsl_vector_free(modelreduced);
  gsl_matrix_free(mmw);
  gsl_vector_free(dmw);

  /* check log likelihood difference is within tolerance */
  if ( Lfrac > LTOL ) { return 1; }

  /* now do the same with the complex model */
  /* get the model model term with the full model */
  COMPLEX16 cmmred, cmmfull;
  gsl_complex cmmfulltmp;
  gettimeofday(&t1, NULL);
  XLAL_CALLGSL( gsl_blas_zdotc(cmodelfull, cmodelfull, &cmmfulltmp) ); /* complex model */
  cmmfull = GSL_REAL(cmmfulltmp) + I*GSL_IMAG(cmmfulltmp);
  gettimeofday(&t2, NULL);

  gettimeofday(&t3, NULL);
  cmmred = LALInferenceROQCOMPLEX16ModelDotModel(cmmw, cmodelreduced);
  gettimeofday(&t4, NULL);

  dt1 = (double)((t2.tv_sec + t2.tv_usec*1.e-6) - (t1.tv_sec + t1.tv_usec*1.e-6));
  dt2 = (double)((t4.tv_sec + t4.tv_usec*1.e-6) - (t3.tv_sec + t3.tv_usec*1.e-6));
  fprintf(stderr, "Complex Signal:\n - M dot M (full) = %le [%.9lf s], M dot M (reduced) = %le [%.9lf s], time ratio = %lf\n", creal(cmmfull), dt1, creal(cmmred), dt2, dt1/dt2);

  COMPLEX16 cdmfull, cdmred;
  gsl_complex cdmfulltmp;
  gettimeofday(&t1, NULL);
  XLAL_CALLGSL( gsl_blas_zdotc(&cdataview.vector, cmodelfull, &cdmfulltmp) );
  cdmfull = GSL_REAL(cdmfulltmp) + I*GSL_IMAG(cdmfulltmp);
  gettimeofday(&t2, NULL);

  gettimeofday(&t3, NULL);
  cdmred = LALInferenceROQCOMPLEX16DataDotModel(cdmw, cmodelreduced);
  gettimeofday(&t4, NULL);

  dt1 = (double)((t2.tv_sec + t2.tv_usec*1.e-6) - (t1.tv_sec + t1.tv_usec*1.e-6));
  dt2 = (double)((t4.tv_sec + t4.tv_usec*1.e-6) - (t3.tv_sec + t3.tv_usec*1.e-6));
  fprintf(stderr, " - D dot M (full) = %le [%.9lf s], D dot M (reduced) = %le [%.9lf s], time ratio = %lf\n", creal(cdmfull), dt1, creal(cdmred), dt2, dt1/dt2);

  /* check difference in log likelihoods */
  Lfull = creal(cmmfull) - 2.*creal(cdmfull);
  Lred = creal(cmmred) - 2.*creal(cdmred);
  Lfrac = 100.*fabs(Lfull-Lred)/fabs(Lfull); /* fractional log likelihood difference (in %) */

  fprintf(stderr, " - Fractional difference in log likelihoods = %lf%%\n", Lfrac);

  XLALFree(cdata);
  gsl_vector_complex_free(cmodelfull);
  gsl_vector_complex_free(cmodelreduced);
  gsl_matrix_complex_free(cmmw);
  gsl_vector_complex_free(cdmw);
  LALInferenceRemoveREALROQInterpolant( interp );
  LALInferenceRemoveCOMPLEXROQInterpolant( cinterp );

  /* check log likelihood difference is within tolerance */
  if ( Lfrac > LTOL ) { return 1; }

  return 0;
}
Exemple #8
0
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() */
Exemple #9
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;
    }
}