inline eT op_min::direct_min(const Mat<eT>& X, const uword row) { arma_extra_debug_sigprint(); const uword X_n_cols = X.n_cols; eT min_val = priv::most_pos<eT>(); uword i,j; for(i=0, j=1; j < X_n_cols; i+=2, j+=2) { const eT tmp_i = X.at(row,i); const eT tmp_j = X.at(row,j); if(tmp_i < min_val) { min_val = tmp_i; } if(tmp_j < min_val) { min_val = tmp_j; } } if(i < X_n_cols) { const eT tmp_i = X.at(row,i); if(tmp_i < min_val) { min_val = tmp_i; } } return min_val; }
arma_hot inline eT op_dot::dot_and_copy_row(eT* out, const Mat<eT>& A, const uword row, const eT* B_mem, const uword N) { eT acc1 = eT(0); eT acc2 = eT(0); uword i,j; for(i=0, j=1; j < N; i+=2, j+=2) { const eT val_i = A.at(row, i); const eT val_j = A.at(row, j); out[i] = val_i; out[j] = val_j; acc1 += val_i * B_mem[i]; acc2 += val_j * B_mem[j]; } if(i < N) { const eT val_i = A.at(row, i); out[i] = val_i; acc1 += val_i * B_mem[i]; } return acc1 + acc2; }
inline bool op_logmat::apply_direct(Mat< std::complex<typename T1::elem_type> >& out, const Op<T1,op_diagmat>& expr, const uword) { arma_extra_debug_sigprint(); typedef typename T1::elem_type T; const diagmat_proxy<T1> P(expr.m); arma_debug_check( (P.n_rows != P.n_cols), "logmat(): given matrix must be square sized" ); const uword N = P.n_rows; out.zeros(N,N); for(uword i=0; i<N; ++i) { const T val = P[i]; if(val >= T(0)) { out.at(i,i) = std::log(val); } else { out.at(i,i) = std::log( std::complex<T>(val) ); } } return true; }
inline eT op_mean::direct_mean(const Mat<eT>& X, const uword row) { arma_extra_debug_sigprint(); typedef typename get_pod_type<eT>::result T; const uword X_n_cols = X.n_cols; eT val = eT(0); uword i,j; for(i=0, j=1; j < X_n_cols; i+=2, j+=2) { val += X.at(row,i); val += X.at(row,j); } if(i < X_n_cols) { val += X.at(row,i); } const eT result = val / T(X_n_cols); return arma_isfinite(result) ? result : op_mean::direct_mean_robust(X, row); }
inline void op_diagmat2::apply(Mat<typename T1::elem_type>& out, const Proxy<T1>& P, const uword row_offset, const uword col_offset) { arma_extra_debug_sigprint(); const uword n_rows = P.get_n_rows(); const uword n_cols = P.get_n_cols(); const uword n_elem = P.get_n_elem(); if(n_elem == 0) { out.reset(); return; } const bool P_is_vec = (T1::is_row) || (T1::is_col) || (n_rows == 1) || (n_cols == 1); if(P_is_vec) { const uword n_pad = (std::max)(row_offset, col_offset); out.zeros(n_elem + n_pad, n_elem + n_pad); if(Proxy<T1>::prefer_at_accessor == false) { typename Proxy<T1>::ea_type Pea = P.get_ea(); for(uword i=0; i < n_elem; ++i) { out.at(row_offset + i, col_offset + i) = Pea[i]; } } else { const unwrap<typename Proxy<T1>::stored_type> U(P.Q); const Proxy<typename unwrap<typename Proxy<T1>::stored_type>::stored_type> PP(U.M); op_diagmat2::apply(out, PP, row_offset, col_offset); } } else // P represents a matrix { arma_debug_check ( ((row_offset > 0) && (row_offset >= n_rows)) || ((col_offset > 0) && (col_offset >= n_cols)), "diagmat(): requested diagonal out of bounds" ); out.zeros(n_rows, n_cols); const uword N = (std::min)(n_rows - row_offset, n_cols - col_offset); for(uword i=0; i<N; ++i) { const uword row = i + row_offset; const uword col = i + col_offset; out.at(row,col) = P.at(row,col); } } }
inline void arma_ostream::print(std::ostream& o, const Mat<eT>& m, const bool modify) { arma_extra_debug_sigprint(); const arma_ostream_state stream_state(o); const std::streamsize cell_width = modify ? arma_ostream::modify_stream(o, m.memptr(), m.n_elem) : o.width(); const uword m_n_rows = m.n_rows; const uword m_n_cols = m.n_cols; if(m.is_empty() == false) { if(m_n_cols > 0) { if(cell_width > 0) { 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); arma_ostream::print_elem(o, m.at(row,col), modify); } o << '\n'; } } else { for(uword row=0; row < m_n_rows; ++row) { for(uword col=0; col < m_n_cols-1; ++col) { arma_ostream::print_elem(o, m.at(row,col), modify); o << ' '; } arma_ostream::print_elem(o, m.at(row, m_n_cols-1), modify); o << '\n'; } } } } else { o << "[matrix size: " << m_n_rows << 'x' << m_n_cols << "]\n"; } o.flush(); stream_state.restore(o); }
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 void op_trimat::apply_htrans ( Mat<eT>& out, const Mat<eT>& A, const bool upper, const typename arma_cx_only<eT>::result* junk ) { arma_extra_debug_sigprint(); arma_ignore(junk); arma_debug_check( (A.is_square() == false), "trimatu()/trimatl(): given matrix must be square sized" ); const uword N = A.n_rows; if(&out != &A) { out.copy_size(A); } if(upper) { // Upper triangular: but since we're transposing, we're taking the lower // triangular and putting it in the upper half. for(uword row = 0; row < N; ++row) { eT* out_colptr = out.colptr(row); for(uword col = 0; col <= row; ++col) { //out.at(col, row) = std::conj( A.at(row, col) ); out_colptr[col] = std::conj( A.at(row, col) ); } } } else { // Lower triangular: but since we're transposing, we're taking the upper // triangular and putting it in the lower half. for(uword row = 0; row < N; ++row) { for(uword col = row; col < N; ++col) { out.at(col, row) = std::conj( A.at(row, col) ); } } } op_trimat::fill_zeros(out, upper); }
arma_hot inline void podarray<eT>::copy_row(const Mat<eT>& A, const uword row) { const uword cols = A.n_cols; // note: this function assumes that the podarray has been set to the correct size beforehand eT* out = memptr(); switch(cols) { default: { uword i,j; for(i=0, j=1; j < cols; i+=2, j+=2) { const eT tmp_i = A.at(row, i); const eT tmp_j = A.at(row, j); out[i] = tmp_i; out[j] = tmp_j; } if(i < cols) { out[i] = A.at(row, i); } } break; case 8: out[7] = A.at(row, 7); // fallthrough case 7: out[6] = A.at(row, 6); // fallthrough case 6: out[5] = A.at(row, 5); // fallthrough case 5: out[4] = A.at(row, 4); // fallthrough case 4: out[3] = A.at(row, 3); // fallthrough case 3: out[2] = A.at(row, 2); // fallthrough case 2: out[1] = A.at(row, 1); // fallthrough case 1: out[0] = A.at(row, 0); // fallthrough case 0: ; // fallthrough } }
arma_hot inline void eop_core<eop_type>::apply_unwrap(Mat<typename T1::elem_type>& out, const eOp<T1, eop_type>& x) { arma_extra_debug_sigprint(); typedef typename T1::elem_type eT; const Proxy<T1>& P = x.P; out.set_size(P.n_rows, P.n_cols); eT* out_mem = out.memptr(); const u32 n_elem = P.n_elem; const unwrap<typename Proxy<T1>::stored_type> tmp(P.Q); const Mat<eT>& A = tmp.M; if(is_generator<eop_type>::value == true) { for(u32 i=0; i<n_elem; ++i) { out_mem[i] = eop_aux::generate<eT,eop_type>(); } } else { if(is_same_type<eop_type, eop_ones_diag>::value == true) { for(u32 col=0; col<P.n_rows; ++col) { for(u32 row=0; row<col; ++row) { out.at(row,col) = eT(0); } out.at(col,col) = eT(1); for(u32 row=col+1; row<P.n_rows; ++row) { out.at(row,col) = eT(0); } } } else { const eT* A_mem = A.memptr(); for(u32 i=0; i<n_elem; ++i) { out_mem[i] = eop_core<eop_type>::process(x, A_mem[i]); } } } }
arma_hot inline void eop_core<eop_type>::apply_proxy(Mat<typename T1::elem_type>& out, const eOp<T1, eop_type>& x) { arma_extra_debug_sigprint(); // eop_type::apply_proxy() function is not allowed to unwrap things // (in order to get the input into a common format). // the proxy class is already providing objects with element access typedef typename T1::elem_type eT; const Proxy<T1>& P = x.P; out.set_size(P.n_rows, P.n_cols); eT* out_mem = out.memptr(); const u32 n_elem = P.n_elem; if(is_generator<eop_type>::value == true) { for(u32 i=0; i<n_elem; ++i) { out_mem[i] = eop_aux::generate<eT,eop_type>(); } } else { if(is_same_type<eop_type, eop_ones_diag>::value == true) { for(u32 col=0; col<P.n_rows; ++col) { for(u32 row=0; row<col; ++row) { out.at(row,col) = eT(0); } out.at(col,col) = eT(1); for(u32 row=col+1; row<P.n_rows; ++row) { out.at(row,col) = eT(0); } } } else { for(u32 i=0; i<n_elem; ++i) { out_mem[i] = eop_core<eop_type>::process(x, P[i]); } } } }
arma_hot inline void op_strans::apply(Mat<eT>& out, const TA& A) { arma_extra_debug_sigprint(); if(&out != &A) { op_strans::apply_noalias(out, A); } else { const uword n_rows = A.n_rows; const uword n_cols = A.n_cols; if(n_rows == n_cols) { arma_extra_debug_print("op_strans::apply(): doing in-place transpose of a square matrix"); const uword N = n_rows; 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]); } } } else { Mat<eT> tmp; op_strans::apply_noalias(tmp, A); out.steal_mem(tmp); } } }
Mat<N> Mat<N>::operator*(const Mat<N>& r) const { Mat<N> ret; for (uint8_t x = 0; x < N; x++) { for (uint8_t y = 0; y < N; y++) { float sum = 0.0f; for (uint8_t i = 0; i < N; i++) { sum += at(i,y) * r.at(x,i); } ret.at(x,y) = sum; } } return ret; }
inline bool op_sqrtmat_cx::apply_direct_noalias(Mat<typename T1::elem_type>& out, const diagmat_proxy<T1>& P) { arma_extra_debug_sigprint(); typedef typename T1::elem_type eT; arma_debug_check( (P.n_rows != P.n_cols), "sqrtmat(): given matrix must be square sized" ); const uword N = P.n_rows; out.zeros(N,N); const eT zero = eT(0); bool singular = false; for(uword i=0; i<N; ++i) { const eT val = P[i]; singular = (singular || (val == zero)); out.at(i,i) = std::sqrt(val); } return (singular) ? false : true; }
inline bool diskio::save_pgm_binary(const Mat<eT>& x, std::ostream& f) { arma_extra_debug_sigprint(); f << "P5" << '\n'; f << x.n_cols << ' ' << x.n_rows << '\n'; f << 255 << '\n'; const u32 n_elem = x.n_rows * x.n_cols; podarray<u8> tmp(n_elem); u32 i = 0; for(u32 row=0; row < x.n_rows; ++row) { for(u32 col=0; col < x.n_cols; ++col) { tmp[i] = u8( x.at(row,col) ); // TODO: add round() ? ++i; } } f.write(reinterpret_cast<const char*>(tmp.mem), n_elem); return f.good(); }
arma_hot inline void op_strans::apply_noalias(Mat<eT>& out, const TA& A) { arma_extra_debug_sigprint(); const uword A_n_cols = A.n_cols; const uword A_n_rows = A.n_rows; out.set_size(A_n_cols, A_n_rows); if( (TA::is_row) || (TA::is_col) || (A_n_cols == 1) || (A_n_rows == 1) ) { arrayops::copy( out.memptr(), A.memptr(), A.n_elem ); } else { if( (A_n_rows <= 4) && (A_n_rows == A_n_cols) ) { op_strans::apply_noalias_tinysq(out, A); } else { for(uword k=0; k < A_n_cols; ++k) { uword i, j; const eT* colptr = A.colptr(k); for(i=0, j=1; j < A_n_rows; i+=2, j+=2) { const eT tmp_i = colptr[i]; const eT tmp_j = colptr[j]; out.at(k, i) = tmp_i; out.at(k, j) = tmp_j; } if(i < A_n_rows) { out.at(k, i) = colptr[i]; } } } } }
inline void glue_times::apply_inplace(Mat<typename T1::elem_type>& out, const T1& X) { arma_extra_debug_sigprint(); typedef typename T1::elem_type eT; const unwrap_check<T1> tmp(X, out); const Mat<eT>& B = tmp.M; arma_debug_assert_mul_size(out, B, "matrix multiply"); if(out.n_cols == B.n_cols) { podarray<eT> tmp(out.n_cols); eT* tmp_rowdata = tmp.memptr(); for(u32 out_row=0; out_row < out.n_rows; ++out_row) { for(u32 out_col=0; out_col < out.n_cols; ++out_col) { tmp_rowdata[out_col] = out.at(out_row,out_col); } for(u32 B_col=0; B_col < B.n_cols; ++B_col) { const eT* B_coldata = B.colptr(B_col); eT val = eT(0); for(u32 i=0; i < B.n_rows; ++i) { val += tmp_rowdata[i] * B_coldata[i]; } out.at(out_row,B_col) = val; } } } else { const Mat<eT> tmp(out); glue_times::apply(out, tmp, B, eT(1), false, false, false); } }
inline void op_sum::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_sum>& in) { arma_extra_debug_sigprint(); const u32 dim = in.aux_u32_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; arma_debug_check( (X.n_elem < 1), "sum(): given object has no elements"); const u32 X_n_rows = X.n_rows; const u32 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); for(u32 col=0; col<X_n_cols; ++col) { out.at(0,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); 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.at(row,0) = val; } } }
inline void op_htrans::apply(Mat< std::complex<T> >& out, const Mat< std::complex<T> >& A) { arma_extra_debug_sigprint(); typedef typename std::complex<T> eT; if(&out != &A) { op_htrans::apply_noalias(out, A); } else { if(out.n_rows == out.n_cols) { arma_extra_debug_print("doing in-place hermitian transpose of a square matrix"); const u32 n_rows = out.n_rows; const u32 n_cols = out.n_cols; for(u32 col=0; col<n_cols; ++col) { eT* coldata = out.colptr(col); out.at(col,col) = std::conj( out.at(col,col) ); for(u32 row=(col+1); row<n_rows; ++row) { const eT val1 = std::conj(coldata[row]); const eT val2 = std::conj(out.at(col,row)); out.at(col,row) = val1; coldata[row] = val2; } } } else { const Mat<eT> A_copy = A; op_htrans::apply_noalias(out, A_copy); } } }
void expectedMatAt() { if(_elemInd >= _genMat.n_elem) { return; } cout << "- Compute expectedMatAt() ... "; save<double>("Mat.at", Mat<double>({_genMat.at(_elemInd)})); cout << "done." << endl; }
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_sort::copy_row(Mat<eT>& A, const eT* X, const uword row) { const uword N = A.n_cols; uword i,j; for(i=0, j=1; j<N; i+=2, j+=2) { A.at(row,i) = X[i]; A.at(row,j) = X[j]; } if(i < N) { A.at(row,i) = X[i]; } }
inline eT op_dotext::direct_rowvec_transmat_colvec ( const eT* A_mem, const Mat<eT>& B, const eT* C_mem ) { arma_extra_debug_sigprint(); const u32 cost_AB = B.n_rows; const u32 cost_BC = B.n_cols; if(cost_AB <= cost_BC) { podarray<eT> tmp(B.n_rows); for(u32 row=0; row<B.n_rows; ++row) { eT val = eT(0); for(u32 i=0; i<B.n_cols; ++i) { val += A_mem[i] * B.at(row,i); } tmp[row] = val; } return op_dot::direct_dot(B.n_rows, tmp.mem, C_mem); } else { podarray<eT> tmp(B.n_cols); for(u32 col=0; col<B.n_cols; ++col) { const eT* B_coldata = B.colptr(col); eT val = eT(0); for(u32 i=0; i<B.n_rows; ++i) { val += B_coldata[i] * C_mem[i]; } tmp[col] = val; } return op_dot::direct_dot(B.n_cols, A_mem, tmp.mem); } }
inline void op_htrans::apply_noalias(Mat< std::complex<T> >& out, const Mat< std::complex<T> >& A) { arma_extra_debug_sigprint(); out.set_size(A.n_cols, A.n_rows); for(u32 in_row = 0; in_row<A.n_rows; ++in_row) { const u32 out_col = in_row; for(u32 in_col = 0; in_col<A.n_cols; ++in_col) { const u32 out_row = in_col; out.at(out_row, out_col) = std::conj( A.at(in_row, in_col) ); } } }
inline eT op_max::direct_max(const Mat<eT>& X, const u32 row) { arma_extra_debug_sigprint(); const u32 X_n_cols = X.n_cols; eT max_val = (X_n_cols != 1) ? priv::most_neg<eT>() : X.at(row,0); for(u32 col=0; col<X_n_cols; ++col) { const eT tmp_val = X.at(row,col); if(tmp_val > max_val) { max_val = tmp_val; } } return max_val; }
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_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 std::complex<T> op_min::direct_min(const Mat< std::complex<T> >& X, const uword row) { arma_extra_debug_sigprint(); const uword X_n_cols = X.n_cols; uword index = 0; T min_val = priv::most_pos<T>(); for(uword col=0; 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; } } return X.at(row,index); }
inline std::complex<T> op_max::direct_max(const Mat< std::complex<T> >& X, const u32 row) { arma_extra_debug_sigprint(); const u32 X_n_cols = X.n_cols; u32 index = 0; T max_val = (X_n_cols != 1) ? priv::most_neg<T>() : std::abs(X.at(row,0)); for(u32 col=0; col<X_n_cols; ++col) { const T tmp_val = std::abs(X.at(row,col)); if(tmp_val > max_val) { max_val = tmp_val; index = col; } } return X.at(row,index); }
//add database items into this tree, be careful! //input: the database items pointer p_d //retval: bool; true--> add all of them ok // false--> something goes wrong bool Tree:: addDatabaseItems( const Mat<double> * p_d ) { size_t r,c; TreeNode * current; Mat<double> result; r = p_d->n_rows; c = p_d->n_cols - 1 ; Row< double > tmp; for( size_t i = 0 ; i < r ; i ++ ) { tmp = p_d->row( i ); tmp.at( c ) = 1; //the x sample needs to become this x=[x0 x1 x2 ... 1 ] current = root; while( (current != NULL) && ( current->isInternal() )) { result = tmp * (current->intL).pvector->at(0) ; if( result.at( 0 ) > 0 ) { current = current->intL.left; }else { current = current->intL.right; } } if( NULL == current ) { cerr <<"current is null in the addDatabaseIntems()\b"; return false; } if( NULL == current->leafL.puivector ) { current->leafL.puivector = new vector< unsigned int >; } (current->leafL).puivector->push_back( i ); } return true; }