diff options
Diffstat (limited to 'src/armadillo/include/armadillo_bits/arma_ostream_meat.hpp')
-rw-r--r-- | src/armadillo/include/armadillo_bits/arma_ostream_meat.hpp | 1274 |
1 files changed, 1274 insertions, 0 deletions
diff --git a/src/armadillo/include/armadillo_bits/arma_ostream_meat.hpp b/src/armadillo/include/armadillo_bits/arma_ostream_meat.hpp new file mode 100644 index 0000000..dbd4b6c --- /dev/null +++ b/src/armadillo/include/armadillo_bits/arma_ostream_meat.hpp @@ -0,0 +1,1274 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) +// Copyright 2008-2016 National ICT Australia (NICTA) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + + +//! \addtogroup arma_ostream +//! @{ + + + +inline +arma_ostream_state::arma_ostream_state(const std::ostream& o) + : orig_flags (o.flags()) + , orig_precision(o.precision()) + , orig_width (o.width()) + , orig_fill (o.fill()) + { + } + + + +inline +void +arma_ostream_state::restore(std::ostream& o) const + { + o.flags (orig_flags); + o.precision(orig_precision); + o.width (orig_width); + o.fill (orig_fill); + } + + + +// +// + + + +template<typename eT> +inline +std::streamsize +arma_ostream::modify_stream(std::ostream& o, const eT* data, const uword n_elem) + { + 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; + bool use_layout_D = false; + + for(uword i=0; i<n_elem; ++i) + { + const eT val = data[i]; + + if(arma_isfinite(val) == false) { continue; } + + if( + ( cond_rel< (sizeof(eT) > 4) && (is_same_type<uword,eT>::yes || is_same_type<sword,eT>::yes) >::geq(val, eT(+10000000000)) ) + || + ( cond_rel< (sizeof(eT) > 4) && is_same_type<sword,eT>::yes >::leq(val, eT(-10000000000)) ) + ) + { + use_layout_D = true; + break; + } + + if( + ( val >= eT(+100) ) + || + //( (is_signed<eT>::value) && (val <= eT(-100)) ) || + //( (is_non_integral<eT>::value) && (val > eT(0)) && (val <= eT(+1e-4)) ) || + //( (is_non_integral<eT>::value) && (is_signed<eT>::value) && (val < eT(0)) && (val >= eT(-1e-4)) ) + ( + cond_rel< is_signed<eT>::value >::leq(val, eT(-100)) + ) + || + ( + cond_rel< is_non_integral<eT>::value >::gt(val, eT(0)) + && + cond_rel< is_non_integral<eT>::value >::leq(val, eT(+1e-4)) + ) + || + ( + cond_rel< is_non_integral<eT>::value && is_signed<eT>::value >::lt(val, eT(0)) + && + cond_rel< is_non_integral<eT>::value && is_signed<eT>::value >::geq(val, eT(-1e-4)) + ) + ) + { + use_layout_C = true; + break; + } + + if( + // (val >= eT(+10)) || ( (is_signed<eT>::value) && (val <= eT(-10)) ) + (val >= eT(+10)) || ( cond_rel< is_signed<eT>::value >::leq(val, eT(-10)) ) + ) + { + use_layout_B = true; + } + } + + if(use_layout_D) + { + o.setf(ios::scientific); + o.setf(ios::right); + o.unsetf(ios::fixed); + o.precision(4); + cell_width = 21; + } + else + if(use_layout_C) + { + o.setf(ios::scientific); + o.setf(ios::right); + o.unsetf(ios::fixed); + o.precision(4); + cell_width = 13; + } + else + if(use_layout_B) + { + 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; + } + + + +//! "better than nothing" settings for complex numbers +template<typename T> +inline +std::streamsize +arma_ostream::modify_stream(std::ostream& o, const std::complex<T>* data, const uword n_elem) + { + arma_ignore(data); + arma_ignore(n_elem); + + o.unsetf(ios::showbase); + o.unsetf(ios::uppercase); + o.fill(' '); + + o.setf(ios::scientific); + o.setf(ios::showpos); + o.setf(ios::right); + o.unsetf(ios::fixed); + + std::streamsize cell_width; + + o.precision(3); + cell_width = 2 + 2*(1 + 3 + o.precision() + 5) + 1; + + return cell_width; + } + + +template<typename eT> +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(arma_isfinite(val) == false) { continue; } + + if( + val >= eT(+100) || + ( (is_signed<eT>::value) && (val <= eT(-100)) ) || + ( (is_non_integral<eT>::value) && (val > eT(0)) && (val <= eT(+1e-4)) ) || + ( (is_non_integral<eT>::value) && (is_signed<eT>::value) && (val < eT(0)) && (val >= eT(-1e-4)) ) + ) + { + use_layout_C = true; + break; + } + + if( + (val >= eT(+10)) || ( (is_signed<eT>::value) && (val <= eT(-10)) ) + ) + { + use_layout_B = true; + } + } + + if(use_layout_C) + { + o.setf(ios::scientific); + o.setf(ios::right); + o.unsetf(ios::fixed); + o.precision(4); + cell_width = 13; + } + else + if(use_layout_B) + { + 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; + } + + + +//! "better than nothing" settings for complex numbers +template<typename eT> +inline +std::streamsize +arma_ostream::modify_stream(std::ostream& o, typename SpMat<eT>::const_iterator begin, const uword n_elem, const typename arma_cx_only<eT>::result* junk) + { + arma_ignore(begin); + arma_ignore(n_elem); + arma_ignore(junk); + + o.unsetf(ios::showbase); + o.unsetf(ios::uppercase); + o.fill(' '); + + o.setf(ios::scientific); + o.setf(ios::showpos); + o.setf(ios::right); + o.unsetf(ios::fixed); + + std::streamsize cell_width; + + o.precision(3); + cell_width = 2 + 2*(1 + 3 + o.precision() + 5) + 1; + + return cell_width; + } + + + +template<typename eT> +inline +void +arma_ostream::print_elem_zero(std::ostream& o, const bool modify) + { + typedef typename promote_type<eT, s16>::result promoted_eT; + + if(modify) + { + const ios::fmtflags save_flags = o.flags(); + const std::streamsize save_precision = o.precision(); + + o.unsetf(ios::scientific); + o.setf(ios::fixed); + o.precision(0); + + o << promoted_eT(0); + + o.flags(save_flags); + o.precision(save_precision); + } + else + { + o << promoted_eT(0); + } + } + + + +template<typename eT> +inline +void +arma_ostream::print_elem(std::ostream& o, const eT& x, const bool modify) + { + if(x == eT(0)) + { + arma_ostream::print_elem_zero<eT>(o, modify); + } + else + { + arma_ostream::raw_print_elem(o, x); + } + } + + + +template<typename eT> +inline +void +arma_ostream::raw_print_elem(std::ostream& o, const eT& x) + { + if(is_signed<eT>::value) + { + typedef typename promote_type<eT, s16>::result promoted_eT; + + if(arma_isfinite(x)) + { + o << promoted_eT(x); + } + else + { + o << ( arma_isinf(x) ? ((x <= eT(0)) ? "-inf" : "inf") : "nan" ); + } + } + else + { + typedef typename promote_type<eT, u16>::result promoted_eT; + + o << promoted_eT(x); + } + } + + + +template<typename T> +inline +void +arma_ostream::print_elem(std::ostream& o, const std::complex<T>& x, const bool modify) + { + if( (x.real() == T(0)) && (x.imag() == T(0)) && (modify) ) + { + o << "(0,0)"; + } + else + { + arma_ostream::raw_print_elem(o, x); + } + } + + + +template<typename T> +inline +void +arma_ostream::raw_print_elem(std::ostream& o, const std::complex<T>& x) + { + std::ostringstream ss; + ss.flags(o.flags()); + //ss.imbue(o.getloc()); + ss.precision(o.precision()); + + ss << '('; + + const T a = x.real(); + + if(arma_isfinite(a)) + { + ss << a; + } + else + { + ss << ( arma_isinf(a) ? ((a <= T(0)) ? "-inf" : "+inf") : "nan" ); + } + + ss << ','; + + const T b = x.imag(); + + if(arma_isfinite(b)) + { + ss << b; + } + else + { + ss << ( arma_isinf(b) ? ((b <= T(0)) ? "-inf" : "+inf") : "nan" ); + } + + ss << ')'; + + o << ss.str(); + } + + + +//! Print a matrix to the specified stream +template<typename eT> +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 + { + if(modify) + { + o.unsetf(ios::showbase); + o.unsetf(ios::uppercase); + o.unsetf(ios::showpos); + o.setf(ios::fixed); + } + + o << "[matrix size: " << m_n_rows << 'x' << m_n_cols << "]\n"; + } + + o.flush(); + stream_state.restore(o); + } + + + +//! Print a cube to the specified stream +template<typename eT> +inline +void +arma_ostream::print(std::ostream& o, const Cube<eT>& x, const bool modify) + { + arma_extra_debug_sigprint(); + + const arma_ostream_state stream_state(o); + + if(x.is_empty() == false) + { + for(uword slice=0; slice < x.n_slices; ++slice) + { + const Mat<eT> tmp(const_cast<eT*>(x.slice_memptr(slice)), x.n_rows, x.n_cols, false); + + o << "[cube slice: " << slice << ']' << '\n'; + arma_ostream::print(o, tmp, modify); + + if((slice+1) < x.n_slices) { o << '\n'; } + } + } + else + { + if(modify) + { + o.unsetf(ios::showbase); + o.unsetf(ios::uppercase); + o.unsetf(ios::showpos); + o.setf(ios::fixed); + } + + o << "[cube size: " << x.n_rows << 'x' << x.n_cols << 'x' << x.n_slices << "]\n"; + } + + stream_state.restore(o); + } + + + + +//! Print a field to the specified stream +//! Assumes type oT can be printed, ie. oT has std::ostream& operator<< (std::ostream&, const oT&) +template<typename oT> +inline +void +arma_ostream::print(std::ostream& o, const field<oT>& x) + { + arma_extra_debug_sigprint(); + + const arma_ostream_state stream_state(o); + + const std::streamsize cell_width = o.width(); + + const uword x_n_rows = x.n_rows; + const uword x_n_cols = x.n_cols; + const uword x_n_slices = x.n_slices; + + if(x.is_empty() == false) + { + if(x_n_slices == 1) + { + for(uword col=0; col < x_n_cols; ++col) + { + o << "[field column: " << col << ']' << '\n'; + + for(uword row=0; row < x_n_rows; ++row) + { + o.width(cell_width); + o << x.at(row,col) << '\n'; + } + + o << '\n'; + } + } + else + { + for(uword slice=0; slice < x_n_slices; ++slice) + { + o << "[field slice: " << slice << ']' << '\n'; + + for(uword col=0; col < x_n_cols; ++col) + { + o << "[field column: " << col << ']' << '\n'; + + for(uword row=0; row < x_n_rows; ++row) + { + o.width(cell_width); + o << x.at(row,col,slice) << '\n'; + } + + o << '\n'; + } + + o << '\n'; + } + } + } + else + { + o.unsetf(ios::showbase); + o.unsetf(ios::uppercase); + o.unsetf(ios::showpos); + o.setf(ios::fixed); + + o << "[field size: " << x_n_rows << 'x' << x_n_cols << 'x' << x_n_slices << "]\n"; + } + + o.flush(); + stream_state.restore(o); + } + + + +//! Print a subfield to the specified stream +//! Assumes type oT can be printed, ie. oT has std::ostream& operator<< (std::ostream&, const oT&) +template<typename oT> +inline +void +arma_ostream::print(std::ostream& o, const subview_field<oT>& x) + { + arma_extra_debug_sigprint(); + + const arma_ostream_state stream_state(o); + + const std::streamsize cell_width = o.width(); + + const uword x_n_rows = x.n_rows; + const uword x_n_cols = x.n_cols; + const uword x_n_slices = x.n_slices; + + if(x.is_empty() == false) + { + if(x_n_slices == 1) + { + for(uword col=0; col < x_n_cols; ++col) + { + o << "[field column: " << col << ']' << '\n'; + for(uword row=0; row<x_n_rows; ++row) + { + o.width(cell_width); + o << x.at(row,col) << '\n'; + } + + o << '\n'; + } + } + else + { + for(uword slice=0; slice < x_n_slices; ++slice) + { + o << "[field slice: " << slice << ']' << '\n'; + + for(uword col=0; col < x_n_cols; ++col) + { + o << "[field column: " << col << ']' << '\n'; + + for(uword row=0; row < x_n_rows; ++row) + { + o.width(cell_width); + o << x.at(row,col,slice) << '\n'; + } + + o << '\n'; + } + + o << '\n'; + } + } + } + else + { + o.unsetf(ios::showbase); + o.unsetf(ios::uppercase); + o.unsetf(ios::showpos); + o.setf(ios::fixed); + + o << "[field size: " << x_n_rows << 'x' << x_n_cols << 'x' << x_n_slices << "]\n"; + } + + o.flush(); + stream_state.restore(o); + } + + + +template<typename eT> +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); + + std::streamsize cell_width = o.width(); + + if(modify) + { + if(m.n_nonzero > 0) + { + cell_width = arma_ostream::modify_stream<eT>(o, m.begin(), m.n_nonzero); + } + else + { + eT tmp[1]; tmp[0] = eT(0); + + cell_width = arma_ostream::modify_stream(o, &tmp[0], 1); + } + } + + 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 + { + if(modify) + { + o.unsetf(ios::showbase); + o.unsetf(ios::uppercase); + o.unsetf(ios::showpos); + o.setf(ios::fixed); + } + + o << "[matrix size: " << m_n_rows << 'x' << m_n_cols << "]\n"; + } + + o.flush(); + stream_state.restore(o); + } + + + +template<typename eT> +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); + + const uword m_n_nonzero = m.n_nonzero; + const double density = (m.n_elem > 0) ? (double(m_n_nonzero) / double(m.n_elem) * double(100)) : double(0); + + o << "[matrix size: " << m.n_rows << 'x' << m.n_cols << "; n_nonzero: " << m_n_nonzero; + + if(density == double(0)) + { + o.precision(0); + } + else + if(density >= (double(10.0)-std::numeric_limits<double>::epsilon())) + { + o.precision(1); + } + else + if(density > (double(0.01)-std::numeric_limits<double>::epsilon())) + { + o.precision(2); + } + else + if(density > (double(0.001)-std::numeric_limits<double>::epsilon())) + { + o.precision(3); + } + else + if(density > (double(0.0001)-std::numeric_limits<double>::epsilon())) + { + o.precision(4); + } + else + { + o.unsetf(ios::fixed); + o.setf(ios::scientific); + o.precision(2); + } + + o << "; density: " << density << "%]\n\n"; + + if(modify == false) { stream_state.restore(o); } + + if(m_n_nonzero > 0) + { + const std::streamsize cell_width = modify ? arma_ostream::modify_stream<eT>(o, m.begin(), m_n_nonzero) : o.width(); + + typename SpMat<eT>::const_iterator it = m.begin(); + typename SpMat<eT>::const_iterator it_end = m.end(); + + while(it != it_end) + { + const uword row = it.row(); + const uword col = it.col(); + + // 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 << " "; } + else if(row < 1000000) { o << ' '; } + + 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 << " "; } + else if(col < 1000000) { o << ' '; } + + if(cell_width > 0) { o.width(cell_width); } + + arma_ostream::print_elem(o, eT(*it), modify); + o << '\n'; + + ++it; + } + + o << '\n'; + } + + o.flush(); + stream_state.restore(o); + } + + + +inline +void +arma_ostream::print(std::ostream& o, const SizeMat& S) + { + arma_extra_debug_sigprint(); + + const arma_ostream_state stream_state(o); + + o.unsetf(ios::showbase); + o.unsetf(ios::uppercase); + o.unsetf(ios::showpos); + + o.setf(ios::fixed); + + o << S.n_rows << 'x' << S.n_cols; + + stream_state.restore(o); + } + + + +inline +void +arma_ostream::print(std::ostream& o, const SizeCube& S) + { + arma_extra_debug_sigprint(); + + const arma_ostream_state stream_state(o); + + o.unsetf(ios::showbase); + o.unsetf(ios::uppercase); + o.unsetf(ios::showpos); + + o.setf(ios::fixed); + + o << S.n_rows << 'x' << S.n_cols << 'x' << S.n_slices; + + stream_state.restore(o); + } + + + +template<typename eT> +inline +void +arma_ostream::brief_print(std::ostream& o, const Mat<eT>& m, const bool print_size) + { + arma_extra_debug_sigprint(); + + const arma_ostream_state stream_state(o); + + if(print_size) + { + o.unsetf(ios::showbase); + o.unsetf(ios::uppercase); + o.unsetf(ios::showpos); + o.setf(ios::fixed); + + o << "[matrix size: " << m.n_rows << 'x' << m.n_cols << "]\n"; + } + + if(m.n_elem == 0) { o.flush(); stream_state.restore(o); return; } + + if((m.n_rows <= 5) && (m.n_cols <= 5)) { arma_ostream::print(o, m, true); return; } + + const bool print_row_ellipsis = (m.n_rows >= 6); + const bool print_col_ellipsis = (m.n_cols >= 6); + + if( (print_row_ellipsis == true) && (print_col_ellipsis == true) ) + { + Mat<eT> X(4, 4, arma_nozeros_indicator()); + + X( span(0,2), span(0,2) ) = m( span(0,2), span(0,2) ); // top left submatrix + X( 3, span(0,2) ) = m( m.n_rows-1, span(0,2) ); // truncated last row + X( span(0,2), 3 ) = m( span(0,2), m.n_cols-1 ); // truncated last column + X( 3, 3 ) = m( m.n_rows-1, m.n_cols-1 ); // bottom right element + + const std::streamsize cell_width = arma_ostream::modify_stream(o, X.memptr(), X.n_elem); + + for(uword row=0; row <= 2; ++row) + { + for(uword col=0; col <= 2; ++col) + { + o.width(cell_width); + arma_ostream::print_elem(o, X.at(row,col), true); + } + + o.width(6); + o << "..."; + + o.width(cell_width); + arma_ostream::print_elem(o, X.at(row,3), true); + o << '\n'; + } + + for(uword col=0; col <= 2; ++col) + { + o.width(cell_width); + o << ':'; + } + + o.width(6); + o << "..."; + + o.width(cell_width); + o << ':' << '\n'; + + const uword row = 3; + { + for(uword col=0; col <= 2; ++col) + { + o.width(cell_width); + arma_ostream::print_elem(o, X.at(row,col), true); + } + + o.width(6); + o << "..."; + + o.width(cell_width); + arma_ostream::print_elem(o, X.at(row,3), true); + o << '\n'; + } + } + + + if( (print_row_ellipsis == true) && (print_col_ellipsis == false) ) + { + Mat<eT> X(4, m.n_cols, arma_nozeros_indicator()); + + X( span(0,2), span::all ) = m( span(0,2), span::all ); // top + X( 3, span::all ) = m( m.n_rows-1, span::all ); // bottom + + const std::streamsize cell_width = arma_ostream::modify_stream(o, X.memptr(), X.n_elem); + + for(uword row=0; row <= 2; ++row) // first 3 rows + { + for(uword col=0; col < m.n_cols; ++col) + { + o.width(cell_width); + arma_ostream::print_elem(o, X.at(row,col), true); + } + + o << '\n'; + } + + for(uword col=0; col < m.n_cols; ++col) + { + o.width(cell_width); + o << ':'; + } + + o.width(cell_width); + o << '\n'; + + const uword row = 3; + { + for(uword col=0; col < m.n_cols; ++col) + { + o.width(cell_width); + arma_ostream::print_elem(o, X.at(row,col), true); + } + } + + o << '\n'; + } + + + if( (print_row_ellipsis == false) && (print_col_ellipsis == true) ) + { + Mat<eT> X(m.n_rows, 4, arma_nozeros_indicator()); + + X( span::all, span(0,2) ) = m( span::all, span(0,2) ); // left + X( span::all, 3 ) = m( span::all, m.n_cols-1 ); // right + + const std::streamsize cell_width = arma_ostream::modify_stream(o, X.memptr(), X.n_elem); + + for(uword row=0; row < m.n_rows; ++row) + { + for(uword col=0; col <= 2; ++col) + { + o.width(cell_width); + arma_ostream::print_elem(o, X.at(row,col), true); + } + + o.width(6); + o << "..."; + + o.width(cell_width); + arma_ostream::print_elem(o, X.at(row,3), true); + o << '\n'; + } + } + + + o.flush(); + stream_state.restore(o); + } + + + +template<typename eT> +inline +void +arma_ostream::brief_print(std::ostream& o, const Cube<eT>& x) + { + arma_extra_debug_sigprint(); + + const arma_ostream_state stream_state(o); + + o.unsetf(ios::showbase); + o.unsetf(ios::uppercase); + o.unsetf(ios::showpos); + o.setf(ios::fixed); + + o << "[cube size: " << x.n_rows << 'x' << x.n_cols << 'x' << x.n_slices << "]\n"; + + if(x.n_elem == 0) { o.flush(); stream_state.restore(o); return; } + + if(x.n_slices <= 3) + { + for(uword slice=0; slice < x.n_slices; ++slice) + { + const Mat<eT> tmp(const_cast<eT*>(x.slice_memptr(slice)), x.n_rows, x.n_cols, false); + + o << "[cube slice: " << slice << ']' << '\n'; + arma_ostream::brief_print(o, tmp, false); + + if((slice+1) < x.n_slices) { o << '\n'; } + } + } + else + { + for(uword slice=0; slice <= 1; ++slice) + { + const Mat<eT> tmp(const_cast<eT*>(x.slice_memptr(slice)), x.n_rows, x.n_cols, false); + + o << "[cube slice: " << slice << ']' << '\n'; + arma_ostream::brief_print(o, tmp, false); + o << '\n'; + } + + o << "[cube slice: ...]\n\n"; + + const uword slice = x.n_slices-1; + { + const Mat<eT> tmp(const_cast<eT*>(x.slice_memptr(slice)), x.n_rows, x.n_cols, false); + + o << "[cube slice: " << slice << ']' << '\n'; + arma_ostream::brief_print(o, tmp, false); + } + } + + stream_state.restore(o); + } + + + +template<typename eT> +inline +void +arma_ostream::brief_print(std::ostream& o, const SpMat<eT>& m) + { + arma_extra_debug_sigprint(); + + if(m.n_nonzero <= 10) { arma_ostream::print(o, m, true); return; } + + 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); + + const uword m_n_nonzero = m.n_nonzero; + const double density = (m.n_elem > 0) ? (double(m_n_nonzero) / double(m.n_elem) * double(100)) : double(0); + + o << "[matrix size: " << m.n_rows << 'x' << m.n_cols << "; n_nonzero: " << m_n_nonzero; + + if(density == double(0)) + { + o.precision(0); + } + else + if(density >= (double(10.0)-std::numeric_limits<double>::epsilon())) + { + o.precision(1); + } + else + if(density > (double(0.01)-std::numeric_limits<double>::epsilon())) + { + o.precision(2); + } + else + if(density > (double(0.001)-std::numeric_limits<double>::epsilon())) + { + o.precision(3); + } + else + if(density > (double(0.0001)-std::numeric_limits<double>::epsilon())) + { + o.precision(4); + } + else + { + o.unsetf(ios::fixed); + o.setf(ios::scientific); + o.precision(2); + } + + o << "; density: " << density << "%]\n\n"; + + // get the first 9 elements and the last element + + typename SpMat<eT>::const_iterator it = m.begin(); + typename SpMat<eT>::const_iterator it_end = m.end(); + + uvec storage_row(10); + uvec storage_col(10); + Col<eT> storage_val(10); + + uword count = 0; + + while( (it != it_end) && (count < 9) ) + { + storage_row(count) = it.row(); + storage_col(count) = it.col(); + storage_val(count) = (*it); + + ++it; + ++count; + } + + it = it_end; + --it; + + storage_row(count) = it.row(); + storage_col(count) = it.col(); + storage_val(count) = (*it); + + const std::streamsize cell_width = arma_ostream::modify_stream(o, storage_val.memptr(), 10); + + for(uword i=0; i < 9; ++i) + { + const uword row = storage_row(i); + const uword col = storage_col(i); + + if(row < 10) { o << " "; } + else if(row < 100) { o << " "; } + else if(row < 1000) { o << " "; } + else if(row < 10000) { o << " "; } + else if(row < 100000) { o << " "; } + else if(row < 1000000) { o << ' '; } + + 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 << " "; } + else if(col < 1000000) { o << ' '; } + + if(cell_width > 0) { o.width(cell_width); } + + arma_ostream::print_elem(o, storage_val(i), true); + o << '\n'; + } + + o << " (:, :) "; + if(cell_width > 0) { o.width(cell_width); } + o << "...\n"; + + + const uword i = 9; + { + const uword row = storage_row(i); + const uword col = storage_col(i); + + if(row < 10) { o << " "; } + else if(row < 100) { o << " "; } + else if(row < 1000) { o << " "; } + else if(row < 10000) { o << " "; } + else if(row < 100000) { o << " "; } + else if(row < 1000000) { o << ' '; } + + 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 << " "; } + else if(col < 1000000) { o << ' '; } + + if(cell_width > 0) { o.width(cell_width); } + + arma_ostream::print_elem(o, storage_val(i), true); + o << '\n'; + } + + o.flush(); + stream_state.restore(o); + } + + + +//! @} |