$treeview $search $mathjax
Eigen
3.2.5
$projectbrief
|
$projectbrief
|
$searchbox |
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 int i = int(matSuffix.length())-1; 00061 while (i>=0 && matSuffix[i]!='\n') 00062 { 00063 rowSpacer += ' '; 00064 i--; 00065 } 00066 } 00067 std::string matPrefix, matSuffix; 00068 std::string rowPrefix, rowSuffix, rowSeparator, rowSpacer; 00069 std::string coeffSeparator; 00070 int precision; 00071 int flags; 00072 }; 00073 00089 template<typename ExpressionType> 00090 class WithFormat 00091 { 00092 public: 00093 00094 WithFormat(const ExpressionType& matrix, const IOFormat& format) 00095 : m_matrix(matrix), m_format(format) 00096 {} 00097 00098 friend std::ostream & operator << (std::ostream & s, const WithFormat& wf) 00099 { 00100 return internal::print_matrix(s, wf.m_matrix.eval(), wf.m_format); 00101 } 00102 00103 protected: 00104 const typename ExpressionType::Nested m_matrix; 00105 IOFormat m_format; 00106 }; 00107 00115 template<typename Derived> 00116 inline const WithFormat<Derived> 00117 DenseBase<Derived>::format(const IOFormat& fmt) const 00118 { 00119 return WithFormat<Derived>(derived(), fmt); 00120 } 00121 00122 namespace internal { 00123 00124 template<typename Scalar, bool IsInteger> 00125 struct significant_decimals_default_impl 00126 { 00127 typedef typename NumTraits<Scalar>::Real RealScalar; 00128 static inline int run() 00129 { 00130 using std::ceil; 00131 using std::log; 00132 return cast<RealScalar,int>(ceil(-log(NumTraits<RealScalar>::epsilon())/log(RealScalar(10)))); 00133 } 00134 }; 00135 00136 template<typename Scalar> 00137 struct significant_decimals_default_impl<Scalar, true> 00138 { 00139 static inline int run() 00140 { 00141 return 0; 00142 } 00143 }; 00144 00145 template<typename Scalar> 00146 struct significant_decimals_impl 00147 : significant_decimals_default_impl<Scalar, NumTraits<Scalar>::IsInteger> 00148 {}; 00149 00152 template<typename Derived> 00153 std::ostream & print_matrix(std::ostream & s, const Derived& _m, const IOFormat& fmt) 00154 { 00155 if(_m.size() == 0) 00156 { 00157 s << fmt.matPrefix << fmt.matSuffix; 00158 return s; 00159 } 00160 00161 typename Derived::Nested m = _m; 00162 typedef typename Derived::Scalar Scalar; 00163 typedef typename Derived::Index Index; 00164 00165 Index width = 0; 00166 00167 std::streamsize explicit_precision; 00168 if(fmt.precision == StreamPrecision) 00169 { 00170 explicit_precision = 0; 00171 } 00172 else if(fmt.precision == FullPrecision) 00173 { 00174 if (NumTraits<Scalar>::IsInteger) 00175 { 00176 explicit_precision = 0; 00177 } 00178 else 00179 { 00180 explicit_precision = significant_decimals_impl<Scalar>::run(); 00181 } 00182 } 00183 else 00184 { 00185 explicit_precision = fmt.precision; 00186 } 00187 00188 std::streamsize old_precision = 0; 00189 if(explicit_precision) old_precision = s.precision(explicit_precision); 00190 00191 bool align_cols = !(fmt.flags & DontAlignCols); 00192 if(align_cols) 00193 { 00194 // compute the largest width 00195 for(Index j = 0; j < m.cols(); ++j) 00196 for(Index i = 0; i < m.rows(); ++i) 00197 { 00198 std::stringstream sstr; 00199 sstr.copyfmt(s); 00200 sstr << m.coeff(i,j); 00201 width = std::max<Index>(width, Index(sstr.str().length())); 00202 } 00203 } 00204 s << fmt.matPrefix; 00205 for(Index i = 0; i < m.rows(); ++i) 00206 { 00207 if (i) 00208 s << fmt.rowSpacer; 00209 s << fmt.rowPrefix; 00210 if(width) s.width(width); 00211 s << m.coeff(i, 0); 00212 for(Index j = 1; j < m.cols(); ++j) 00213 { 00214 s << fmt.coeffSeparator; 00215 if (width) s.width(width); 00216 s << m.coeff(i, j); 00217 } 00218 s << fmt.rowSuffix; 00219 if( i < m.rows() - 1) 00220 s << fmt.rowSeparator; 00221 } 00222 s << fmt.matSuffix; 00223 if(explicit_precision) s.precision(old_precision); 00224 return s; 00225 } 00226 00227 } // end namespace internal 00228 00240 template<typename Derived> 00241 std::ostream & operator << 00242 (std::ostream & s, 00243 const DenseBase<Derived> & m) 00244 { 00245 return internal::print_matrix(s, m.eval(), EIGEN_DEFAULT_IO_FORMAT); 00246 } 00247 00248 } // end namespace Eigen 00249 00250 #endif // EIGEN_IO_H