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]); } }
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); }
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); }
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; }
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); } }
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 }
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; } }
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; }
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; }
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); } }
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); } }