Example #1
0
/*
  computes the svd of a complex matrix. Missing in gsl.
 */
int
svd(gsl_matrix_complex *A, gsl_matrix_complex *V, gsl_vector *S)
{
  int n = A->size1;
  gsl_eigen_hermv_workspace *gsl_work = gsl_eigen_hermv_alloc(n);
  gsl_matrix_complex *Asq = gsl_matrix_complex_alloc(n, n);
  gsl_complex zero = gsl_complex_rect(0., 0.);
  gsl_complex one = gsl_complex_rect(1., 0.);
  gsl_vector *e = gsl_vector_alloc(n);
  gsl_matrix_complex *U = gsl_matrix_complex_alloc(n, n);

  gsl_blas_zgemm(CblasNoTrans, CblasConjTrans, one, A, A, zero, Asq);  
  gsl_eigen_hermv(Asq, e, U, gsl_work);
  gsl_eigen_hermv_sort(e, U, GSL_EIGEN_SORT_VAL_DESC);

  gsl_blas_zgemm(CblasConjTrans, CblasNoTrans, one, A, A, zero, Asq);  
  gsl_eigen_hermv(Asq, e, V, gsl_work);
  gsl_eigen_hermv_sort(e, V, GSL_EIGEN_SORT_VAL_DESC);
  
  gsl_blas_zgemm(CblasNoTrans, CblasNoTrans, one, A, V, zero, Asq);  
  gsl_blas_zgemm(CblasConjTrans, CblasNoTrans, one, U, Asq, zero, A);
  for(int i=0; i<n; i++){
    gsl_complex x = gsl_matrix_complex_get(A, i, i);
    double phase = gsl_complex_arg(gsl_complex_mul_real(x, 1./sqrt(e->data[i])));
    gsl_vector_complex_view U_col = gsl_matrix_complex_column(U, i);
    gsl_vector_complex_scale(&U_col.vector, gsl_complex_polar(1., phase));
    gsl_vector_set(S, i, sqrt(gsl_vector_get(e, i)));
  }

  gsl_matrix_complex_memcpy(A, U);
  gsl_vector_free(e);
  gsl_matrix_complex_free(U);
  gsl_matrix_complex_free(Asq);
  gsl_eigen_hermv_free(gsl_work);
  return 0;
}
Example #2
0
/// Multiply by a number
/// @param d :: The number
ComplexVector &ComplexVector::operator*=(const ComplexType d) {
  gsl_vector_complex_scale(gsl(), gsl_complex{{d.real(), d.imag()}});
  return *this;
}
Example #3
0
int
lls_complex_stdform(gsl_matrix_complex *A, gsl_vector_complex *b,
                    const gsl_vector *wts, const gsl_vector *L,
                    lls_complex_workspace *w)
{
  const size_t n = A->size1;
  const size_t p = A->size2;

  if (p != w->p)
    {
      fprintf(stderr, "lls_complex_stdform: A has wrong size2\n");
      return GSL_EBADLEN;
    }
  else if (n != b->size)
    {
      fprintf(stderr, "lls_complex_stdform: b has wrong size\n");
      return GSL_EBADLEN;
    }
  else if (wts != NULL && n != wts->size)
    {
      fprintf(stderr, "lls_complex_stdform: wts has wrong size\n");
      return GSL_EBADLEN;
    }
  else if (L != NULL && p != L->size)
    {
      fprintf(stderr, "lls_complex_stdform: L has wrong size\n");
      return GSL_EBADLEN;
    }
  else
    {
      int s = 0;
      size_t i;

      if (wts != NULL)
        {
          for (i = 0; i < n; ++i)
            {
              gsl_vector_complex_view rv = gsl_matrix_complex_row(A, i);
              gsl_complex bi = gsl_vector_complex_get(b, i);
              double wi = gsl_vector_get(wts, i);
              double sqrtwi = sqrt(wi);
              gsl_complex val;

              GSL_SET_COMPLEX(&val, sqrtwi, 0.0);

              /* A <- sqrt(W) A */
              gsl_vector_complex_scale(&rv.vector, val);

              /* b <- sqrt(W) b */
              val = gsl_complex_mul_real(bi, sqrtwi);
              gsl_vector_complex_set(b, i, val);
            }
        }

      if (L != NULL)
        {
          /* A <- sqrt(W) A L^{-1} */
          for (i = 0; i < p; ++i)
            {
              gsl_vector_complex_view cv = gsl_matrix_complex_column(A, i);
              double Li = gsl_vector_get(L, i);
              gsl_complex val;

              if (Li == 0.0)
                {
                  GSL_ERROR("L matrix is singular", GSL_ESING);
                }

              GSL_SET_COMPLEX(&val, 1.0 / Li, 0.0);

              gsl_vector_complex_scale(&cv.vector, val);
            }
        }

      return s;
    }
} /* lls_complex_stdform() */