MOAB
4.9.3pre
|
00001 // This file is part of Eigen, a lightweight C++ template library 00002 // for linear algebra. 00003 // 00004 // Copyright (C) 2006-2008 Benoit Jacob <[email protected]> 00005 // Copyright (C) 2008 Gael Guennebaud <[email protected]> 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 const typename ExpressionType::Nested m_matrix; 00109 IOFormat m_format; 00110 }; 00111 00119 template<typename Derived> 00120 inline const WithFormat<Derived> 00121 DenseBase<Derived>::format(const IOFormat& fmt) const 00122 { 00123 return WithFormat<Derived>(derived(), fmt); 00124 } 00125 00126 namespace internal { 00127 00128 template<typename Scalar, bool IsInteger> 00129 struct significant_decimals_default_impl 00130 { 00131 typedef typename NumTraits<Scalar>::Real RealScalar; 00132 static inline int run() 00133 { 00134 using std::ceil; 00135 using std::log; 00136 return cast<RealScalar,int>(ceil(-log(NumTraits<RealScalar>::epsilon())/log(RealScalar(10)))); 00137 } 00138 }; 00139 00140 template<typename Scalar> 00141 struct significant_decimals_default_impl<Scalar, true> 00142 { 00143 static inline int run() 00144 { 00145 return 0; 00146 } 00147 }; 00148 00149 template<typename Scalar> 00150 struct significant_decimals_impl 00151 : significant_decimals_default_impl<Scalar, NumTraits<Scalar>::IsInteger> 00152 {}; 00153 00156 template<typename Derived> 00157 std::ostream & print_matrix(std::ostream & s, const Derived& _m, const IOFormat& fmt) 00158 { 00159 if(_m.size() == 0) 00160 { 00161 s << fmt.matPrefix << fmt.matSuffix; 00162 return s; 00163 } 00164 00165 typename Derived::Nested m = _m; 00166 typedef typename Derived::Scalar Scalar; 00167 00168 Index width = 0; 00169 00170 std::streamsize explicit_precision; 00171 if(fmt.precision == StreamPrecision) 00172 { 00173 explicit_precision = 0; 00174 } 00175 else if(fmt.precision == FullPrecision) 00176 { 00177 if (NumTraits<Scalar>::IsInteger) 00178 { 00179 explicit_precision = 0; 00180 } 00181 else 00182 { 00183 explicit_precision = significant_decimals_impl<Scalar>::run(); 00184 } 00185 } 00186 else 00187 { 00188 explicit_precision = fmt.precision; 00189 } 00190 00191 std::streamsize old_precision = 0; 00192 if(explicit_precision) old_precision = s.precision(explicit_precision); 00193 00194 bool align_cols = !(fmt.flags & DontAlignCols); 00195 if(align_cols) 00196 { 00197 // compute the largest width 00198 for(Index j = 0; j < m.cols(); ++j) 00199 for(Index i = 0; i < m.rows(); ++i) 00200 { 00201 std::stringstream sstr; 00202 sstr.copyfmt(s); 00203 sstr << m.coeff(i,j); 00204 width = std::max<Index>(width, Index(sstr.str().length())); 00205 } 00206 } 00207 s << fmt.matPrefix; 00208 for(Index i = 0; i < m.rows(); ++i) 00209 { 00210 if (i) 00211 s << fmt.rowSpacer; 00212 s << fmt.rowPrefix; 00213 if(width) s.width(width); 00214 s << m.coeff(i, 0); 00215 for(Index j = 1; j < m.cols(); ++j) 00216 { 00217 s << fmt.coeffSeparator; 00218 if (width) s.width(width); 00219 s << m.coeff(i, j); 00220 } 00221 s << fmt.rowSuffix; 00222 if( i < m.rows() - 1) 00223 s << fmt.rowSeparator; 00224 } 00225 s << fmt.matSuffix; 00226 if(explicit_precision) s.precision(old_precision); 00227 return s; 00228 } 00229 00230 } // end namespace internal 00231 00243 template<typename Derived> 00244 std::ostream & operator << 00245 (std::ostream & s, 00246 const DenseBase<Derived> & m) 00247 { 00248 return internal::print_matrix(s, m.eval(), EIGEN_DEFAULT_IO_FORMAT); 00249 } 00250 00251 } // end namespace Eigen 00252 00253 #endif // EIGEN_IO_H