inline
void
GenEigsSolver<eT, SelectionRule, OpType>::retrieve_ritzpair()
  {
  arma_extra_debug_sigprint();
  
  UpperHessenbergEigen<eT> decomp(fac_H);
  
  Col< std::complex<eT> > evals = decomp.eigenvalues();
  Mat< std::complex<eT> > evecs = decomp.eigenvectors();
  
  SortEigenvalue< std::complex<eT>, SelectionRule > sorting(evals.memptr(), evals.n_elem);
  std::vector<uword> ind = sorting.index();
  
  // Copy the ritz values and vectors to ritz_val and ritz_vec, respectively
  for(uword i = 0; i < ncv; i++)
    {
    ritz_val(i) = evals(ind[i]);
    ritz_est(i) = evecs(ncv - 1, ind[i]);
    }
  for(uword i = 0; i < nev; i++)
    {
    ritz_vec.col(i) = evecs.col(ind[i]);
    }
  }
예제 #2
0
inline
Col<eT>::Col(const Col<eT>& X)
  : Mat<eT>(arma_vec_indicator(), X.n_elem, 1, 1)
  {
  arma_extra_debug_sigprint();
  
  arrayops::copy((*this).memptr(), X.memptr(), X.n_elem);
  }
예제 #3
0
파일: Col_meat.hpp 프로젝트: iirob/wire
inline
Col<eT>::Col(const Col<eT>& X)
  : Mat<eT>(X.n_elem, 1)
  {
  arma_extra_debug_sigprint();
  
  access::rw(Mat<eT>::vec_state) = 1;
  
  arrayops::copy((*this).memptr(), X.memptr(), X.n_elem);
  }
예제 #4
0
inline
bool
op_null::apply_direct(Mat<typename T1::elem_type>& out, const Base<typename T1::elem_type,T1>& expr, typename T1::pod_type tol)
  {
  arma_extra_debug_sigprint();
  
  typedef typename T1::elem_type eT;
  typedef typename T1::pod_type   T;
  
  arma_debug_check((tol < T(0)), "null(): tolerance must be >= 0");
  
  const unwrap<T1>   tmp(expr.get_ref());
  const Mat<eT>& X = tmp.M;
  
  Mat<eT> U;
  Col< T> s;
  Mat<eT> V;
  
  const bool status = auxlib::svd_dc(U, s, V, X);
  
  U.reset();
  
  if(status == false)  { out.reset(); return false; }
  
  if(s.is_empty())  { out.reset(); return true; }
  
  const uword s_n_elem = s.n_elem;
  const T*    s_mem    = s.memptr();
  
  // set tolerance to default if it hasn't been specified
  if(tol == T(0))  { tol = (std::max)(X.n_rows, X.n_cols) * s_mem[0] * std::numeric_limits<T>::epsilon(); }
  
  uword count = 0;
  
  for(uword i=0; i < s_n_elem; ++i)  { count += (s_mem[i] > tol) ? uword(1) : uword(0); }
  
  if(count < X.n_cols)
    {
    out = V.tail_cols(X.n_cols - count);
    
    const uword out_n_elem = out.n_elem;
          eT*   out_mem    = out.memptr();
    
    for(uword i=0; i<out_n_elem; ++i)
      {
      if(std::abs(out_mem[i]) < std::numeric_limits<T>::epsilon())  { out_mem[i] = eT(0); }
      }
    }
  else
    {
    out.set_size(X.n_cols, 0);
    }
  
  return true;
  }
예제 #5
0
inline
arma_warn_unused
uword
rank
  (
  const Base<typename T1::elem_type,T1>& X,
        typename T1::pod_type            tol = 0.0,
  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
  )
  {
  arma_extra_debug_sigprint();
  arma_ignore(junk);
  
  typedef typename T1::pod_type T;
  
  uword  X_n_rows;
  uword  X_n_cols;
  Col<T> s;
  
  const bool  status = auxlib::svd_dc(s, X, X_n_rows, X_n_cols);
  const uword n_elem = s.n_elem;
  
  if(status == true)
    {
    if( (tol == T(0)) && (n_elem > 0) )
      {
      tol = (std::max)(X_n_rows, X_n_cols) * eop_aux::direct_eps(max(s));
      }
    
    // count non zero valued elements in s
    
    const T* s_mem = s.memptr();
    
    uword count = 0;
    
    for(uword i=0; i<n_elem; ++i)
      {
      if(s_mem[i] > tol) { ++count; }
      }
    
    return count;
    }
  else
    {
    arma_bad("rank(): failed to converge");
    
    return uword(0);
    }
  }
예제 #6
0
inline
bool
op_sqrtmat_sympd::apply_direct(Mat<typename T1::elem_type>& out, const Base<typename T1::elem_type,T1>& expr)
  {
  arma_extra_debug_sigprint();
  
  #if defined(ARMA_USE_LAPACK)
    {
    typedef typename T1::pod_type   T;
    typedef typename T1::elem_type eT;
    
    const unwrap<T1>   U(expr.get_ref());
    const Mat<eT>& X = U.M;
    
    arma_debug_check( (X.is_square() == false), "sqrtmat_sympd(): given matrix must be square sized" );
    
    Col< T> eigval;
    Mat<eT> eigvec;
    
    const bool status = auxlib::eig_sym_dc(eigval, eigvec, X);
    
    if(status == false)  { return false; }
    
    const uword N          = eigval.n_elem;
    const T*    eigval_mem = eigval.memptr();
    
    bool all_pos = true;
    
    for(uword i=0; i<N; ++i)  { all_pos = (eigval_mem[i] < T(0)) ? false : all_pos; }
    
    if(all_pos == false)  { return false; }
    
    eigval = sqrt(eigval);
    
    out = eigvec * diagmat(eigval) * eigvec.t();
    
    return true;
    }
  #else
    {
    arma_ignore(out);
    arma_ignore(expr);
    arma_stop_logic_error("sqrtmat_sympd(): use of LAPACK must be enabled");
    return false;
    }
  #endif
  }
예제 #7
0
inline
void
glue_trapz::apply_noalias(Mat<eT>& out, const Mat<eT>& X, const Mat<eT>& Y, const uword dim)
  {
  arma_extra_debug_sigprint();
  
  arma_debug_check( (dim > 1), "trapz(): argument 'dim' must be 0 or 1" );
  
  arma_debug_check( ((X.is_vec() == false) && (X.is_empty() == false)), "trapz(): argument 'X' must be a vector" );
  
  const uword N = X.n_elem;
  
  if(dim == 0)
    {
    arma_debug_check( (N != Y.n_rows), "trapz(): length of X must equal the number of rows in Y when dim=0" );
    }
  else
  if(dim == 1)
    {
    arma_debug_check( (N != Y.n_cols), "trapz(): length of X must equal the number of columns in Y when dim=1" );
    }
  
  if(N <= 1)
    {
         if(dim == 0)  { out.zeros(1, Y.n_cols); }
    else if(dim == 1)  { out.zeros(Y.n_rows, 1); }
    
    return;
    }
  
  const Col<eT> vec_X( const_cast<eT*>(X.memptr()), X.n_elem, false, true );
  
  const Col<eT> diff_X = diff(vec_X);
  
  if(dim == 0)
    {
    const Row<eT> diff_X_t( const_cast<eT*>(diff_X.memptr()), diff_X.n_elem, false, true );
    
    out = diff_X_t * (0.5 * (Y.rows(0, N-2) + Y.rows(1, N-1)));
    }
  else
  if(dim == 1)
    {
    out = (0.5 * (Y.cols(0, N-2) + Y.cols(1, N-1))) * diff_X;
    }
  }
예제 #8
0
arma_warn_unused
inline
uword
rank
  (
  const Base<typename T1::elem_type,T1>& X,
        typename T1::pod_type            tol = 0.0,
  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
  )
  {
  arma_extra_debug_sigprint();
  arma_ignore(junk);
  
  typedef typename T1::pod_type T;
  
  uword  X_n_rows;
  uword  X_n_cols;
  Col<T> s;
  
  const bool status = auxlib::svd_dc(s, X, X_n_rows, X_n_cols);
  
  if(status == false)
    {
    arma_stop_runtime_error("rank(): svd failed");
    
    return uword(0);
    }
  
  const uword s_n_elem = s.n_elem;
  const T*    s_mem    = s.memptr();
  
  // set tolerance to default if it hasn't been specified
  if( (tol == T(0)) && (s_n_elem > 0) )
    {
    tol = (std::max)(X_n_rows, X_n_cols) * s_mem[0] * std::numeric_limits<T>::epsilon();
    }
  
  uword count = 0;
  
  for(uword i=0; i < s_n_elem; ++i)  { count += (s_mem[i] > tol) ? uword(1) : uword(0); }
  
  return count;
  }
예제 #9
0
inline
eT
prod(const Col<eT>& X)
  {
  arma_extra_debug_sigprint();
  
  arma_debug_check( (X.n_elem < 1), "prod(): given object has no elements" );
  
  const u32 n_elem = X.n_elem;
  const eT* X_mem  = X.memptr();
  
  eT val = X_mem[0];
  
  for(u32 i=1; i<n_elem; ++i)
    {
    val *= X_mem[i];
    }
  
  return val;
  }
예제 #10
0
inline
void
op_pinv::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_pinv>& in)
  {
  arma_extra_debug_sigprint();
  
  typedef typename T1::elem_type            eT;
  typedef typename get_pod_type<eT>::result  T;
  
  const bool use_divide_and_conquer = (in.aux_uword_a == 1);
  
  T tol = access::tmp_real(in.aux);
  
  arma_debug_check((tol < T(0)), "pinv(): tolerance must be >= 0");
  
  const Proxy<T1> P(in.m);
  
  const uword n_rows = P.get_n_rows();
  const uword n_cols = P.get_n_cols();
  
  if( (n_rows*n_cols) == 0 )
    {
    out.set_size(n_cols,n_rows);
    return;
    }
  
  
  // economical SVD decomposition 
  Mat<eT> U;
  Col< T> s;
  Mat<eT> V;
  
  bool status = false;
  
  if(use_divide_and_conquer)
    {
    status = (n_cols > n_rows) ? auxlib::svd_dc_econ(U, s, V, trans(P.Q)) : auxlib::svd_dc_econ(U, s, V, P.Q);
    }
  else
    {
    status = (n_cols > n_rows) ? auxlib::svd_econ(U, s, V, trans(P.Q), 'b') : auxlib::svd_econ(U, s, V, P.Q, 'b');
    }
  
  if(status == false)
    {
    out.reset();
    arma_bad("pinv(): svd failed");
    return;
    }
  
  const uword s_n_elem = s.n_elem;
  const T*    s_mem    = s.memptr();
  
  // set tolerance to default if it hasn't been specified
  if( (tol == T(0)) && (s_n_elem > 0) )
    {
    tol = (std::max)(n_rows, n_cols) * s_mem[0] * std::numeric_limits<T>::epsilon();
    }
  
  
  uword count = 0;
  
  for(uword i = 0; i < s_n_elem; ++i)
    {
    count += (s_mem[i] >= tol) ? uword(1) : uword(0);
    }
  
  
  if(count > 0)
    {
    Col<T> s2(count);
    
    T* s2_mem = s2.memptr();
    
    uword count2 = 0;
    
    for(uword i=0; i < s_n_elem; ++i)
      {
      const T val = s_mem[i];
      
      if(val >= tol)  {  s2_mem[count2] = T(1) / val;  ++count2; }
      }
    
    
    if(n_rows >= n_cols)
      {
      out = ( (V.n_cols > count) ? V.cols(0,count-1) : V ) * diagmat(s2) * trans( (U.n_cols > count) ? U.cols(0,count-1) : U );
      }
    else
      {
      out = ( (U.n_cols > count) ? U.cols(0,count-1) : U ) * diagmat(s2) * trans( (V.n_cols > count) ? V.cols(0,count-1) : V );
      }
    }
  else
    {
    out.zeros(n_cols, n_rows);
    }
  }
예제 #11
0
inline
void
op_pinv::direct_pinv(Mat<eT>& out, const Mat<eT>& A, const eT in_tol)
  {
  arma_extra_debug_sigprint();
  
  typedef typename get_pod_type<eT>::result T;
  
  T tol = access::tmp_real(in_tol);
  
  arma_debug_check((tol < T(0)), "pinv(): tolerance must be >= 0");
  
  const uword n_rows = A.n_rows;
  const uword n_cols = A.n_cols;
  
  // economical SVD decomposition 
  Mat<eT> U;
  Col< T> s;
  Mat<eT> V;
  
  const bool status = (n_cols > n_rows) ? auxlib::svd_econ(U,s,V,trans(A),'b') : auxlib::svd_econ(U,s,V,A,'b');
  
  if(status == false)
    {
    out.reset();
    arma_bad("pinv(): svd failed");
    return;
    }
  
  const uword s_n_elem = s.n_elem;
  const T*    s_mem    = s.memptr();
  
  // set tolerance to default if it hasn't been specified as an argument 
  if( (tol == T(0)) && (s_n_elem > 0) )
    {
    tol = (std::max)(n_rows, n_cols) * eop_aux::direct_eps( op_max::direct_max(s_mem, s_n_elem) );
    }
  
  
  // count non zero valued elements in s
  
  uword count = 0;
  
  for(uword i = 0; i < s_n_elem; ++i)
    {
    if(s_mem[i] > tol)
      {
      ++count;
      }
    }
  
  if(count != 0)
    {
    Col<T> s2(count);
    
    T* s2_mem = s2.memptr();
    
    uword count2 = 0;
    
    for(uword i=0; i < s_n_elem; ++i)
      {
      const T val = s_mem[i];
      
      if(val > tol)
        {
        s2_mem[count2] = T(1) / val;
        ++count2;
        }
      }
    
    
    if(n_rows >= n_cols)
      {
      out = ( V.n_cols > count ? V.cols(0,count-1) : V ) * diagmat(s2) * trans( U.n_cols > count ? U.cols(0,count-1) : U );
      }
    else
      {
      out = ( U.n_cols > count ? U.cols(0,count-1) : U ) * diagmat(s2) * trans( V.n_cols > count ? V.cols(0,count-1) : V );
      }
    }
  else
    {
    out.zeros(n_cols, n_rows);
    }
  }