inline Row<eT>::Row() : Mat<eT>(arma_vec_indicator(), 2) { arma_extra_debug_sigprint(); }
inline GlueCube<T1,T2,glue_type>::~GlueCube() { arma_extra_debug_sigprint(); }
inline bool eig_gen ( Col< std::complex<eT> >& eigval, Mat< std::complex<eT> >& eigvec, const Base<eT, 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 << "real" << std::endl; arma_debug_check( ( ((void*)(&eigval)) == ((void*)(&eigvec)) ), "eig_gen(): eigval is an alias of eigvec" ); Mat<eT> dummy_eigvec; Mat<eT> tmp_eigvec; bool status; switch(side) { case 'r': status = auxlib::eig_gen(eigval, dummy_eigvec, tmp_eigvec, X, side); break; case 'l': status = auxlib::eig_gen(eigval, tmp_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); } else { const uword n = eigval.n_elem; if(n > 0) { eigvec.set_size(n,n); for(uword j=0; j<n; ++j) { if( (j < n-1) && (eigval[j] == std::conj(eigval[j+1])) ) { // eigvec.col(j) = Mat< std::complex<eT> >( tmp_eigvec.col(j), tmp_eigvec.col(j+1) ); // eigvec.col(j+1) = Mat< std::complex<eT> >( tmp_eigvec.col(j), -tmp_eigvec.col(j+1) ); for(uword i=0; i<n; ++i) { eigvec.at(i,j) = std::complex<eT>( tmp_eigvec.at(i,j), tmp_eigvec.at(i,j+1) ); eigvec.at(i,j+1) = std::complex<eT>( tmp_eigvec.at(i,j), -tmp_eigvec.at(i,j+1) ); } ++j; } else { // eigvec.col(i) = tmp_eigvec.col(i); for(uword i=0; i<n; ++i) { eigvec.at(i,j) = std::complex<eT>(tmp_eigvec.at(i,j), eT(0)); } } } } } return status; }
inline subview_cube_each1<eT>::~subview_cube_each1() { arma_extra_debug_sigprint(); }
inline void running_stat_vec_aux::update_stats(running_stat_vec< std::complex<T> >& x, const Mat< std::complex<T> >& sample) { arma_extra_debug_sigprint(); typedef typename std::complex<T> eT; const T N = x.counter.value(); if(N > T(0)) { arma_debug_assert_same_size(x.r_mean, sample, "running_stat_vec(): dimensionality mismatch"); const u32 n_elem = sample.n_elem; const eT* sample_mem = sample.memptr(); eT* r_mean_mem = x.r_mean.memptr(); T* r_var_mem = x.r_var.memptr(); eT* min_val_mem = x.min_val.memptr(); eT* max_val_mem = x.max_val.memptr(); T* min_val_norm_mem = x.min_val_norm.memptr(); T* max_val_norm_mem = x.max_val_norm.memptr(); const T N_plus_1 = x.counter.value_plus_1(); const T N_minus_1 = x.counter.value_minus_1(); if(x.calc_cov == true) { Mat<eT>& tmp1 = x.tmp1; Mat<eT>& tmp2 = x.tmp2; tmp1 = sample - x.r_mean; if(sample.n_cols == 1) { tmp2 = conj(tmp1)*trans(tmp1); } else { tmp2 = trans(conj(tmp1))*tmp1; } x.r_cov *= (N_minus_1/N); x.r_cov += tmp2 / N_plus_1; } for(u32 i=0; i<n_elem; ++i) { const eT& val = sample_mem[i]; const T val_norm = std::norm(val); if(val_norm < min_val_norm_mem[i]) { min_val_norm_mem[i] = val_norm; min_val_mem[i] = val; } if(val_norm > max_val_norm_mem[i]) { max_val_norm_mem[i] = val_norm; max_val_mem[i] = val; } const eT& r_mean_val = r_mean_mem[i]; r_var_mem[i] = N_minus_1/N * r_var_mem[i] + std::norm(val - r_mean_val)/N_plus_1; r_mean_mem[i] = r_mean_val + (val - r_mean_val)/N_plus_1; } } else { arma_debug_check( (sample.is_vec() == false), "running_stat_vec(): given sample is not a vector"); x.r_mean.set_size(sample.n_rows, sample.n_cols); x.r_var.zeros(sample.n_rows, sample.n_cols); if(x.calc_cov == true) { x.r_cov.zeros(sample.n_elem, sample.n_elem); } x.min_val.set_size(sample.n_rows, sample.n_cols); x.max_val.set_size(sample.n_rows, sample.n_cols); x.min_val_norm.set_size(sample.n_rows, sample.n_cols); x.max_val_norm.set_size(sample.n_rows, sample.n_cols); const u32 n_elem = sample.n_elem; const eT* sample_mem = sample.memptr(); eT* r_mean_mem = x.r_mean.memptr(); eT* min_val_mem = x.min_val.memptr(); eT* max_val_mem = x.max_val.memptr(); T* min_val_norm_mem = x.min_val_norm.memptr(); T* max_val_norm_mem = x.max_val_norm.memptr(); for(u32 i=0; i<n_elem; ++i) { const eT& val = sample_mem[i]; const T val_norm = std::norm(val); r_mean_mem[i] = val; min_val_mem[i] = val; max_val_mem[i] = val; min_val_norm_mem[i] = val_norm; max_val_norm_mem[i] = val_norm; } } x.counter++; }
inline std::streamsize arma_ostream::modify_stream(std::ostream& o, typename SpMat<eT>::const_iterator begin, const uword n_elem, const typename arma_not_cx<eT>::result* junk) { arma_extra_debug_sigprint(); arma_ignore(junk); o.unsetf(ios::showbase); o.unsetf(ios::uppercase); o.unsetf(ios::showpos); o.fill(' '); std::streamsize cell_width; bool use_layout_B = false; bool use_layout_C = false; for(typename SpMat<eT>::const_iterator it = begin; it.pos() < n_elem; ++it) { const eT val = *it; if( val >= eT(+100) || ( (is_signed<eT>::value == true) && (val <= eT(-100)) ) || ( (is_non_integral<eT>::value == true) && (val > eT(0)) && (val <= eT(+1e-4)) ) || ( (is_non_integral<eT>::value == true) && (is_signed<eT>::value == true) && (val < eT(0)) && (val >= eT(-1e-4)) ) ) { use_layout_C = true; break; } if( (val >= eT(+10)) || ( (is_signed<eT>::value == true) && (val <= eT(-10)) ) ) { use_layout_B = true; } } if(use_layout_C == true) { o.setf(ios::scientific); o.setf(ios::right); o.unsetf(ios::fixed); o.precision(4); cell_width = 13; } else if(use_layout_B == true) { o.unsetf(ios::scientific); o.setf(ios::right); o.setf(ios::fixed); o.precision(4); cell_width = 10; } else { o.unsetf(ios::scientific); o.setf(ios::right); o.setf(ios::fixed); o.precision(4); cell_width = 9; } return cell_width; }
inline void arma_ostream::print(std::ostream& o, const SpMat<eT>& m, const bool modify) { arma_extra_debug_sigprint(); const arma_ostream_state stream_state(o); o.unsetf(ios::showbase); o.unsetf(ios::uppercase); o.unsetf(ios::showpos); o.unsetf(ios::scientific); o.setf(ios::right); o.setf(ios::fixed); o.precision(2); const uword m_n_nonzero = m.n_nonzero; o << "[matrix size: " << m.n_rows << 'x' << m.n_cols << "; n_nonzero: " << m_n_nonzero << "; density: " << ((m.n_elem > 0) ? (double(m_n_nonzero) / double(m.n_elem) * double(100)) : double(0)) << "%]\n\n"; if(modify == false) { stream_state.restore(o); } if(m_n_nonzero > 0) { const std::streamsize cell_width = modify ? modify_stream<eT>(o, m.begin(), m_n_nonzero) : o.width(); typename SpMat<eT>::const_iterator begin = m.begin(); while(begin != m.end()) { const uword row = begin.row(); // TODO: change the maximum number of spaces before and after each location to be dependent on n_rows and n_cols if(row < 10) { o << " "; } else if(row < 100) { o << " "; } else if(row < 1000) { o << " "; } else if(row < 10000) { o << " "; } else if(row < 100000) { o << ' '; } const uword col = begin.col(); o << '(' << row << ", " << col << ") "; if(col < 10) { o << " "; } else if(col < 100) { o << " "; } else if(col < 1000) { o << " "; } else if(col < 10000) { o << " "; } else if(col < 100000) { o << ' '; } if(cell_width > 0) { o.width(cell_width); } arma_ostream::print_elem(o, eT(*begin), modify); o << '\n'; ++begin; } o << '\n'; } o.flush(); stream_state.restore(o); }
inline void spop_var::apply_noalias ( SpMat<typename T1::pod_type>& out, const SpProxy<T1>& p, const uword norm_type, const uword dim ) { arma_extra_debug_sigprint(); typedef typename T1::elem_type in_eT; //typedef typename T1::pod_type out_eT; const uword p_n_rows = p.get_n_rows(); const uword p_n_cols = p.get_n_cols(); // TODO: this is slow; rewrite based on the approach used by sparse mean() if(dim == 0) // find variance in each column { arma_extra_debug_print("spop_var::apply_noalias(): dim = 0"); out.set_size((p_n_rows > 0) ? 1 : 0, p_n_cols); if( (p_n_rows == 0) || (p.get_n_nonzero() == 0) ) { return; } for(uword col = 0; col < p_n_cols; ++col) { if(SpProxy<T1>::must_use_iterator) { // We must use an iterator; we can't access memory directly. typename SpProxy<T1>::const_iterator_type it = p.begin_col(col); typename SpProxy<T1>::const_iterator_type end = p.begin_col(col + 1); const uword n_zero = p_n_rows - (end.pos() - it.pos()); // in_eT is used just to get the specialization right (complex / noncomplex) out.at(0, col) = spop_var::iterator_var(it, end, n_zero, norm_type, in_eT(0)); } else { // We can use direct memory access to calculate the variance. out.at(0, col) = spop_var::direct_var ( &p.get_values()[p.get_col_ptrs()[col]], p.get_col_ptrs()[col + 1] - p.get_col_ptrs()[col], p_n_rows, norm_type ); } } } else if(dim == 1) // find variance in each row { arma_extra_debug_print("spop_var::apply_noalias(): dim = 1"); out.set_size(p_n_rows, (p_n_cols > 0) ? 1 : 0); if( (p_n_cols == 0) || (p.get_n_nonzero() == 0) ) { return; } for(uword row = 0; row < p_n_rows; ++row) { // We have to use an iterator here regardless of whether or not we can // directly access memory. typename SpProxy<T1>::const_row_iterator_type it = p.begin_row(row); typename SpProxy<T1>::const_row_iterator_type end = p.end_row(row); const uword n_zero = p_n_cols - (end.pos() - it.pos()); out.at(row, 0) = spop_var::iterator_var(it, end, n_zero, norm_type, in_eT(0)); } } }
arma_hot inline void spglue_plus::apply_noalias(SpMat<eT>& out, const SpProxy<T1>& pa, const SpProxy<T2>& pb) { arma_extra_debug_sigprint(); arma_debug_assert_same_size(pa.get_n_rows(), pa.get_n_cols(), pb.get_n_rows(), pb.get_n_cols(), "addition"); if( (pa.get_n_nonzero() != 0) && (pb.get_n_nonzero() != 0) ) { out.zeros(pa.get_n_rows(), pa.get_n_cols()); // Resize memory to correct size. out.mem_resize(n_unique(pa, pb, op_n_unique_add())); // Now iterate across both matrices. typename SpProxy<T1>::const_iterator_type x_it = pa.begin(); typename SpProxy<T2>::const_iterator_type y_it = pb.begin(); typename SpProxy<T1>::const_iterator_type x_end = pa.end(); typename SpProxy<T2>::const_iterator_type y_end = pb.end(); uword cur_val = 0; while( (x_it != x_end) || (y_it != y_end) ) { if(x_it == y_it) { const eT val = (*x_it) + (*y_it); if(val != eT(0)) { access::rw(out.values[cur_val]) = val; access::rw(out.row_indices[cur_val]) = x_it.row(); ++access::rw(out.col_ptrs[x_it.col() + 1]); ++cur_val; } ++x_it; ++y_it; } else { const uword x_it_row = x_it.row(); const uword x_it_col = x_it.col(); const uword y_it_row = y_it.row(); const uword y_it_col = y_it.col(); if((x_it_col < y_it_col) || ((x_it_col == y_it_col) && (x_it_row < y_it_row))) // if y is closer to the end { const eT val = (*x_it); if(val != eT(0)) { access::rw(out.values[cur_val]) = val; access::rw(out.row_indices[cur_val]) = x_it_row; ++access::rw(out.col_ptrs[x_it_col + 1]); ++cur_val; } ++x_it; } else { const eT val = (*y_it); if(val != eT(0)) { access::rw(out.values[cur_val]) = val; access::rw(out.row_indices[cur_val]) = y_it_row; ++access::rw(out.col_ptrs[y_it_col + 1]); ++cur_val; } ++y_it; } } } const uword out_n_cols = out.n_cols; uword* col_ptrs = access::rwp(out.col_ptrs); // Fix column pointers to be cumulative. for(uword c = 1; c <= out_n_cols; ++c) { col_ptrs[c] += col_ptrs[c - 1]; } } else { if(pa.get_n_nonzero() == 0) { out = pb.Q; return; } if(pb.get_n_nonzero() == 0) { out = pa.Q; return; } } }
inline typename arma_cx_only<typename T1::elem_type>::result op_max::max_with_index(const Proxy<T1>& P, uword& index_of_max_val) { arma_extra_debug_sigprint(); typedef typename T1::elem_type eT; typedef typename get_pod_type<eT>::result T; const uword n_elem = P.get_n_elem(); if(n_elem == 0) { arma_debug_check(true, "max(): object has no elements"); return Datum<eT>::nan; } T best_val = priv::most_neg<T>(); if(Proxy<T1>::prefer_at_accessor == false) { typedef typename Proxy<T1>::ea_type ea_type; ea_type A = P.get_ea(); uword best_index = 0; for(uword i=0; i<n_elem; ++i) { const T tmp = std::abs(A[i]); if(tmp > best_val) { best_val = tmp; best_index = i; } } index_of_max_val = best_index; return( A[best_index] ); } else { const uword n_rows = P.get_n_rows(); const uword n_cols = P.get_n_cols(); uword best_row = 0; uword best_col = 0; uword best_index = 0; if(n_rows == 1) { for(uword col=0; col < n_cols; ++col) { const T tmp = std::abs(P.at(0,col)); if(tmp > best_val) { best_val = tmp; best_col = col; } } best_index = best_col; } else if(n_cols == 1) { for(uword row=0; row < n_rows; ++row) { const T tmp = std::abs(P.at(row,0)); if(tmp > best_val) { best_val = tmp; best_row = row; } } best_index = best_row; } else { uword count = 0; for(uword col=0; col < n_cols; ++col) for(uword row=0; row < n_rows; ++row) { const T tmp = std::abs(P.at(row,col)); if(tmp > best_val) { best_val = tmp; best_row = row; best_col = col; best_index = count; } ++count; } } index_of_max_val = best_index; return P.at(best_row, best_col); } }
inline eT spop_var::direct_var ( const eT* const X, const uword length, const uword N, const uword norm_type ) { arma_extra_debug_sigprint(); if(length >= 2 && N >= 2) { const eT acc1 = spop_mean::direct_mean(X, length, N); eT acc2 = eT(0); eT acc3 = eT(0); uword i, j; for(i = 0, j = 1; j < length; i += 2, j += 2) { const eT Xi = X[i]; const eT Xj = X[j]; const eT tmpi = acc1 - Xi; const eT tmpj = acc1 - Xj; acc2 += tmpi * tmpi + tmpj * tmpj; acc3 += tmpi + tmpj; } if(i < length) { const eT Xi = X[i]; const eT tmpi = acc1 - Xi; acc2 += tmpi * tmpi; acc3 += tmpi; } // Now add in all zero elements. acc2 += (N - length) * (acc1 * acc1); acc3 += (N - length) * acc1; const eT norm_val = (norm_type == 0) ? eT(N - 1) : eT(N); const eT var_val = (acc2 - (acc3 * acc3) / eT(N)) / norm_val; return var_val; } else if(length == 1 && N > 1) // if N == 1, then variance is zero. { const eT mean = X[0] / eT(N); const eT val = mean - X[0]; const eT acc2 = (val * val) + (N - length) * (mean * mean); const eT acc3 = val + (N - length) * mean; const eT norm_val = (norm_type == 0) ? eT(N - 1) : eT(N); const eT var_val = (acc2 - (acc3 * acc3) / eT(N)) / norm_val; return var_val; } else { return eT(0); } }
inline std::complex<T> op_max::max(const subview< std::complex<T> >& X) { arma_extra_debug_sigprint(); typedef typename std::complex<T> eT; if(X.n_elem == 0) { arma_debug_check(true, "max(): object has no elements"); return Datum<eT>::nan; } const Mat<eT>& A = X.m; const uword X_n_rows = X.n_rows; const uword X_n_cols = X.n_cols; const uword start_row = X.aux_row1; const uword start_col = X.aux_col1; const uword end_row_p1 = start_row + X_n_rows; const uword end_col_p1 = start_col + X_n_cols; T max_val = priv::most_neg<T>(); uword best_row = 0; uword best_col = 0; if(X_n_rows == 1) { best_col = 0; for(uword col=start_col; col < end_col_p1; ++col) { const T tmp_val = std::abs( A.at(start_row, col) ); if(tmp_val > max_val) { max_val = tmp_val; best_col = col; } } best_row = start_row; } else { for(uword col=start_col; col < end_col_p1; ++col) for(uword row=start_row; row < end_row_p1; ++row) { const T tmp_val = std::abs( A.at(row, col) ); if(tmp_val > max_val) { max_val = tmp_val; best_row = row; best_col = col; } } } return A.at(best_row, best_col); }
inline mtGlue<out_eT,T1,T2,glue_type>::~mtGlue() { arma_extra_debug_sigprint(); }
inline Row<eT>::Row(const uword in_n_elem) : Mat<eT>(arma_vec_indicator(), 1, in_n_elem, 2) { arma_extra_debug_sigprint(); }
inline void glue_join::apply_noalias(Mat<eT>& out, const Mat<eT>& A, const Mat<eT>& B, const uword join_type) { arma_extra_debug_sigprint(); const uword A_n_rows = A.n_rows; const uword A_n_cols = A.n_cols; const uword B_n_rows = B.n_rows; const uword B_n_cols = B.n_cols; if(join_type == 0) { arma_debug_check ( ( (A_n_cols != B_n_cols) && ( (A_n_rows > 0) || (A_n_cols > 0) ) && ( (B_n_rows > 0) || (B_n_cols > 0) ) ), "join_cols() / join_vert(): number of columns must be the same" ); } else { arma_debug_check ( ( (A_n_rows != B.n_rows) && ( (A_n_rows > 0) || (A_n_cols > 0) ) && ( (B_n_rows > 0) || (B_n_cols > 0) ) ), "join_rows() / join_horiz(): number of rows must be the same" ); } if(join_type == 0) // join columns (i.e. result matrix has more rows) { out.set_size( A_n_rows + B_n_rows, (std::max)(A_n_cols, B_n_cols) ); if( out.n_elem > 0 ) { if(A.is_empty() == false) { out.submat(0, 0, A_n_rows-1, out.n_cols-1) = A; } if(B.is_empty() == false) { out.submat(A_n_rows, 0, out.n_rows-1, out.n_cols-1) = B; } } } else // join rows (i.e. result matrix has more columns) { out.set_size( (std::max)(A_n_rows, B_n_rows), A_n_cols + B_n_cols ); if( out.n_elem > 0 ) { if(A.is_empty() == false) { out.submat(0, 0, out.n_rows-1, A.n_cols-1) = A; } if(B.is_empty() == false) { out.submat(0, A_n_cols, out.n_rows-1, out.n_cols-1) = B; } } } }
inline static void apply_blas_type( Mat<eT>& C, const TA& A, const TB& B, const eT alpha = eT(1), const eT beta = eT(0) ) { arma_extra_debug_sigprint(); if( (A.n_rows <= 4) && (A.n_rows == A.n_cols) && (A.n_rows == B.n_rows) && (B.n_rows == B.n_cols) && (is_cx<eT>::no) ) { if(do_trans_B == false) { gemm_emul_tinysq<do_trans_A, use_alpha, use_beta>::apply(C, A, B, alpha, beta); } else { Mat<eT> BB(B.n_rows, B.n_rows); op_strans::apply_mat_noalias_tinysq(BB, B); gemm_emul_tinysq<do_trans_A, use_alpha, use_beta>::apply(C, A, BB, alpha, beta); } } else { #if defined(ARMA_USE_ATLAS) { arma_extra_debug_print("atlas::cblas_gemm()"); atlas::cblas_gemm<eT> ( atlas::CblasColMajor, (do_trans_A) ? ( is_cx<eT>::yes ? CblasConjTrans : atlas::CblasTrans ) : atlas::CblasNoTrans, (do_trans_B) ? ( is_cx<eT>::yes ? CblasConjTrans : atlas::CblasTrans ) : atlas::CblasNoTrans, C.n_rows, C.n_cols, (do_trans_A) ? A.n_rows : A.n_cols, (use_alpha) ? alpha : eT(1), A.mem, (do_trans_A) ? A.n_rows : C.n_rows, B.mem, (do_trans_B) ? C.n_cols : ( (do_trans_A) ? A.n_rows : A.n_cols ), (use_beta) ? beta : eT(0), C.memptr(), C.n_rows ); } #elif defined(ARMA_USE_BLAS) { arma_extra_debug_print("blas::gemm()"); const char trans_A = (do_trans_A) ? ( is_cx<eT>::yes ? 'C' : 'T' ) : 'N'; const char trans_B = (do_trans_B) ? ( is_cx<eT>::yes ? 'C' : 'T' ) : 'N'; const blas_int m = C.n_rows; const blas_int n = C.n_cols; const blas_int k = (do_trans_A) ? A.n_rows : A.n_cols; const eT local_alpha = (use_alpha) ? alpha : eT(1); const blas_int lda = (do_trans_A) ? k : m; const blas_int ldb = (do_trans_B) ? n : k; const eT local_beta = (use_beta) ? beta : eT(0); arma_extra_debug_print( arma_boost::format("blas::gemm(): trans_A = %c") % trans_A ); arma_extra_debug_print( arma_boost::format("blas::gemm(): trans_B = %c") % trans_B ); blas::gemm<eT> ( &trans_A, &trans_B, &m, &n, &k, &local_alpha, A.mem, &lda, B.mem, &ldb, &local_beta, C.memptr(), &m ); } #else { gemm_emul<do_trans_A, do_trans_B, use_alpha, use_beta>::apply(C,A,B,alpha,beta); } #endif } }
inline void op_diagmat::apply(Mat<typename T1::elem_type>& out, const Op<T1, op_diagmat>& X) { arma_extra_debug_sigprint(); typedef typename T1::elem_type eT; const unwrap<T1> tmp(X.m); const Mat<eT>& A = tmp.M; if(A.is_vec() == true) { // generate a diagonal matrix out of a vector const u32 N = A.n_elem; const eT* A_mem = A.memptr(); if(&out != &A) { // no aliasing out.zeros(N,N); for(u32 i=0; i<N; ++i) { out.at(i,i) = A_mem[i]; } } else { // aliasing const podarray<eT> tmp(A_mem, N); const eT* tmp_mem = tmp.memptr(); out.zeros(N,N); for(u32 i=0; i<N; ++i) { out.at(i,i) = tmp_mem[i]; } } } else { // generate a diagonal matrix out of a matrix arma_debug_check( (A.is_square() == false), "diagmat(): given matrix is not square" ); const u32 N = A.n_rows; out.set_size(N,N); for(u32 col=0; col<N; ++col) { for(u32 row=0; row<col; ++row) { out.at(row,col) = eT(0); } out.at(col,col) = A.at(col,col); for(u32 row=col+1; row<N; ++row) { out.at(row,col) = eT(0); } } } }
arma_hot inline static void apply ( Mat<eT>& C, const TA& A, const TB& B, const eT alpha = eT(1), const eT beta = eT(0) ) { arma_extra_debug_sigprint(); const uword A_n_rows = A.n_rows; const uword A_n_cols = A.n_cols; const uword B_n_rows = B.n_rows; const uword B_n_cols = B.n_cols; if( (do_trans_A == false) && (do_trans_B == false) ) { arma_aligned podarray<eT> tmp(A_n_cols); eT* A_rowdata = tmp.memptr(); for(uword row_A=0; row_A < A_n_rows; ++row_A) { tmp.copy_row(A, row_A); for(uword col_B=0; col_B < B_n_cols; ++col_B) { const eT acc = op_dot::direct_dot_arma(B_n_rows, A_rowdata, B.colptr(col_B)); if( (use_alpha == false) && (use_beta == false) ) { C.at(row_A,col_B) = acc; } else if( (use_alpha == true ) && (use_beta == false) ) { C.at(row_A,col_B) = alpha*acc; } else if( (use_alpha == false) && (use_beta == true ) ) { C.at(row_A,col_B) = acc + beta*C.at(row_A,col_B); } else if( (use_alpha == true ) && (use_beta == true ) ) { C.at(row_A,col_B) = alpha*acc + beta*C.at(row_A,col_B); } } } } else if( (do_trans_A == true) && (do_trans_B == false) ) { for(uword col_A=0; col_A < A_n_cols; ++col_A) { // col_A is interpreted as row_A when storing the results in matrix C const eT* A_coldata = A.colptr(col_A); for(uword col_B=0; col_B < B_n_cols; ++col_B) { const eT acc = op_dot::direct_dot_arma(B_n_rows, A_coldata, B.colptr(col_B)); if( (use_alpha == false) && (use_beta == false) ) { C.at(col_A,col_B) = acc; } else if( (use_alpha == true ) && (use_beta == false) ) { C.at(col_A,col_B) = alpha*acc; } else if( (use_alpha == false) && (use_beta == true ) ) { C.at(col_A,col_B) = acc + beta*C.at(col_A,col_B); } else if( (use_alpha == true ) && (use_beta == true ) ) { C.at(col_A,col_B) = alpha*acc + beta*C.at(col_A,col_B); } } } } else if( (do_trans_A == false) && (do_trans_B == true) ) { Mat<eT> BB; op_strans::apply_mat_noalias(BB, B); gemm_emul_large<false, false, use_alpha, use_beta>::apply(C, A, BB, alpha, beta); } else if( (do_trans_A == true) && (do_trans_B == true) ) { // mat B_tmp = trans(B); // dgemm_arma<true, false, use_alpha, use_beta>::apply(C, A, B_tmp, alpha, beta); // By using the trans(A)*trans(B) = trans(B*A) equivalency, // transpose operations are not needed arma_aligned podarray<eT> tmp(B.n_cols); eT* B_rowdata = tmp.memptr(); for(uword row_B=0; row_B < B_n_rows; ++row_B) { tmp.copy_row(B, row_B); for(uword col_A=0; col_A < A_n_cols; ++col_A) { const eT acc = op_dot::direct_dot_arma(A_n_rows, B_rowdata, A.colptr(col_A)); if( (use_alpha == false) && (use_beta == false) ) { C.at(col_A,row_B) = acc; } else if( (use_alpha == true ) && (use_beta == false) ) { C.at(col_A,row_B) = alpha*acc; } else if( (use_alpha == false) && (use_beta == true ) ) { C.at(col_A,row_B) = acc + beta*C.at(col_A,row_B); } else if( (use_alpha == true ) && (use_beta == true ) ) { C.at(col_A,row_B) = alpha*acc + beta*C.at(col_A,row_B); } } } } }
inline void arma_ostream::print_dense(std::ostream& o, const SpMat<eT>& m, const bool modify) { arma_extra_debug_sigprint(); const arma_ostream_state stream_state(o); const uword m_n_rows = m.n_rows; const uword m_n_cols = m.n_cols; if(m.n_nonzero > 0) { const std::streamsize cell_width = modify ? modify_stream<eT>(o, m.begin(), m.n_nonzero) : o.width(); typename SpMat<eT>::const_iterator begin = m.begin(); if(m_n_cols > 0) { if(cell_width > 0) { // An efficient row_iterator would make this simpler and faster for(uword row=0; row < m_n_rows; ++row) { for(uword col=0; col < m_n_cols; ++col) { // the cell width appears to be reset after each element is printed, // hence we need to restore it o.width(cell_width); eT val = eT(0); for(typename SpMat<eT>::const_iterator it = begin; it.pos() < m.n_nonzero; ++it) { if(it.row() == row && it.col() == col) { val = *it; break; } } arma_ostream::print_elem(o,eT(val), modify); } o << '\n'; } } else { // An efficient row_iterator would make this simpler and faster for(uword row=0; row < m_n_rows; ++row) { for(uword col=0; col < m_n_cols; ++col) { eT val = eT(0); for(typename SpMat<eT>::const_iterator it = begin; it.pos() < m.n_nonzero; ++it) { if(it.row() == row && it.col() == col) { val = *it; break; } } arma_ostream::print_elem(o,eT(val), modify); o << ' '; } o << '\n'; } } } } else { if(m.n_elem == 0) { o << "[matrix size: " << m_n_rows << 'x' << m_n_cols << "]\n"; } else { eT tmp[1]; tmp[0] = eT(0); const std::streamsize cell_width = modify ? arma_ostream::modify_stream(o, &tmp[0], 1) : o.width(); for(uword row=0; row < m_n_rows; ++row) { for(uword col=0; col < m_n_cols; ++col) { o.width(cell_width); arma_ostream::print_elem_zero<eT>(o, modify); o << ' '; } o << '\n'; } } } o.flush(); stream_state.restore(o); }
inline explicit Proxy(const eOp<T1, eop_type>& A) : Q(A) { arma_extra_debug_sigprint(); }
inline subview_cube_each2<eT,TB>::~subview_cube_each2() { arma_extra_debug_sigprint(); }
inline explicit Proxy(const eGlue<T1, T2, eglue_type>& A) : Q(A) { arma_extra_debug_sigprint(); }
inline subview_cube_each1<eT>::subview_cube_each1(const Cube<eT>& in_p) : subview_cube_each_common<eT>::subview_cube_each_common(in_p) { arma_extra_debug_sigprint(); }
inline explicit Proxy(const mtOp<out_eT, T1, op_type>& A) : Q(A) { arma_extra_debug_sigprint(); }
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 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); } }
inline explicit Proxy(const mtGlue<out_eT, T1, T2, glue_type>& A) : Q(A) { arma_extra_debug_sigprint(); }
inline bool op_logmat_cx::apply_common(Mat< std::complex<T> >& out, Mat< std::complex<T> >& S, const uword n_iters) { arma_extra_debug_sigprint(); typedef typename std::complex<T> eT; Mat<eT> U; const bool schur_ok = auxlib::schur(U,S); if(schur_ok == false) { arma_extra_debug_print("logmat(): schur decomposition failed"); return false; } //double theta[] = { 1.10e-5, 1.82e-3, 1.62e-2, 5.39e-2, 1.14e-1, 1.87e-1, 2.64e-1 }; double theta[] = { 0.0, 0.0, 1.6206284795015624e-2, 5.3873532631381171e-2, 1.1352802267628681e-1, 1.8662860613541288e-1, 2.642960831111435e-1 }; // theta[0] and theta[1] not really used const uword N = S.n_rows; uword p = 0; uword m = 6; uword iter = 0; while(iter < n_iters) { const T tau = norm( (S - eye< Mat<eT> >(N,N)), 1 ); if(tau <= theta[6]) { p++; uword j1 = 0; uword j2 = 0; for(uword i=2; i<=6; ++i) { if( tau <= theta[i]) { j1 = i; break; } } for(uword i=2; i<=6; ++i) { if((tau/2.0) <= theta[i]) { j2 = i; break; } } // sanity check, for development purposes only arma_debug_check( (j2 > j1), "internal error: op_logmat::apply_direct(): j2 > j1" ); if( ((j1 - j2) <= 1) || (p == 2) ) { m = j1; break; } } const bool sqrtmat_ok = op_sqrtmat_cx::apply_direct(S,S); if(sqrtmat_ok == false) { arma_extra_debug_print("logmat(): sqrtmat() failed"); return false; } iter++; } if(iter >= n_iters) { arma_debug_warn("logmat(): reached max iterations without full convergence"); } S.diag() -= eT(1); if(m >= 1) { const bool helper_ok = op_logmat_cx::helper(S,m); if(helper_ok == false) { return false; } } out = U * S * U.t(); out *= eT(eop_aux::pow(double(2), double(iter))); return true; }
inline explicit Proxy(const Col<eT>& A) : Q(A) { arma_extra_debug_sigprint(); }
inline typename arma_not_cx<typename T1::elem_type>::result op_min::min(const Base<typename T1::elem_type,T1>& X) { arma_extra_debug_sigprint(); typedef typename T1::elem_type eT; const Proxy<T1> P(X.get_ref()); const uword n_elem = P.get_n_elem(); arma_debug_check( (n_elem == 0), "min(): given object has no elements" ); eT min_val = priv::most_pos<eT>(); if(Proxy<T1>::prefer_at_accessor == false) { typedef typename Proxy<T1>::ea_type ea_type; ea_type A = P.get_ea(); uword i,j; for(i=0, j=1; j<n_elem; i+=2, j+=2) { const eT tmp_i = A[i]; const eT tmp_j = A[j]; if(tmp_i < min_val) { min_val = tmp_i; } if(tmp_j < min_val) { min_val = tmp_j; } } if(i < n_elem) { const eT tmp_i = A[i]; if(tmp_i < min_val) { min_val = tmp_i; } } } else { const uword n_rows = P.get_n_rows(); const uword n_cols = P.get_n_cols(); if(n_rows == 1) { uword i,j; for(i=0, j=1; j < n_cols; i+=2, j+=2) { const eT tmp_i = P.at(0,i); const eT tmp_j = P.at(0,j); if(tmp_i < min_val) { min_val = tmp_i; } if(tmp_j < min_val) { min_val = tmp_j; } } if(i < n_cols) { const eT tmp_i = P.at(0,i); if(tmp_i < min_val) { min_val = tmp_i; } } } else { for(uword col=0; col < n_cols; ++col) { uword i,j; for(i=0, j=1; j < n_rows; i+=2, j+=2) { const eT tmp_i = P.at(i,col); const eT tmp_j = P.at(j,col); if(tmp_i < min_val) { min_val = tmp_i; } if(tmp_j < min_val) { min_val = tmp_j; } } if(i < n_rows) { const eT tmp_i = P.at(i,col); if(tmp_i < min_val) { min_val = tmp_i; } } } } } return min_val; }
inline void op_princomp::direct_princomp ( Mat< std::complex<T> >& coeff_out, Mat< std::complex<T> >& score_out, const Mat< std::complex<T> >& in ) { arma_extra_debug_sigprint(); typedef std::complex<T> eT; const u32 n_rows = in.n_rows; const u32 n_cols = in.n_cols; if(n_rows > 1) // more than one sample { // subtract the mean - use score_out as temporary matrix score_out = in - repmat(mean(in), n_rows, 1); // singular value decomposition Mat<eT> U; Col< T> s; const bool svd_ok = svd(U,s,coeff_out,score_out); if(svd_ok == false) { arma_print("princomp(): singular value decomposition failed"); coeff_out.reset(); score_out.reset(); return; } // U.reset(); // normalize the eigenvalues s /= std::sqrt(n_rows - 1); // project the samples to the principals score_out *= coeff_out; if(n_rows <= n_cols) // number of samples is less than their dimensionality { score_out.cols(n_rows-1,n_cols-1).zeros(); } } else // single sample - row { if(n_rows == 1) { coeff_out = eye< Mat<eT> >(n_cols, n_cols); score_out.copy_size(in); score_out.zeros(); } else { coeff_out.reset(); score_out.reset(); } } }