inline void glue_solve::solve_direct(Mat<eT>& out, Mat<eT>& A, const Base<eT,T2>& X, const bool slow) { arma_extra_debug_sigprint(); const uword A_n_rows = A.n_rows; const uword A_n_cols = A.n_cols; bool status = false; if(A_n_rows == A_n_cols) { status = auxlib::solve(out, A, X, slow); } else if(A_n_rows > A_n_cols) { arma_extra_debug_print("solve(): detected over-determined system"); status = auxlib::solve_od(out, A, X); } else { arma_extra_debug_print("solve(): detected under-determined system"); status = auxlib::solve_ud(out, A, X); } if(status == false) { out.reset(); arma_bad("solve(): solution not found"); } }
inline arma_hot arma_pure typename arma_cx_only<eT>::result op_dot::direct_dot(const uword n_elem, const eT* const A, const eT* const B) { if( n_elem <= 16u ) { return op_dot::direct_dot_arma(n_elem, A, B); } else { #if defined(ARMA_USE_ATLAS) { arma_extra_debug_print("atlas::cx_cblas_dot()"); return atlas::cx_cblas_dot(n_elem, A, B); } #elif defined(ARMA_USE_BLAS) { arma_extra_debug_print("blas::dot()"); return blas::dot(n_elem, A, B); } #else { return op_dot::direct_dot_arma(n_elem, A, B); } #endif } }
arma_hot arma_pure inline typename arma_float_only<eT>::result op_dot::direct_dot(const uword n_elem, const eT* const A, const eT* const B) { arma_extra_debug_sigprint(); if( n_elem <= (128/sizeof(eT)) ) { return op_dot::direct_dot_arma(n_elem, A, B); } else { #if defined(ARMA_USE_ATLAS) { arma_extra_debug_print("atlas::cblas_dot()"); return atlas::cblas_dot(n_elem, A, B); } #elif defined(ARMA_USE_BLAS) { arma_extra_debug_print("blas::dot()"); return blas::dot(n_elem, A, B); } #else { return op_dot::direct_dot_arma(n_elem, A, B); } #endif } }
inline void op_sort::apply_noalias(Mat<eT>& out, const Mat<eT>& X, const uword sort_type, const uword dim) { arma_extra_debug_sigprint(); if( (X.n_rows * X.n_cols) <= 1 ) { out = X; return; } if(dim == 0) // sort the contents of each column { arma_extra_debug_print("op_sort::apply(), dim = 0"); out = X; const uword n_rows = out.n_rows; const uword n_cols = out.n_cols; for(uword col=0; col < n_cols; ++col) { op_sort::direct_sort( out.colptr(col), n_rows, sort_type ); } } else if(dim == 1) // sort the contents of each row { if(X.n_rows == 1) // a row vector { arma_extra_debug_print("op_sort::apply(), dim = 1, vector specific"); out = X; op_sort::direct_sort(out.memptr(), out.n_elem, sort_type); } else // not a row vector { arma_extra_debug_print("op_sort::apply(), dim = 1, generic"); out.copy_size(X); const uword n_rows = out.n_rows; const uword n_cols = out.n_cols; podarray<eT> tmp_array(n_cols); for(uword row=0; row < n_rows; ++row) { op_sort::copy_row(tmp_array.memptr(), X, row); op_sort::direct_sort( tmp_array.memptr(), n_cols, sort_type ); op_sort::copy_row(out, tmp_array.memptr(), row); } } } }
inline void op_stddev::apply(Mat<typename T1::pod_type>& out, const mtOp<typename T1::pod_type, T1, op_stddev>& in) { arma_extra_debug_sigprint(); typedef typename T1::elem_type in_eT; typedef typename T1::pod_type out_eT; const unwrap_check_mixed<T1> tmp(in.m, out); const Mat<in_eT>& X = tmp.M; const uword norm_type = in.aux_uword_a; const uword dim = in.aux_uword_b; arma_debug_check( (norm_type > 1), "stddev(): incorrect usage. norm_type must be 0 or 1"); arma_debug_check( (dim > 1), "stddev(): incorrect usage. dim must be 0 or 1" ); const uword X_n_rows = X.n_rows; const uword X_n_cols = X.n_cols; if(dim == 0) { arma_extra_debug_print("op_stddev::apply(), dim = 0"); arma_debug_check( (X_n_rows == 0), "stddev(): given object has zero rows" ); out.set_size(1, X_n_cols); out_eT* out_mem = out.memptr(); for(uword col=0; col<X_n_cols; ++col) { out_mem[col] = std::sqrt( op_var::direct_var( X.colptr(col), X_n_rows, norm_type ) ); } } else if(dim == 1) { arma_extra_debug_print("op_stddev::apply(), dim = 1"); arma_debug_check( (X_n_cols == 0), "stddev(): given object has zero columns" ); out.set_size(X_n_rows, 1); podarray<in_eT> dat(X_n_cols); in_eT* dat_mem = dat.memptr(); out_eT* out_mem = out.memptr(); for(uword row=0; row<X_n_rows; ++row) { dat.copy_row(X, row); out_mem[row] = std::sqrt( op_var::direct_var( dat_mem, X_n_cols, norm_type) ); } } }
inline void op_cumsum_mat::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_cumsum_mat>& in) { arma_extra_debug_sigprint(); typedef typename T1::elem_type eT; const unwrap<T1> tmp(in.m); const Mat<eT>& X = tmp.M; const uword dim = in.aux_uword_a; arma_debug_check( (dim > 1), "cumsum(): incorrect usage. dim must be 0 or 1"); out.copy_size(X); const uword X_n_rows = X.n_rows; const uword X_n_cols = X.n_cols; if(dim == 0) { arma_extra_debug_print("op_cumsum::apply(), dim = 0"); for(uword col=0; col<X_n_cols; ++col) { eT* out_colmem = out.colptr(col); const eT* X_colmem = X.colptr(col); eT acc = eT(0); for(uword row=0; row<X_n_rows; ++row) { acc += X_colmem[row]; out_colmem[row] = acc; } } } else if(dim == 1) { arma_extra_debug_print("op_cumsum::apply(), dim = 1"); for(uword row=0; row<X_n_rows; ++row) { eT acc = eT(0); for(uword col=0; col<X_n_cols; ++col) { acc += X.at(row,col); out.at(row,col) = acc; } } } }
inline void op_min::apply(Mat< std::complex<T> >& out, const Op<T1,op_min>& in) { arma_extra_debug_sigprint(); typedef typename std::complex<T> eT; isnt_same_type<eT, typename T1::elem_type>::check(); const unwrap_check<T1> tmp(in.m, out); const Mat<eT>& X = tmp.M; arma_debug_check( (X.n_elem == 0), "min(): given matrix has no elements" ); const u32 dim = in.aux_u32_a; arma_debug_check( (dim > 1), "min(): incorrect usage. dim must be 0 or 1"); if(dim == 0) // column-wise min { arma_extra_debug_print("op_min::apply(), dim = 0"); out.set_size(1, X.n_cols); for(u32 col=0; col<X.n_cols; ++col) { out[col] = op_min::direct_min( X.colptr(col), X.n_rows ); } } else if(dim == 1) // row-wise min { arma_extra_debug_print("op_min::apply(), dim = 1"); out.set_size(X.n_rows, 1); for(u32 row=0; row<X.n_rows; ++row) { u32 index = 0; T min_val = std::abs(X.at(row,index)); for(u32 col=1; col<X.n_cols; ++col) { const T tmp_val = std::abs(X.at(row,col)); if(tmp_val < min_val) { min_val = tmp_val; index = col; } } out[row] = X.at(row,index); } } }
inline void op_min::apply_noalias(Mat<eT>& out, const Mat<eT>& X, const uword dim, const typename arma_not_cx<eT>::result* junk) { arma_extra_debug_sigprint(); arma_ignore(junk); const uword X_n_rows = X.n_rows; const uword X_n_cols = X.n_cols; if(dim == 0) { arma_extra_debug_print("op_min::apply(): dim = 0"); out.set_size((X_n_rows > 0) ? 1 : 0, X_n_cols); if(X_n_rows == 0) { return; } eT* out_mem = out.memptr(); for(uword col=0; col<X_n_cols; ++col) { out_mem[col] = op_min::direct_min( X.colptr(col), X_n_rows ); } } else if(dim == 1) { arma_extra_debug_print("op_min::apply(): dim = 1"); out.set_size(X_n_rows, (X_n_cols > 0) ? 1 : 0); if(X_n_cols == 0) { return; } eT* out_mem = out.memptr(); arrayops::copy(out_mem, X.colptr(0), X_n_rows); for(uword col=1; col<X_n_cols; ++col) { const eT* col_mem = X.colptr(col); for(uword row=0; row<X_n_rows; ++row) { const eT col_val = col_mem[row]; if(col_val < out_mem[row]) { out_mem[row] = col_val; } } } } }
inline void op_mean::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_mean>& in) { arma_extra_debug_sigprint(); typedef typename T1::elem_type eT; const unwrap_check<T1> tmp(in.m, out); const Mat<eT>& X = tmp.M; arma_debug_check( (X.n_elem == 0), "mean(): given matrix has no elements" ); const u32 dim = in.aux_u32_a; arma_debug_check( (dim > 1), "mean(): incorrect usage. dim must be 0 or 1"); if(dim == 0) { arma_extra_debug_print("op_mean::apply(), dim = 0"); out.set_size(1, X.n_cols); for(u32 col=0; col<X.n_cols; ++col) { out[col] = op_mean::direct_mean( X.colptr(col), X.n_rows ); } } else if(dim == 1) { arma_extra_debug_print("op_mean::apply(), dim = 1"); out.set_size(X.n_rows, 1); for(u32 row=0; row<X.n_rows; ++row) { eT val = eT(0); for(u32 col=0; col<X.n_cols; ++col) { val += X.at(row,col); } out[row] = val / eT(X.n_cols); } } }
inline void op_var::apply(Mat< typename get_pod_type<eT>::result >& out, const Mat<eT>& X, const u32 norm_type, const u32 dim) { arma_extra_debug_sigprint(); arma_debug_check( (X.n_elem == 0), "var(): given matrix has no elements" ); arma_debug_check( (norm_type > 1), "var(): incorrect usage. norm_type must be 0 or 1"); arma_debug_check( (dim > 1), "var(): incorrect usage. dim must be 0 or 1" ); if(dim == 0) { arma_extra_debug_print("op_var::apply(), dim = 0"); out.set_size(1, X.n_cols); for(u32 col=0; col<X.n_cols; ++col) { out[col] = op_var::direct_var( X.colptr(col), X.n_rows, norm_type ); } } else if(dim == 1) { arma_extra_debug_print("op_var::apply(), dim = 1"); const u32 n_rows = X.n_rows; const u32 n_cols = X.n_cols; out.set_size(n_rows, 1); podarray<eT> tmp(n_cols); eT* tmp_mem = tmp.memptr(); for(u32 row=0; row<n_rows; ++row) { for(u32 col=0; col<n_cols; ++col) { tmp_mem[col] = X.at(row,col); } out[row] = op_var::direct_var(tmp_mem, n_cols, norm_type); } } }
inline void op_max::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_max>& in) { arma_extra_debug_sigprint(); typedef typename T1::elem_type eT; const unwrap_check<T1> tmp(in.m, out); const Mat<eT>& X = tmp.M; const uword dim = in.aux_uword_a; arma_debug_check( (dim > 1), "max(): incorrect usage. dim must be 0 or 1"); const uword X_n_rows = X.n_rows; const uword X_n_cols = X.n_cols; if(dim == 0) { arma_extra_debug_print("op_max::apply(), dim = 0"); arma_debug_check( (X_n_rows == 0), "max(): given object has zero rows" ); out.set_size(1, X_n_cols); eT* out_mem = out.memptr(); for(uword col=0; col<X_n_cols; ++col) { out_mem[col] = op_max::direct_max( X.colptr(col), X_n_rows ); } } else if(dim == 1) { arma_extra_debug_print("op_max::apply(), dim = 1"); arma_debug_check( (X_n_cols == 0), "max(): given object has zero columns" ); out.set_size(X_n_rows, 1); eT* out_mem = out.memptr(); for(uword row=0; row<X_n_rows; ++row) { out_mem[row] = op_max::direct_max( X, row ); } } }
inline typename enable_if2< is_Mat<vec_type>::value && (is_signed<uT>::value == false), vec_type >::result regspace ( const typename vec_type::pod_type start, const uT delta, const typename vec_type::pod_type end ) { arma_extra_debug_sigprint(); arma_extra_debug_print("regspace(): unsigned version"); vec_type x; if( (delta == uT(+1)) && (start <= end) ) { internal_regspace_default_delta(x, start, end); } else { internal_regspace_var_delta(x, start, delta, end); } if(x.n_elem == 0) { if(is_Mat_only<vec_type>::value) { x.set_size(1,0); } } return x; }
inline typename T1::elem_type prod(const Op<T1, op_prod>& in) { arma_extra_debug_sigprint(); arma_extra_debug_print("prod(): two consecutive prod() calls detected"); typedef typename T1::elem_type eT; const unwrap<T1> tmp(in.m); const Mat<eT>& X = tmp.M; 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 const Col<eT>& Col<eT>::fixed<fixed_n_elem>::operator=(const eGlue<T1, T2, eglue_type>& X) { arma_extra_debug_sigprint(); arma_type_check(( is_same_type< eT, typename T1::elem_type >::no )); arma_type_check(( is_same_type< eT, typename T2::elem_type >::no )); const bool bad_alias = ( (eGlue<T1, T2, eglue_type>::proxy1_type::has_subview && X.P1.is_alias(*this)) || (eGlue<T1, T2, eglue_type>::proxy2_type::has_subview && X.P2.is_alias(*this)) ); if(bad_alias == false) { arma_debug_assert_same_size(fixed_n_elem, uword(1), X.get_n_rows(), X.get_n_cols(), "Col::fixed::operator="); eglue_type::apply(*this, X); } else { arma_extra_debug_print("bad_alias = true"); Col<eT> tmp(X); (*this) = tmp; } return *this; }
inline const Row<eT>& Row<eT>::fixed<fixed_n_elem>::operator=(const eOp<T1, eop_type>& X) { arma_extra_debug_sigprint(); arma_type_check(( is_same_type< eT, typename T1::elem_type >::no )); const bool bad_alias = (eOp<T1, eop_type>::proxy_type::has_subview && X.P.is_alias(*this)); if(bad_alias == false) { arma_debug_assert_same_size(uword(1), fixed_n_elem, X.get_n_rows(), X.get_n_cols(), "Row::fixed::operator="); eop_type::apply(*this, X); } else { arma_extra_debug_print("bad_alias = true"); Row<eT> tmp(X); (*this) = tmp; } return *this; }
inline bool op_logmat_cx::helper(Mat<eT>& A, const uword m) { arma_extra_debug_sigprint(); if(A.is_finite() == false) { return false; } const vec indices = regspace<vec>(1,m-1); mat tmp(m,m,fill::zeros); tmp.diag(-1) = indices / sqrt(square(2.0*indices) - 1.0); tmp.diag(+1) = indices / sqrt(square(2.0*indices) - 1.0); vec eigval; mat eigvec; const bool eig_ok = eig_sym_helper(eigval, eigvec, tmp, 'd', "logmat()"); if(eig_ok == false) { arma_extra_debug_print("logmat(): eig_sym() failed"); return false; } const vec nodes = (eigval + 1.0) / 2.0; const vec weights = square(eigvec.row(0).t()); const uword N = A.n_rows; Mat<eT> B(N,N,fill::zeros); Mat<eT> X; for(uword i=0; i < m; ++i) { // B += weights(i) * solve( (nodes(i)*A + eye< Mat<eT> >(N,N)), A ); //const bool solve_ok = solve( X, (nodes(i)*A + eye< Mat<eT> >(N,N)), A, solve_opts::fast ); const bool solve_ok = solve( X, trimatu(nodes(i)*A + eye< Mat<eT> >(N,N)), A ); if(solve_ok == false) { arma_extra_debug_print("logmat(): solve() failed"); return false; } B += weights(i) * X; } A = B; return true; }
arma_inline const T1& htrans(const Op<T1, op_htrans>& X) { arma_extra_debug_sigprint(); arma_extra_debug_print("htrans(): removing op_htrans"); return X.m; }
arma_inline const Op<T1, op_diagmat> trans(const Op<T1, op_diagmat>& X) { arma_extra_debug_sigprint(); arma_extra_debug_print("trans(): not applying op_trans to diagonal matrix"); return X; }
arma_inline const Op<T1, op_trans> htrans(const Base<typename T1::pod_type,T1>& X) { arma_extra_debug_sigprint(); arma_extra_debug_print("htrans(): non-complex object given -- using regular transpose"); return Op<T1, op_trans>(X.get_ref()); }
inline arma_warn_unused typename T1::elem_type mean(const SpOp<T1, spop_mean>& in) { arma_extra_debug_sigprint(); arma_extra_debug_print("mean(): two consecutive mean() calls detected"); return spop_mean::mean_all(in.m); }
inline arma_warn_unused typename T1::elem_type sum(const Op<T1, op_sum>& in) { arma_extra_debug_sigprint(); arma_extra_debug_print("sum(): two consecutive sum() calls detected"); return accu(in.m); }
arma_warn_unused inline typename T1::elem_type min(const Op<T1, op_min>& in) { arma_extra_debug_sigprint(); arma_extra_debug_print("min(): two consecutive min() calls detected"); return op_min::min(in.m); }
arma_warn_unused inline typename T1::elem_type min(const SpOp<T1, spop_min>& X) { arma_extra_debug_sigprint(); arma_extra_debug_print("min(): two consecutive min() calls detected"); return spop_min::vector_min(X.m); }
inline arma_warn_unused bool all(const mtOp<uword, T1, op_all>& in) { arma_extra_debug_sigprint(); arma_extra_debug_print("all(): two consecutive calls to all() detected"); return op_all::all_vec(in.m); }
arma_warn_unused inline typename T1::elem_type prod(const Op<T1, op_prod>& in) { arma_extra_debug_sigprint(); arma_extra_debug_print("prod(): two consecutive prod() calls detected"); return op_prod::prod( in.m ); }
inline void op_max::apply_noalias(Mat<eT>& out, const Mat<eT>& X, const uword dim, const typename arma_cx_only<eT>::result* junk) { arma_extra_debug_sigprint(); arma_ignore(junk); const uword X_n_rows = X.n_rows; const uword X_n_cols = X.n_cols; if(dim == 0) { arma_extra_debug_print("op_max::apply(): dim = 0"); out.set_size((X_n_rows > 0) ? 1 : 0, X_n_cols); if(X_n_rows == 0) { return; } eT* out_mem = out.memptr(); for(uword col=0; col<X_n_cols; ++col) { out_mem[col] = op_max::direct_max( X.colptr(col), X_n_rows ); } } else if(dim == 1) { arma_extra_debug_print("op_max::apply(): dim = 1"); out.set_size(X_n_rows, (X_n_cols > 0) ? 1 : 0); if(X_n_cols == 0) { return; } eT* out_mem = out.memptr(); for(uword row=0; row<X_n_rows; ++row) { out_mem[row] = op_max::direct_max( X, row ); } } }
arma_hot inline void op_strans2::apply(Mat<eT>& out, const TA& A, const eT val) { arma_extra_debug_sigprint(); if(&out != &A) { op_strans2::apply_noalias(out, A, val); } else { const uword n_rows = out.n_rows; const uword n_cols = out.n_cols; if(n_rows == n_cols) { arma_extra_debug_print("op_strans2::apply(): doing in-place transpose of a square matrix"); const uword N = n_rows; // TODO: do multiplication while swapping for(uword k=0; k < N; ++k) { eT* colptr = out.colptr(k); uword i,j; for(i=(k+1), j=(k+2); j < N; i+=2, j+=2) { std::swap(out.at(k,i), colptr[i]); std::swap(out.at(k,j), colptr[j]); } if(i < N) { std::swap(out.at(k,i), colptr[i]); } } arrayops::inplace_mul( out.memptr(), val, out.n_elem ); } else { Mat<eT> tmp; op_strans2::apply_noalias(tmp, A, val); out.steal_mem(tmp); } } }
inline bool op_sqrtmat::apply_direct(Mat< std::complex<typename T1::elem_type> >& out, const Base<typename T1::elem_type,T1>& expr) { arma_extra_debug_sigprint(); typedef typename T1::elem_type in_T; typedef typename std::complex<in_T> out_T; const Proxy<T1> P(expr.get_ref()); arma_debug_check( (P.get_n_rows() != P.get_n_cols()), "sqrtmat(): given matrix must be square sized" ); if(P.get_n_elem() == 0) { out.reset(); return true; } typename Proxy<T1>::ea_type Pea = P.get_ea(); Mat<out_T> U; Mat<out_T> S(P.get_n_rows(), P.get_n_cols()); out_T* Smem = S.memptr(); const uword N = P.get_n_elem(); for(uword i=0; i<N; ++i) { Smem[i] = std::complex<in_T>( Pea[i] ); } const bool schur_ok = auxlib::schur(U,S); if(schur_ok == false) { arma_extra_debug_print("sqrtmat(): schur decomposition failed"); out.reset(); return false; } const bool status = op_sqrtmat_cx::helper(S); const Mat<out_T> X = U*S; S.reset(); out = X*U.t(); return status; }
inline arma_warn_unused eT min(const Op<subview<eT>, op_min>& in) { arma_extra_debug_sigprint(); arma_extra_debug_print("max(): two consecutive max() calls detected"); const subview<eT>& X = in.m; arma_debug_check( (X.n_elem == 0), "max(): given matrix has no elements" ); return op_min::direct_min(X); }
arma_hot arma_pure inline eT op_cdot::direct_cdot(const uword n_elem, const eT* const A, const eT* const B) { arma_extra_debug_sigprint(); if( n_elem <= 32u ) { return op_cdot::direct_cdot_arma(n_elem, A, B); } else { #if defined(ARMA_USE_BLAS) { arma_extra_debug_print("blas::gemv()"); // using gemv() workaround due to compatibility issues with cdotc() and zdotc() const char trans = 'C'; const blas_int m = blas_int(n_elem); const blas_int n = 1; //const blas_int lda = (n_elem > 0) ? blas_int(n_elem) : blas_int(1); const blas_int inc = 1; const eT alpha = eT(1); const eT beta = eT(0); eT result[2]; // paranoia: using two elements instead of one //blas::gemv(&trans, &m, &n, &alpha, A, &lda, B, &inc, &beta, &result[0], &inc); blas::gemv(&trans, &m, &n, &alpha, A, &m, B, &inc, &beta, &result[0], &inc); return result[0]; } #elif defined(ARMA_USE_ATLAS) { // TODO: use dedicated atlas functions cblas_cdotc_sub() and cblas_zdotc_sub() and retune threshold return op_cdot::direct_cdot_arma(n_elem, A, B); } #else { return op_cdot::direct_cdot_arma(n_elem, A, B); } #endif } }