![]() |
Eigen
3.3.3
|
00001 // This file is part of Eigen, a lightweight C++ template library 00002 // for linear algebra. 00003 // 00004 // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> 00005 // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> 00006 // 00007 // This Source Code Form is subject to the terms of the Mozilla 00008 // Public License v. 2.0. If a copy of the MPL was not distributed 00009 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 00010 00011 #ifndef EIGEN_IO_H 00012 #define EIGEN_IO_H 00013 00014 namespace Eigen { 00015 00016 enum { DontAlignCols = 1 }; 00017 enum { StreamPrecision = -1, 00018 FullPrecision = -2 }; 00019 00020 namespace internal { 00021 template<typename Derived> 00022 std::ostream & print_matrix(std::ostream & s, const Derived& _m, const IOFormat& fmt); 00023 } 00024 00050 struct IOFormat 00051 { 00053 IOFormat(int _precision = StreamPrecision, int _flags = 0, 00054 const std::string& _coeffSeparator = " ", 00055 const std::string& _rowSeparator = "\n", const std::string& _rowPrefix="", const std::string& _rowSuffix="", 00056 const std::string& _matPrefix="", const std::string& _matSuffix="") 00057 : matPrefix(_matPrefix), matSuffix(_matSuffix), rowPrefix(_rowPrefix), rowSuffix(_rowSuffix), rowSeparator(_rowSeparator), 00058 rowSpacer(""), coeffSeparator(_coeffSeparator), precision(_precision), flags(_flags) 00059 { 00060 // TODO check if rowPrefix, rowSuffix or rowSeparator contains a newline 00061 // don't add rowSpacer if columns are not to be aligned 00062 if((flags & DontAlignCols)) 00063 return; 00064 int i = int(matSuffix.length())-1; 00065 while (i>=0 && matSuffix[i]!='\n') 00066 { 00067 rowSpacer += ' '; 00068 i--; 00069 } 00070 } 00071 std::string matPrefix, matSuffix; 00072 std::string rowPrefix, rowSuffix, rowSeparator, rowSpacer; 00073 std::string coeffSeparator; 00074 int precision; 00075 int flags; 00076 }; 00077 00093 template<typename ExpressionType> 00094 class WithFormat 00095 { 00096 public: 00097 00098 WithFormat(const ExpressionType& matrix, const IOFormat& format) 00099 : m_matrix(matrix), m_format(format) 00100 {} 00101 00102 friend std::ostream & operator << (std::ostream & s, const WithFormat& wf) 00103 { 00104 return internal::print_matrix(s, wf.m_matrix.eval(), wf.m_format); 00105 } 00106 00107 protected: 00108 typename ExpressionType::Nested m_matrix; 00109 IOFormat m_format; 00110 }; 00111 00112 namespace internal { 00113 00114 // NOTE: This helper is kept for backward compatibility with previous code specializing 00115 // this internal::significant_decimals_impl structure. In the future we should directly 00116 // call digits10() which has been introduced in July 2016 in 3.3. 00117 template<typename Scalar> 00118 struct significant_decimals_impl 00119 { 00120 static inline int run() 00121 { 00122 return NumTraits<Scalar>::digits10(); 00123 } 00124 }; 00125 00128 template<typename Derived> 00129 std::ostream & print_matrix(std::ostream & s, const Derived& _m, const IOFormat& fmt) 00130 { 00131 if(_m.size() == 0) 00132 { 00133 s << fmt.matPrefix << fmt.matSuffix; 00134 return s; 00135 } 00136 00137 typename Derived::Nested m = _m; 00138 typedef typename Derived::Scalar Scalar; 00139 00140 Index width = 0; 00141 00142 std::streamsize explicit_precision; 00143 if(fmt.precision == StreamPrecision) 00144 { 00145 explicit_precision = 0; 00146 } 00147 else if(fmt.precision == FullPrecision) 00148 { 00149 if (NumTraits<Scalar>::IsInteger) 00150 { 00151 explicit_precision = 0; 00152 } 00153 else 00154 { 00155 explicit_precision = significant_decimals_impl<Scalar>::run(); 00156 } 00157 } 00158 else 00159 { 00160 explicit_precision = fmt.precision; 00161 } 00162 00163 std::streamsize old_precision = 0; 00164 if(explicit_precision) old_precision = s.precision(explicit_precision); 00165 00166 bool align_cols = !(fmt.flags & DontAlignCols); 00167 if(align_cols) 00168 { 00169 // compute the largest width 00170 for(Index j = 0; j < m.cols(); ++j) 00171 for(Index i = 0; i < m.rows(); ++i) 00172 { 00173 std::stringstream sstr; 00174 sstr.copyfmt(s); 00175 sstr << m.coeff(i,j); 00176 width = std::max<Index>(width, Index(sstr.str().length())); 00177 } 00178 } 00179 s << fmt.matPrefix; 00180 for(Index i = 0; i < m.rows(); ++i) 00181 { 00182 if (i) 00183 s << fmt.rowSpacer; 00184 s << fmt.rowPrefix; 00185 if(width) s.width(width); 00186 s << m.coeff(i, 0); 00187 for(Index j = 1; j < m.cols(); ++j) 00188 { 00189 s << fmt.coeffSeparator; 00190 if (width) s.width(width); 00191 s << m.coeff(i, j); 00192 } 00193 s << fmt.rowSuffix; 00194 if( i < m.rows() - 1) 00195 s << fmt.rowSeparator; 00196 } 00197 s << fmt.matSuffix; 00198 if(explicit_precision) s.precision(old_precision); 00199 return s; 00200 } 00201 00202 } // end namespace internal 00203 00215 template<typename Derived> 00216 std::ostream & operator << 00217 (std::ostream & s, 00218 const DenseBase<Derived> & m) 00219 { 00220 return internal::print_matrix(s, m.eval(), EIGEN_DEFAULT_IO_FORMAT); 00221 } 00222 00223 } // end namespace Eigen 00224 00225 #endif // EIGEN_IO_H