inline arma_warn_unused typename enable_if2 <(is_arma_sparse_type<T1>::value) && (is_arma_sparse_type<T2>::value) && (is_same_type<typename T1::elem_type, typename T2::elem_type>::value), typename T1::elem_type >::result dot ( const SpBase<typename T1::elem_type, T1>& x, const SpBase<typename T2::elem_type, T2>& y ) { arma_extra_debug_sigprint(); const SpProxy<T1> pa(x.get_ref()); const SpProxy<T2> pb(y.get_ref()); arma_debug_assert_same_size(pa.get_n_rows(), pa.get_n_cols(), pb.get_n_rows(), pb.get_n_cols(), "dot()"); typedef typename T1::elem_type eT; if((&(x.get_ref()) == &(y.get_ref())) && (SpProxy<T1>::must_use_iterator == false)) { // We can do it directly! return op_dot::direct_dot_arma(pa.get_n_nonzero(), pa.get_values(), pa.get_values()); } else { // Iterate over both objects and see when they are the same eT result = eT(0); typename SpProxy<T1>::const_iterator_type a_it = pa.begin(); typename SpProxy<T2>::const_iterator_type b_it = pb.begin(); while((a_it.pos() < pa.get_n_nonzero()) && (b_it.pos() < pb.get_n_nonzero())) { if(a_it == b_it) { result += (*a_it) * (*b_it); ++a_it; ++b_it; } else if((a_it.col() < b_it.col()) || ((a_it.col() == b_it.col()) && (a_it.row() < b_it.row()))) { // a_it is "behind" ++a_it; } else { // b_it is "behind" ++b_it; } } return result; } }
inline const SpGlue<T1, T2, spglue_join_rows> join_horiz(const SpBase<typename T1::elem_type,T1>& A, const SpBase<typename T1::elem_type,T2>& B) { arma_extra_debug_sigprint(); return SpGlue<T1, T2, spglue_join_rows>(A.get_ref(), B.get_ref()); }
inline const SpSubview<eT>& SpSubview<eT>::operator/=(const SpBase<eT, T1>& x) { arma_extra_debug_sigprint(); SpProxy<T1> p(x.get_ref()); arma_debug_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols(), "element-wise division"); if(p.is_alias(m) == false) { for(uword lcol = 0; lcol < n_cols; ++lcol) for(uword lrow = 0; lrow < n_rows; ++lrow) { at(lrow,lcol) /= p.at(lrow,lcol); } } else { const SpMat<eT> tmp(p.Q); (*this).operator/=(tmp); } return *this; }
inline arma_warn_unused typename enable_if2 <(is_arma_type<T1>::value) && (is_arma_sparse_type<T2>::value) && (is_same_type<typename T1::elem_type, typename T2::elem_type>::value), typename T1::elem_type >::result dot ( const Base<typename T1::elem_type, T1>& x, const SpBase<typename T2::elem_type, T2>& y ) { arma_extra_debug_sigprint(); const Proxy<T1> pa(x.get_ref()); const SpProxy<T2> pb(y.get_ref()); arma_debug_assert_same_size(pa.get_n_rows(), pa.get_n_cols(), pb.get_n_rows(), pb.get_n_cols(), "dot()"); typedef typename T1::elem_type eT; eT result = eT(0); typename SpProxy<T2>::const_iterator_type it = pb.begin(); // prefer_at_accessor won't save us operations while(it.pos() < pb.get_n_nonzero()) { result += (*it) * pa.at(it.row(), it.col()); ++it; } return result; }
arma_warn_unused inline Col<uword> find(const SpBase<typename T1::elem_type,T1>& X, const uword k = 0) { arma_extra_debug_sigprint(); const SpProxy<T1> P(X.get_ref()); const uword n_rows = P.get_n_rows(); const uword n_nz = P.get_n_nonzero(); Mat<uword> tmp(n_nz,1); uword* tmp_mem = tmp.memptr(); typename SpProxy<T1>::const_iterator_type it = P.begin(); for(uword i=0; i<n_nz; ++i) { const uword index = it.row() + it.col()*n_rows; tmp_mem[i] = index; ++it; } Col<uword> out; const uword count = (k == 0) ? uword(n_nz) : uword( (std::min)(n_nz, k) ); out.steal_mem_col(tmp, count); return out; }
inline void op_nonzeros::apply_noalias(Mat<typename T1::elem_type>& out, const SpBase<typename T1::elem_type,T1>& X) { arma_extra_debug_sigprint(); typedef typename T1::elem_type eT; const SpProxy<T1> P(X.get_ref()); const uword N = P.get_n_nonzero(); out.set_size(N,1); if(N > 0) { if(is_SpMat<typename SpProxy<T1>::stored_type>::value) { const unwrap_spmat<typename SpProxy<T1>::stored_type> U(P.Q); arrayops::copy(out.memptr(), U.M.values, N); } else { eT* out_mem = out.memptr(); typename SpProxy<T1>::const_iterator_type it = P.begin(); for(uword i=0; i<N; ++i) { out_mem[i] = (*it); ++it; } } } }
inline uword n_unique ( const SpBase<typename T1::elem_type, T1>& x, const SpBase<typename T2::elem_type, T2>& y, const op_n_unique_type junk ) { arma_extra_debug_sigprint(); const SpProxy<T1> pa(x.get_ref()); const SpProxy<T2> pb(y.get_ref()); return n_unique(pa,pb,junk); }
inline arma_warn_unused bool is_finite(const SpBase<typename T1::elem_type,T1>& X) { arma_extra_debug_sigprint(); const SpProxy<T1> P(X.get_ref()); if(is_SpMat<typename SpProxy<T1>::stored_type>::value) { const unwrap_spmat<typename SpProxy<T1>::stored_type> tmp(P.Q); return tmp.M.is_finite(); } else { typename SpProxy<T1>::const_iterator_type it = P.begin(); typename SpProxy<T1>::const_iterator_type it_end = P.end(); while(it != it_end) { if(arma_isfinite(*it) == false) { return false; } ++it; } } return true; }
inline Mat<typename T1::elem_type> spsolve ( const SpBase<typename T1::elem_type, T1>& A, const Base<typename T1::elem_type, T2>& B, const char* solver = "superlu", const spsolve_opts_base& settings = spsolve_opts_none(), const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0 ) { arma_extra_debug_sigprint(); arma_ignore(junk); typedef typename T1::elem_type eT; Mat<eT> out; const bool status = spsolve_helper(out, A.get_ref(), B.get_ref(), solver, settings); if(status == false) { arma_bad("spsolve(): solution not found"); } return out; }
inline const SpSubview<eT>& SpSubview<eT>::operator*=(const SpBase<eT, T1>& x) { arma_extra_debug_sigprint(); return (*this).operator=( (*this) * x.get_ref() ); }
arma_inline const SpOp<T1, spop_repmat> repmat(const SpBase<typename T1::elem_type,T1>& A, const uword r, const uword c) { arma_extra_debug_sigprint(); return SpOp<T1, spop_repmat>(A.get_ref(), r, c); }
inline const SpOp<T1, spop_reshape> reshape(const SpBase<typename T1::elem_type, T1>& X, const SizeMat& s) { arma_extra_debug_sigprint(); return SpOp<T1, spop_reshape>(X.get_ref(), s.n_rows, s.n_cols); }
arma_inline const SpOp<T1, spop_sqrt> sqrt(const SpBase<typename T1::elem_type,T1>& A) { arma_extra_debug_sigprint(); return SpOp<T1, spop_sqrt>(A.get_ref()); }
inline const SpSubview<eT>& SpSubview<eT>::operator%=(const SpBase<eT, T1>& x) { arma_extra_debug_sigprint(); // TODO: implement dedicated machinery return (*this).operator=( (*this) % x.get_ref() ); }
arma_inline const SpOp<T1, spop_abs> abs(const SpBase<typename T1::elem_type,T1>& X, const typename arma_not_cx<typename T1::elem_type>::result* junk = 0) { arma_extra_debug_sigprint(); arma_ignore(junk); return SpOp<T1, spop_abs>(X.get_ref()); }
arma_inline const mtSpOp<typename T1::pod_type, T1, spop_cx_abs> abs(const SpBase< std::complex<typename T1::pod_type>, T1>& X, const typename arma_cx_only<typename T1::elem_type>::result* junk = 0) { arma_extra_debug_sigprint(); arma_ignore(junk); return mtSpOp<typename T1::pod_type, T1, spop_cx_abs>(X.get_ref()); }
arma_warn_unused arma_inline typename enable_if2< is_cx<typename T1::elem_type>::yes, const SpOp<T1, spop_symmat_cx> >::result symmatl(const SpBase<typename T1::elem_type,T1>& X, const bool do_conj = true) { arma_extra_debug_sigprint(); return SpOp<T1, spop_symmat_cx>(X.get_ref(), 1, (do_conj ? 1 : 0)); }
inline SpRow<eT>::SpRow(const SpBase<eT,T1>& X) { arma_extra_debug_sigprint(); access::rw(SpMat<eT>::vec_state) = 2; SpMat<eT>::operator=(X.get_ref()); }
arma_warn_unused arma_inline typename enable_if2< is_cx<typename T1::elem_type>::no, const SpOp<T1, spop_symmat> >::result symmatl(const SpBase<typename T1::elem_type,T1>& X, const bool do_conj = false) { arma_extra_debug_sigprint(); arma_ignore(do_conj); return SpOp<T1, spop_symmat>(X.get_ref(), 1, 0); }
inline const SpRow<eT>& SpRow<eT>::operator=(const SpBase<eT,T1>& X) { arma_extra_debug_sigprint(); SpMat<eT>::operator=(X.get_ref()); return *this; }
arma_warn_unused inline uword size(const SpBase<typename T1::elem_type,T1>& X, const uword dim) { arma_extra_debug_sigprint(); const SpProxy<T1> P(X.get_ref()); return SizeMat( P.get_n_rows(), P.get_n_cols() )( dim ); }
inline const SpCol<eT>& SpCol<eT>::operator=(const SpBase<eT,T1>& X) { arma_extra_debug_sigprint(); access::rw(SpMat<eT>::vec_state) = 1; SpMat<eT>::operator=(X.get_ref()); return *this; }
inline const SpOp<T1,spop_htrans> htrans ( const SpBase<typename T1::elem_type, T1>& x, const typename arma_cx_only<typename T1::elem_type>::result* junk = 0 ) { arma_extra_debug_sigprint(); arma_ignore(junk); return SpOp<T1,spop_htrans>( x.get_ref() ); }
arma_warn_unused inline const SpOp<T1, spop_reverse> reverse ( const SpBase<typename T1::elem_type,T1>& X, const uword dim = 0 ) { arma_extra_debug_sigprint(); return SpOp<T1, spop_reverse>(X.get_ref(), dim, 0); }
arma_warn_unused inline Col<typename T1::elem_type> nonzeros(const SpBase<typename T1::elem_type,T1>& X) { arma_extra_debug_sigprint(); Col<typename T1::elem_type> out; op_nonzeros::apply_noalias(out, X.get_ref()); return out; }
inline SpMat<typename T1::elem_type> sprandn(const SpBase<typename T1::elem_type, T1>& X) { arma_extra_debug_sigprint(); typedef typename T1::elem_type eT; SpMat<eT> out( X.get_ref() ); arma_rng::randn<eT>::fill( access::rwp(out.values), out.n_nonzero ); return out; }
inline void spdiagview<eT>::operator/=(const SpBase<eT,T1>& o) { arma_extra_debug_sigprint(); spdiagview<eT>& d = *this; SpMat<eT>& d_m = const_cast< SpMat<eT>& >(d.m); const uword d_n_elem = d.n_elem; const uword d_row_offset = d.row_offset; const uword d_col_offset = d.col_offset; const SpProxy<T1> P( o.get_ref() ); arma_debug_check ( ( (d_n_elem != P.get_n_elem()) || ((P.get_n_rows() != 1) && (P.get_n_cols() != 1)) ), "spdiagview: given object has incompatible size" ); if( SpProxy<T1>::must_use_iterator || P.is_alias(d_m) ) { const SpMat<eT> tmp(P.Q); if(tmp.n_cols == 1) { for(uword i=0; i < d_n_elem; ++i) { d_m.at(i + d_row_offset, i + d_col_offset) /= tmp.at(i,0); } } else if(tmp.n_rows == 1) { for(uword i=0; i < d_n_elem; ++i) { d_m.at(i + d_row_offset, i + d_col_offset) /= tmp.at(0,i); } } } else { if(P.get_n_cols() == 1) { for(uword i=0; i < d_n_elem; ++i) { d_m.at(i + d_row_offset, i + d_col_offset) /= P.at(i,0); } } else if(P.get_n_rows() == 1) { for(uword i=0; i < d_n_elem; ++i) { d_m.at(i + d_row_offset, i + d_col_offset) /= P.at(0,i); } } } }
inline typename enable_if2 < (is_arma_type<T1>::value && is_arma_sparse_type<T2>::value && is_same_type<typename T1::elem_type, typename T2::elem_type>::value), Mat<typename T1::elem_type> >::result operator/ ( const Base<typename T1::elem_type, T1>& x, const SpBase<typename T2::elem_type, T2>& y ) { arma_extra_debug_sigprint(); const Proxy<T1> pa(x.get_ref()); const SpProxy<T2> pb(y.get_ref()); arma_debug_assert_same_size(pa.get_n_rows(), pa.get_n_cols(), pb.get_n_rows(), pb.get_n_cols(), "element-wise division"); Mat<typename T1::elem_type> result(pa.get_n_rows(), pa.get_n_cols()); result.fill(Datum<typename T1::elem_type>::inf); // Now divide each element typename SpProxy<T2>::const_iterator_type it = pb.begin(); while(it.pos() < pb.get_n_nonzero()) { if(Proxy<T1>::prefer_at_accessor == false) { const uword index = (it.col() * result.n_rows) + it.row(); result[index] = pa[index] / (*it); } else { result.at(it.row(), it.col()) = pa.at(it.row(), it.col()) / (*it); } ++it; } return result; }
inline bool spsolve ( Mat<typename T1::elem_type>& out, const SpBase<typename T1::elem_type, T1>& A, const Base<typename T1::elem_type, T2>& B, const char* solver = "superlu", const spsolve_opts_base& settings = spsolve_opts_none(), const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0 ) { arma_extra_debug_sigprint(); arma_ignore(junk); const bool status = spsolve_helper(out, A.get_ref(), B.get_ref(), solver, settings); return status; }
inline typename T1::elem_type spop_mean::mean_all(const SpBase<typename T1::elem_type, T1>& X) { arma_extra_debug_sigprint(); SpProxy<T1> p(X.get_ref()); if(SpProxy<T1>::must_use_iterator) { typename SpProxy<T1>::const_iterator_type it = p.begin(); typename SpProxy<T1>::const_iterator_type end = p.end(); return spop_mean::iterator_mean(it, end, p.get_n_elem() - p.get_n_nonzero(), typename T1::elem_type(0)); } else // must_use_iterator == false; that is, we can directly access the values array { return spop_mean::direct_mean(p.get_values(), p.get_n_nonzero(), p.get_n_elem()); } }