inline const subview_field<oT> field<oT>::cols(const u32 in_col1, const u32 in_col2) const { arma_extra_debug_sigprint(); arma_debug_check ( ( (in_col1 > in_col2) || (in_col2 >= n_cols) ), "field::cols(): indicies out of bounds or incorrectly used" ); const u32 sub_n_cols = in_col2 - in_col1 + 1; return subview_field<oT>(*this, 0, in_col1, n_rows, sub_n_cols); }
inline eT subview_cube<eT>::operator()(const u32 i) const { arma_debug_check( (i >= n_elem), "subview_cube::operator(): index out of bounds"); const u32 in_slice = i / n_elem_slice; const u32 offset = in_slice * n_elem_slice; const u32 j = i - offset; const u32 in_col = j / n_rows; const u32 in_row = j % n_rows; const u32 index = (in_slice + aux_slice1)*m.n_elem_slice + (in_col + aux_col1)*m.n_rows + aux_row1 + in_row; return m.mem[index]; }
inline subview_field<oT> field<oT>::rows(const u32 in_row1, const u32 in_row2) { arma_extra_debug_sigprint(); arma_debug_check ( ( (in_row1 > in_row2) || (in_row2 >= n_rows) ), "field::rows(): indicies out of bounds or incorrectly used" ); const u32 sub_n_rows = in_row2 - in_row1 + 1; return subview_field<oT>(*this, in_row1, 0, sub_n_rows, n_cols); }
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 }
arma_hot inline typename T1::elem_type op_dot::apply_proxy(const Base<typename T1::elem_type,T1>& X, const Base<typename T1::elem_type,T2>& Y) { arma_extra_debug_sigprint(); typedef typename T1::elem_type eT; typedef typename Proxy<T1>::ea_type ea_type1; typedef typename Proxy<T2>::ea_type ea_type2; const Proxy<T1> A(X.get_ref()); const Proxy<T2> B(Y.get_ref()); const bool prefer_at_accessor = (Proxy<T1>::prefer_at_accessor) && (Proxy<T2>::prefer_at_accessor); if(prefer_at_accessor == false) { arma_debug_check( (A.get_n_elem() != B.get_n_elem()), "dot(): objects must have the same number of elements" ); const uword N = A.get_n_elem(); ea_type1 PA = A.get_ea(); ea_type2 PB = B.get_ea(); eT val1 = eT(0); eT val2 = eT(0); uword i,j; for(i=0, j=1; j<N; i+=2, j+=2) { val1 += PA[i] * PB[i]; val2 += PA[j] * PB[j]; } if(i < N) { val1 += PA[i] * PB[i]; } return val1 + val2; } else { return op_dot::apply_unwrap(A.Q, B.Q); } }
inline bool op_orth::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)), "orth(): 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); V.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 > 0) { out = U.head_cols(count); // out *= eT(-1); } else { out.set_size(X.n_rows, 0); } return true; }
inline bool op_inv::apply_diagmat(Mat<typename T1::elem_type>& out, const T1& X) { arma_extra_debug_sigprint(); typedef typename T1::elem_type eT; const diagmat_proxy<T1> A(X); arma_debug_check( (A.n_rows != A.n_cols), "inv(): given matrix must be square sized" ); const uword N = (std::min)(A.n_rows, A.n_cols); bool status = true; if(A.is_alias(out) == false) { out.zeros(N,N); for(uword i=0; i<N; ++i) { const eT val = A[i]; out.at(i,i) = eT(1) / val; if(val == eT(0)) { status = false; } } } else { Mat<eT> tmp(N, N, fill::zeros); for(uword i=0; i<N; ++i) { const eT val = A[i]; tmp.at(i,i) = eT(1) / val; if(val == eT(0)) { status = false; } } out.steal_mem(tmp); } return status; }
inline void op_sum::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_sum>& in) { arma_extra_debug_sigprint(); const uword dim = in.aux_uword_a; arma_debug_check( (dim > 1), "sum(): incorrect usage. dim must be 0 or 1"); typedef typename T1::elem_type eT; const unwrap_check<T1> tmp(in.m, out); const Mat<eT>& X = tmp.M; const uword X_n_rows = X.n_rows; const uword X_n_cols = X.n_cols; if(dim == 0) // traverse across rows (i.e. find the sum in each column) { out.set_size(1, X_n_cols); eT* out_mem = out.memptr(); for(uword col=0; col<X_n_cols; ++col) { out_mem[col] = arrayops::accumulate(X.colptr(col), X_n_rows); } } else // traverse across columns (i.e. find the sum in each row) { out.set_size(X_n_rows, 1); eT* out_mem = out.memptr(); for(uword row=0; row<X_n_rows; ++row) { eT val = eT(0); for(uword col=0; col<X_n_cols; ++col) { val += X.at(row,col); } out_mem[row] = val; } } }
inline void op_trimat::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_trimat>& in) { arma_extra_debug_sigprint(); typedef typename T1::elem_type eT; const unwrap<T1> tmp(in.m); const Mat<eT>& A = tmp.M; arma_debug_check( (A.is_square() == false), "trimatu()/trimatl(): given matrix must be square sized" ); const uword N = A.n_rows; const bool upper = (in.aux_uword_a == 0); if(&out != &A) { out.copy_size(A); if(upper) { // upper triangular: copy the diagonal and the elements above the diagonal for(uword i=0; i<N; ++i) { const eT* A_data = A.colptr(i); eT* out_data = out.colptr(i); arrayops::copy( out_data, A_data, i+1 ); } } else { // lower triangular: copy the diagonal and the elements below the diagonal for(uword i=0; i<N; ++i) { const eT* A_data = A.colptr(i); eT* out_data = out.colptr(i); arrayops::copy( &out_data[i], &A_data[i], N-i ); } } } op_trimat::fill_zeros(out, upper); }
inline arma_warn_unused std::complex<T> median(const Col< std::complex<T> >& A) { arma_extra_debug_sigprint(); const u32 A_n_elem = A.n_elem; arma_debug_check( (A_n_elem == 0), "median(): given object has no elements" ); u32 index1; u32 index2; op_median::direct_cx_median_index(index1, index2, A.mem, A_n_elem); return (index1 == index2) ? A.mem[index1] : op_median::robust_mean( A.mem[index1], A.mem[index2] ); }
inline arma_warn_unused typename T1::elem_type det ( const Op<T1, op_trimat>& X, const char* method ) { arma_extra_debug_sigprint(); const char sig = (method != NULL) ? method[0] : char(0); arma_debug_check( ((sig != 's') && (sig != 'f')), "det(): unknown method specified" ); return det(X, false); }
arma_inline eT& subview_cube<eT>::operator()(const u32 i) { arma_check( (m_ptr == 0), "subview_cube::operator(): matrix is read-only"); arma_debug_check( (i >= n_elem), "subview_cube::operator(): index out of bounds"); const u32 in_slice = i / n_elem_slice; const u32 offset = in_slice * n_elem_slice; const u32 j = i - offset; const u32 in_col = j / n_rows; const u32 in_row = j % n_rows; const u32 index = (in_slice + aux_slice1)*m.n_elem_slice + (in_col + aux_col1)*m.n_rows + aux_row1 + in_row; return access::rw( (*m_ptr).mem[index] ); }
arma_hot inline typename T1::elem_type op_norm_dot::apply(const T1& X, const T2& Y) { arma_extra_debug_sigprint(); typedef typename T1::elem_type eT; typedef typename Proxy<T1>::ea_type ea_type1; typedef typename Proxy<T2>::ea_type ea_type2; const bool prefer_at_accessor = (Proxy<T1>::prefer_at_accessor) && (Proxy<T2>::prefer_at_accessor); if(prefer_at_accessor == false) { const Proxy<T1> PA(X); const Proxy<T2> PB(Y); const uword N = PA.get_n_elem(); arma_debug_check( (N != PB.get_n_elem()), "norm_dot(): objects must have the same number of elements" ); ea_type1 A = PA.get_ea(); ea_type2 B = PB.get_ea(); eT acc1 = eT(0); eT acc2 = eT(0); eT acc3 = eT(0); for(uword i=0; i<N; ++i) { const eT tmpA = A[i]; const eT tmpB = B[i]; acc1 += tmpA * tmpA; acc2 += tmpB * tmpB; acc3 += tmpA * tmpB; } return acc3 / ( std::sqrt(acc1 * acc2) ); } else { return op_norm_dot::apply_unwrap(X, Y); } }
inline eT& subview_cube<eT>::operator()(const uword i) { arma_debug_check( (i >= n_elem), "subview_cube::operator(): index out of bounds"); const uword in_slice = i / n_elem_slice; const uword offset = in_slice * n_elem_slice; const uword j = i - offset; const uword in_col = j / n_rows; const uword in_row = j % n_rows; const uword index = (in_slice + aux_slice1)*m.n_elem_slice + (in_col + aux_col1)*m.n_rows + aux_row1 + in_row; return access::rw( (const_cast< Cube<eT>& >(m)).mem[index] ); }
inline bool eig_gen ( Col<std::complex<T> >& eigval, Mat<std::complex<T> >& eigvec, const Base<std::complex<T>, T1>& X, const char side = 'r', const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0 ) { arma_extra_debug_sigprint(); arma_ignore(junk); //std::cout << "complex" << std::endl; arma_debug_check( ( ((void*)(&eigval)) == ((void*)(&eigvec)) ), "eig_gen(): eigval is an alias of eigvec" ); Mat< std::complex<T> > dummy_eigvec; bool status; switch(side) { case 'r': status = auxlib::eig_gen(eigval, dummy_eigvec, eigvec, X, side); break; case 'l': status = auxlib::eig_gen(eigval, eigvec, dummy_eigvec, X, side); break; default: arma_stop("eig_gen(): parameter 'side' is invalid"); status = false; } if(status == false) { eigval.reset(); eigvec.reset(); arma_bad("eig_gen(): failed to converge", false); } return status; }
inline arma_warn_unused 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"); typedef typename T1::elem_type eT; const unwrap<T1> tmp1(in.m); const Mat<eT>& X = tmp1.M; arma_debug_check( (X.n_elem == 0), "min(): given matrix has no elements" ); return op_min::direct_min(X.mem, X.n_elem); }
inline const subview_field<oT> field<oT>::subfield(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2) const { arma_extra_debug_sigprint(); arma_debug_check ( (in_row1 > in_row2) || (in_col1 > in_col2) || (in_row2 >= n_rows) || (in_col2 >= n_cols), "field::subfield(): indices out of bounds or incorrectly used" ); const uword sub_n_rows = in_row2 - in_row1 + 1; const uword sub_n_cols = in_col2 - in_col1 + 1; return subview_field<oT>(*this, in_row1, in_col1, sub_n_rows, sub_n_cols); }
inline const Op<T1, op_chol> chol ( const Base<typename T1::elem_type,T1>& X, const char* layout = "upper", const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0 ) { arma_extra_debug_sigprint(); arma_ignore(junk); const char sig = (layout != NULL) ? layout[0] : char(0); arma_debug_check( ((sig != 'u') && (sig != 'l')), "chol(): layout must be \"upper\" or \"lower\"" ); return Op<T1, op_chol>(X.get_ref(), ((sig == 'u') ? 0 : 1), 0 ); }
inline const mtOp<uword, T1, op_find> find(const Base<eT,T1>& X, const uword k = 0, const char* direction = "first") { arma_extra_debug_sigprint(); const char sig = direction[0]; arma_debug_check ( (sig != 'f' && sig != 'F' && sig != 'l' && sig != 'L'), "find(): 3rd input argument must be \"first\" or \"last\"" ); const uword type = (sig == 'f' || sig == 'F') ? 0 : 1; return mtOp<uword, T1, op_find>(X.get_ref(), k, type); }
inline void lu ( Mat<typename T1::elem_type>& L, Mat<typename T1::elem_type>& U, const Base<typename T1::elem_type,T1>& X, const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0 ) { arma_extra_debug_sigprint(); arma_ignore(junk); arma_debug_check( (&L == &U), "lu(): L and U are the same object"); auxlib::lu(L, U, X); }
inline void subview_field<oT>::operator= (const field<oT>& x) { arma_extra_debug_sigprint(); subview_field<oT>& t = *this; arma_debug_check( (t.n_rows != x.n_rows) || (t.n_cols != x.n_cols), "incompatible field dimensions"); for(u32 col=0; col<t.n_cols; ++col) { for(u32 row=0; row<t.n_rows; ++row) { t.at(row,col) = x.at(row,col); } } }
inline typename T1::pod_type spop_var::var_vec ( const T1& X, const uword norm_type ) { arma_extra_debug_sigprint(); arma_debug_check((norm_type > 1), "var(): incorrect usage. norm_type must be 0 or 1."); // conditionally unwrap it into a temporary and then directly operate. const unwrap_spmat<T1> tmp(X); return direct_var(tmp.M.values, tmp.M.n_nonzero, tmp.M.n_elem, norm_type); }
inline void SpSubview<eT>::swap_rows(const uword in_row1, const uword in_row2) { arma_extra_debug_sigprint(); arma_debug_check((in_row1 >= n_rows) || (in_row2 >= n_rows), "SpSubview::swap_rows(): invalid row index"); const uword lstart_col = aux_col1; const uword lend_col = aux_col1 + n_cols; for(uword c = lstart_col; c < lend_col; ++c) { eT val = m.at(in_row1 + aux_row1, c); access::rw(m).at(in_row2 + aux_row1, c) = m.at(in_row1 + aux_row1, c); access::rw(m).at(in_row1 + aux_row1, c) = val; } }
arma_inline const subview_row<eT> Row<eT>::subvec(const span& col_span) const { arma_extra_debug_sigprint(); const bool col_all = col_span.whole; const uword local_n_cols = Mat<eT>::n_cols; const uword in_col1 = col_all ? 0 : col_span.a; const uword in_col2 = col_span.b; const uword subvec_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1; arma_debug_check( ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) ), "Row::subvec(): indices out of bounds or incorrectly used"); return subview_row<eT>(*this, 0, in_col1, subvec_n_cols); }
inline void SpSubview<eT>::swap_cols(const uword in_col1, const uword in_col2) { arma_extra_debug_sigprint(); arma_debug_check((in_col1 >= n_cols) || (in_col2 >= n_cols), "SpSubview::swap_cols(): invalid column index"); const uword lstart_row = aux_row1; const uword lend_row = aux_row1 + n_rows; for(uword r = lstart_row; r < lend_row; ++r) { eT val = m.at(r, in_col1 + aux_col1); access::rw(m).at(r, in_col1 + aux_col1) = m.at(r, in_col2 + aux_col1); access::rw(m).at(r, in_col2 + aux_col1) = val; } }
arma_inline const Op<T1, op_inv_tr> inv ( const Op<T1, op_trimat>& X, const char* method, const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0 ) { arma_extra_debug_sigprint(); arma_ignore(junk); const char sig = (method != NULL) ? method[0] : char(0); arma_debug_check( ((sig != 's') && (sig != 'f')), "inv(): unknown method specified" ); return Op<T1, op_inv_tr>(X.m, X.aux_uword_a, 0); }
inline const Col<eT>& Col<eT>::fixed<fixed_n_elem>::operator=(const std::initializer_list<eT>& list) { arma_extra_debug_sigprint(); const uword N = list.size(); arma_debug_check( (N > fixed_n_elem), "Col::fixed: initialiser list is too long" ); eT* this_mem = (*this).memptr(); arrayops::copy( this_mem, list.begin(), N ); for(uword iq=N; iq < fixed_n_elem; ++iq) { this_mem[iq] = eT(0); } return *this; }
inline const mtOp<uword, T1, op_find> find(const Base<typename T1::elem_type,T1>& X, const uword k, const char* direction = "first") { arma_extra_debug_sigprint(); const char sig = (direction != NULL) ? direction[0] : char(0); arma_debug_check ( ( (sig != 'f') && (sig != 'F') && (sig != 'l') && (sig != 'L') ), "find(): direction must be \"first\" or \"last\"" ); const uword type = ( (sig == 'f') || (sig == 'F') ) ? 0 : 1; return mtOp<uword, T1, op_find>(X.get_ref(), k, type); }
arma_inline const subview_col<eT> Col<eT>::subvec(const span& row_span) const { arma_extra_debug_sigprint(); const bool row_all = row_span.whole; const uword local_n_rows = Mat<eT>::n_rows; const uword in_row1 = row_all ? 0 : row_span.a; const uword in_row2 = row_span.b; const uword subvec_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1; arma_debug_check( ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) ), "Col::subvec(): indices out of bounds or incorrectly used"); return subview_col<eT>(*this, 0, in_row1, subvec_n_rows); }
arma_inline const Op<T1, op_inv> inv ( const Base<typename T1::elem_type,T1>& X, const char* method, const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0 ) { arma_extra_debug_sigprint(); arma_ignore(junk); const char sig = (method != NULL) ? method[0] : char(0); arma_debug_check( ((sig != 's') && (sig != 'f')), "inv(): unknown method specified" ); return Op<T1, op_inv>(X.get_ref(), ((sig == 'f') ? 0 : 1), 0); }