Пример #1
0
/* Tridiagonal Decomposition of Real Symmetric Matrices */
CAMLprim value ml_gsl_linalg_symmtd_decomp(value A, value TAU)
{
  _DECLARE_MATRIX(A);
  _DECLARE_VECTOR(TAU);
  _CONVERT_MATRIX(A);
  _CONVERT_VECTOR(TAU);
  gsl_linalg_symmtd_decomp(&m_A, &v_TAU);
  return Val_unit;
}
Пример #2
0
 /**
  * C++ version of gsl_linalg_symmtd_decomp().
  * @param A A matrix
  * @param tau A vector
  * @return Error code on failure
  */
 inline int symmtd_decomp( matrix& A, vector& tau ){
   return gsl_linalg_symmtd_decomp( A.get(), tau.get() ); } 
Пример #3
0
int
gsl_eigen_symmv (gsl_matrix * A, gsl_vector * eval, gsl_matrix * evec,
                       gsl_eigen_symmv_workspace * w)
{
  if (A->size1 != A->size2)
    {
      GSL_ERROR ("matrix must be square to compute eigenvalues", GSL_ENOTSQR);
    }
  else if (eval->size != A->size1)
    {
      GSL_ERROR ("eigenvalue vector must match matrix size", GSL_EBADLEN);
    }
  else if (evec->size1 != A->size1 || evec->size2 != A->size1)
    {
      GSL_ERROR ("eigenvector matrix must match matrix size", GSL_EBADLEN);
    }
  else
    {
      double *const d = w->d;
      double *const sd = w->sd;
      const size_t N = A->size1;
      size_t a, b;

      /* handle special case */

      if (N == 1)
        {
          double A00 = gsl_matrix_get (A, 0, 0);
          gsl_vector_set (eval, 0, A00);
          gsl_matrix_set (evec, 0, 0, 1.0);
          return GSL_SUCCESS;
        }

      /* use sd as the temporary workspace for the decomposition when
         computing eigenvectors */

      {
        gsl_vector_view d_vec = gsl_vector_view_array (d, N);
        gsl_vector_view sd_vec = gsl_vector_view_array (sd, N - 1);
        gsl_vector_view tau = gsl_vector_view_array (sd, N - 1);
        gsl_linalg_symmtd_decomp (A, &tau.vector);
        gsl_linalg_symmtd_unpack (A, &tau.vector, evec, &d_vec.vector, &sd_vec.vector);
      }

      /* Make an initial pass through the tridiagonal decomposition
         to remove off-diagonal elements which are effectively zero */
      
      chop_small_elements (N, d, sd);
      
      /* Progressively reduce the matrix until it is diagonal */
      
      b = N - 1;
      
      while (b > 0)
        {
          if (sd[b - 1] == 0.0 || isnan(sd[b - 1]))
            {
              b--;
              continue;
            }
          
          /* Find the largest unreduced block (a,b) starting from b
             and working backwards */
          
          a = b - 1;
          
          while (a > 0)
            {
              if (sd[a - 1] == 0.0)
                {
                  break;
                }
              a--;
            }
          
          {
            size_t i;
            const size_t n_block = b - a + 1;
            double *d_block = d + a;
            double *sd_block = sd + a;
            double * const gc = w->gc;
            double * const gs = w->gs;
            
            /* apply QR reduction with implicit deflation to the
               unreduced block */
            
            qrstep (n_block, d_block, sd_block, gc, gs);
            
            /* Apply  Givens rotation Gij(c,s) to matrix Q,  Q <- Q G */
            
            for (i = 0; i < n_block - 1; i++)
              {
                const double c = gc[i], s = gs[i];
                size_t k;
                
                for (k = 0; k < N; k++)
                  {
                    double qki = gsl_matrix_get (evec, k, a + i);
                    double qkj = gsl_matrix_get (evec, k, a + i + 1);
                    gsl_matrix_set (evec, k, a + i, qki * c - qkj * s);
                    gsl_matrix_set (evec, k, a + i + 1, qki * s + qkj * c);
                  }
              }
            
            /* remove any small off-diagonal elements */
            
            chop_small_elements (N, d, sd);
          }
        }

      {
        gsl_vector_view d_vec = gsl_vector_view_array (d, N);
        gsl_vector_memcpy (eval, &d_vec.vector);
      }
      
      return GSL_SUCCESS;
    }
}
Пример #4
0
int
gsl_eigen_symm (gsl_matrix * A, gsl_vector * eval,
                     gsl_eigen_symm_workspace * w)
{
  if (A->size1 != A->size2)
    {
      GSL_ERROR ("matrix must be square to compute eigenvalues", GSL_ENOTSQR);
    }
  else if (eval->size != A->size1)
    {
      GSL_ERROR ("eigenvalue vector must match matrix size", GSL_EBADLEN);
    }
  else
    {
      const size_t N = A->size1;
      double *const d = w->d;
      double *const sd = w->sd;

      size_t a, b;

      /* handle special case */

      if (N == 1)
        {
          double A00 = gsl_matrix_get (A, 0, 0);
          gsl_vector_set (eval, 0, A00);
          return GSL_SUCCESS;
        }

      /* use sd as the temporary workspace for the decomposition,
         since we can discard the tau result immediately if we are not
         computing eigenvectors */

      {
        gsl_vector_view d_vec = gsl_vector_view_array (d, N);
        gsl_vector_view sd_vec = gsl_vector_view_array (sd, N - 1);
        gsl_vector_view tau = gsl_vector_view_array (sd, N - 1);
        gsl_linalg_symmtd_decomp (A, &tau.vector);
        gsl_linalg_symmtd_unpack_T (A, &d_vec.vector, &sd_vec.vector);
      }
      
      /* Make an initial pass through the tridiagonal decomposition
         to remove off-diagonal elements which are effectively zero */
      
      chop_small_elements (N, d, sd);
      
      /* Progressively reduce the matrix until it is diagonal */
      
      b = N - 1;
      
      while (b > 0)
        {
          if (sd[b - 1] == 0.0 || isnan(sd[b - 1]))
            {
              b--;
              continue;
            }
          
          /* Find the largest unreduced block (a,b) starting from b
             and working backwards */
          
          a = b - 1;
          
          while (a > 0)
            {
              if (sd[a - 1] == 0.0)
                {
                  break;
                }
              a--;
            }
          
          {
            const size_t n_block = b - a + 1;
            double *d_block = d + a;
            double *sd_block = sd + a;
            
            /* apply QR reduction with implicit deflation to the
               unreduced block */
            
            qrstep (n_block, d_block, sd_block, NULL, NULL);
            
            /* remove any small off-diagonal elements */
            
            chop_small_elements (n_block, d_block, sd_block);
          }
        }
      
      {
        gsl_vector_view d_vec = gsl_vector_view_array (d, N);
        gsl_vector_memcpy (eval, &d_vec.vector);
      }

      return GSL_SUCCESS;
    }
}
Пример #5
0
int main(int argc, char **argv) {
    gsl_rng *rng;
    gsl_rng_env_setup();
    const gsl_rng_type *rngType = gsl_rng_default;
    rng = gsl_rng_alloc(rngType);

    const size_t M = SIZE1;
    const size_t N = SIZE2;

    gsl_matrix *A = gsl_matrix_alloc(M, N);

    int i = 0;
    int j = 0;
    int sigNum = 0;

    for (i = 0; i < M; i++) {
        for (j = 0; j < N; j++) {
            gsl_matrix_set(A, i, j, gsl_ran_ugaussian(rng));
        }
    }

    gsl_matrix *B = gsl_matrix_alloc(M, N);
    gsl_matrix_memcpy(B, A);
    gsl_matrix *C = gsl_matrix_alloc(M, N);
    gsl_blas_dgemm(CblasNoTrans, CblasTrans, 1.0, A, B, 0.0, C);
    gsl_matrix *D = gsl_matrix_alloc(M, N);
    gsl_matrix_memcpy(D, C);        // will be used in QTQ' decompostion
    gsl_linalg_cholesky_decomp(C);
    printf("%e\n", gsl_matrix_get(C, M/2, N/2));
    gsl_matrix_free(B);

    gsl_matrix *A1 = gsl_matrix_alloc(M, N);
    gsl_matrix_memcpy(A1, A);
    gsl_permutation *P = gsl_permutation_alloc(M); // will be used in
    // other cases
    gsl_permutation_init(P);
    gsl_ran_shuffle (rng, P->data, M, sizeof(size_t));
    gsl_linalg_LU_decomp(A1, P, &sigNum);
    printf("%e\n", gsl_matrix_get(A1, M/2, N/2));

    gsl_matrix *A2 = gsl_matrix_alloc(M, N);
    gsl_matrix_memcpy(A2, A);
    gsl_vector *tau = gsl_vector_alloc(GSL_MIN(M, N));
    gsl_linalg_QR_decomp(A2, tau);
    printf("%e\n", gsl_matrix_get(A2, M/2, N/2));
    gsl_vector_free(tau);

    gsl_matrix *A3 = gsl_matrix_alloc(M, N);
    gsl_matrix_memcpy(A3, A);
    gsl_matrix *svdV = gsl_matrix_alloc(N, N);
    gsl_vector *svdS = gsl_vector_alloc(N);
    gsl_vector *svdWorkspace = gsl_vector_alloc(N);
    gsl_linalg_SV_decomp(A3, svdV, svdS, svdWorkspace);
    printf("%e\n", gsl_vector_get(svdS, N/2));

    gsl_vector *tau2 = gsl_vector_alloc(N - 1);
    gsl_linalg_symmtd_decomp(D, tau2);
    printf("%e\n", gsl_matrix_get(D, N/2, N/2));

    return 0;
}