Example #1
0
Embedding MNF(const Matrix &data, const Matrix &noise_covariance, Index reduced_dimensions) {

    if (noise_covariance.cols() != noise_covariance.rows() || noise_covariance.rows() != data.cols()) {
        throw std::invalid_argument("The rows and columns of noise covariance should both equal to the columns of the data.");
    }
    if (reduced_dimensions == 0) reduced_dimensions = data.cols();
    if (reduced_dimensions > data.cols()) throw std::invalid_argument("Reduced dimensions should be less than or equal to the total dimensions.");


    Matrix U1(noise_covariance);
    Matrix V1(data.cols(), data.cols());

    gsl_vector *S1v = gsl_vector_alloc(data.cols());

    gsl_linalg_SV_decomp_jacobi(U1.m_, V1.m_, S1v);

    Matrix wX(data.rows(), data.cols());
    Matrix wXintermediate(data.cols(), data.cols());
    Matrix invsqrtS1(data.cols(), data.cols());
    for (Index i = 0; i < data.cols(); ++i) {
        invsqrtS1(i, i) = 1.0 / sqrt(gsl_vector_get(S1v, i));
    }
    gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, 1.0, U1.m_, invsqrtS1.m_, 0.0, wXintermediate.m_);
    gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, 1.0, data.m_, wXintermediate.m_, 0.0, wX.m_);
    gsl_blas_dgemm(CblasTrans, CblasNoTrans, 1.0, wX.m_, wX.m_, 0.0, wXintermediate.m_);


    Matrix V2(data.cols(), data.cols());
    gsl_vector *S2v = gsl_vector_alloc(data.cols());
    gsl_linalg_SV_decomp_jacobi(wXintermediate.m_, V2.m_, S2v);


    Embedding result;
    result.space = std::make_shared<gsl::Matrix>(data.rows(), reduced_dimensions);
    result.vectors = std::make_shared<gsl::Matrix>(data.cols(), data.cols());
    result.values = std::make_shared<gsl::Matrix>(1, data.cols());

    Matrix intermediate2(data.cols(), data.cols());
    gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, 1.0, invsqrtS1.m_, V2.m_, 0.0, intermediate2.m_);
    gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, 1.0, U1.m_, intermediate2.m_, 0.0, result.vectors->m_);

    gsl_matrix_const_view reduced_vectors = gsl_matrix_const_submatrix(result.vectors->m_, 0, 0, result.vectors->rows(), reduced_dimensions);

    gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, 1.0, data.m_, &reduced_vectors.matrix, 0.0, result.space->m_);


    // TODO: assign eigenvalues and eigenvectors

    gsl_vector_free(S1v);
    gsl_vector_free(S2v);

    return result;
}
Example #2
0
 	void SVD_jacobi(
 		matrix& A,
 		matrix& V,
 		vector& S) {
 		int ret = gsl_linalg_SV_decomp_jacobi(
 			A.ptr_,
 			V.ptr_,
 			S.ptr_);
 	}
Example #3
0
CAMLprim value ml_gsl_linalg_SV_decomp_jacobi(value A, value V, value S)
{
  _DECLARE_MATRIX2(A, V);
  _DECLARE_VECTOR(S);
  _CONVERT_MATRIX2(A, V);
  _CONVERT_VECTOR(S);
  gsl_linalg_SV_decomp_jacobi(&m_A, &m_V, &v_S);
  return Val_unit;
}
Example #4
0
void test_nullspace_gsl(CuTest* tc) {
    int i, j;
    gsl_matrix* A;
    gsl_matrix* V;
    gsl_matrix* U;
    gsl_vector* S;
    gsl_matrix_view vcov;
    double cov[4] = {-0.93390448957619598, 1.8004204750064117, 0, 0};
    int M=2, N=2;

    A = gsl_matrix_alloc(M, N);
    S = gsl_vector_alloc(N);
    V = gsl_matrix_alloc(N, N);

    vcov = gsl_matrix_view_array(cov, M, N);
    gsl_matrix_memcpy(A, &(vcov.matrix));

    gsl_linalg_SV_decomp_jacobi(A, V, S);
    // the U result is written to A.
    U = A;

    printf("S = [");
    for (i=0; i<N; i++)
        printf(" %g", gsl_vector_get(S, i));
    printf(" ]\n");

    printf("U = [");
    for (j=0; j<M; j++) {
        if (j)
            printf("    [");
        for (i=0; i<N; i++)
            printf(" %g", gsl_matrix_get(U, j, i));
        printf(" ]\n");
    }

    printf("V = [");
    for (j=0; j<N; j++) {
        if (j)
            printf("    [");
        for (i=0; i<N; i++)
            printf(" %g", gsl_matrix_get(V, j, i));
        printf(" ]\n");
    }

    CuAssertDblEquals(tc, 0, gsl_vector_get(S, 1), 1e-6);
    CuAssertDblEquals(tc, 2.02822373, gsl_vector_get(S, 0), 1e-6);

    gsl_matrix_free(A);
    gsl_matrix_free(V);
    gsl_vector_free(S);

}
Example #5
0
 /**
  * C++ version of gsl_linalg_SV_decomp_jacobi().
  * @param A A matrix
  * @param Q A matrix
  * @param S A vector
  * @return Error code on failure
  */
 inline int SV_decomp_jacobi( matrix& A, matrix& Q, vector& S ){
   return gsl_linalg_SV_decomp_jacobi( A.get(), Q.get(), S.get() ); } 
Example #6
0
int ap_svd_jacobi(gsl_matrix * u, gsl_vector * s, gsl_matrix * v,
                  gsl_matrix const * a){
  gsl_matrix_memcpy(u, a);
  assert(GSL_SUCCESS == gsl_linalg_SV_decomp_jacobi(u, v, s));
  return GSL_SUCCESS;
}
Example #7
0
/* Return the pixel scale of the dataset in units of the WCS. */
double *
gal_wcs_pixel_scale(struct wcsprm *wcs)
{
  gsl_vector S;
  gsl_matrix A, V;
  int warning_printed;
  size_t i, j, maxj, n=wcs->naxis;
  double jvmax, *a, *out, maxrow, minrow;
  double *v=gal_data_malloc_array(GAL_TYPE_FLOAT64, n*n, __func__, "v");
  size_t *permutation=gal_data_malloc_array(GAL_TYPE_SIZE_T, n, __func__,
                                            "permutation");
  gal_data_t *pixscale=gal_data_alloc(NULL, GAL_TYPE_FLOAT64, 1, &n, NULL,
                                      0, -1, NULL, NULL, NULL);


  /* Write the full WCS rotation matrix into an array, irrespective of what
     style it was stored in the wcsprm structure (`PCi_j' style or `CDi_j'
     style). */
  a=gal_wcs_warp_matrix(wcs);


  /* To avoid confusing issues with floating point errors being written in
     the non-diagonal elements of the FITS header PC or CD matrices, we
     need to check if the minimum and maximum values in each row are not
     several orders of magnitude apart.

     Note that in some cases (for example a spectrum), one axis might be in
     degrees (value around 1e-5) and the other in angestroms (value around
     1e-10). So we can't look at the minimum and maximum of the whole
     matrix. However, in such cases, people will probably not warp/rotate
     the image to mix the coordinates. So the important thing to check is
     the minimum and maximum (non-zero) values in each row. */
  warning_printed=0;
  for(i=0;i<n;++i)
    {
      /* Find the minimum and maximum values in each row. */
      minrow=FLT_MAX;
      maxrow=-FLT_MAX;
      for(j=0;j<n;++j)
        if(a[i*n+j]!=0.0) /* We aren't concerned with 0 valued elements. */
          {
            /* We have to use absolutes because in cases like RA, the
               diagonal values in different rows may have different signs*/
            if(fabs(a[i*n+j])<minrow) minrow=fabs(a[i*n+j]);
            if(fabs(a[i*n+j])>maxrow) maxrow=fabs(a[i*n+j]);
          }

      /* Do the check, print warning and make correction. */
      if(maxrow!=minrow && maxrow/minrow>1e4 && warning_printed==0)
        {
          fprintf(stderr, "\nWARNING: The input WCS matrix (possibly taken "
                  "from the FITS header keywords starting with `CD' or `PC') "
                  "contains values with very different scales (more than "
                  "10^4 different). This is probably due to floating point "
                  "errors. These values might bias the pixel scale (and "
                  "subsequent) calculations.\n\n"
                  "You can see the respective matrix with one of the "
                  "following two commands (depending on how the FITS file "
                  "was written). Recall that if the desired extension/HDU "
                  "isn't the default, you can choose it with the `--hdu' "
                  "(or `-h') option before the `|' sign in these commands."
                  "\n\n"
                  "    $ astfits file.fits -p | grep 'PC._.'\n"
                  "    $ astfits file.fits -p | grep 'CD._.'\n\n"
                  "You can delete the ones with obvious floating point "
                  "error values using the following command (assuming you "
                  "want to delete `CD1_2' and `CD2_1'). Afterwards, you can "
                  "rerun your original command to remove this warning "
                  "message and possibly correct errors that it might have "
                  "caused.\n\n"
                  "    $ astfits file.fits --delete=CD1_2 --delete=CD2_1\n\n"
                  );
          warning_printed=1;
        }
    }


  /* Fill in the necessary GSL vector and Matrix structures. */
  S.size=n;     S.stride=1;                S.data=pixscale->array;
  V.size1=n;    V.size2=n;    V.tda=n;     V.data=v;
  A.size1=n;    A.size2=n;    A.tda=n;     A.data=a;


  /* Run GSL's Singular Value Decomposition, using one-sided Jacobi
     orthogonalization which computes the singular (scale) values to a
     higher relative accuracy. */
  gsl_linalg_SV_decomp_jacobi(&A, &V, &S);


  /* The raw pixel scale array produced from the singular value
     decomposition above is ordered based on values, not the input. So when
     the pixel scales in all the dimensions aren't the same (the units of
     the dimensions differ), the order of the values in `pixelscale' will
     not necessarily correspond to the input's dimensions.

     To correct the order, we can use the `V' matrix to find the original
     position of the pixel scale values and then use permutation to
     re-order it correspondingly. The column with the largest (absolute)
     value will be taken as the one to be used for each row. */
  for(i=0;i<n;++i)
    {
      /* Find the column with the maximum value. */
      maxj=-1;
      jvmax=-FLT_MAX;
      for(j=0;j<n;++j)
        if(fabs(v[i*n+j])>jvmax)
          {
            maxj=j;
            jvmax=fabs(v[i*n+j]);
          }

      /* Use the column with the maximum value for this dimension. */
      permutation[i]=maxj;
    }


  /* Apply the permutation described above. */
  gal_permutation_apply(pixscale, permutation);


  /* Clean up and return. */
  free(a);
  free(v);
  free(permutation);
  out=pixscale->array;
  pixscale->array=NULL;
  gal_data_free(pixscale);
  return out;
}
Example #8
0
int wrap_gsl_linalg_SV_decomp_jacobi(gsl_matrix* A, gsl_matrix* V,
				     gsl_matrix* S)
{
  gsl_vector_view _S = gsl_matrix_diagonal(S);
  return gsl_linalg_SV_decomp_jacobi(A, V, &_S.vector);
}