From 2f74801ca4b1cd82cd95cd98ab1ee0857efdcac2 Mon Sep 17 00:00:00 2001 From: Benoit Jacob Date: Fri, 14 Aug 2009 16:31:42 -0400 Subject: [PATCH] as discussed on list: default to align cols, reorganize parameters accordingly so that the default corresponds to 0 flag, and implement FullPrecision output (non-default). --- Eigen/src/Core/IO.h | 44 +++++++++++++++++++++++++++------- Eigen/src/Core/MathFunctions.h | 2 +- 2 files changed, 36 insertions(+), 10 deletions(-) diff --git a/Eigen/src/Core/IO.h b/Eigen/src/Core/IO.h index 53e02412f..03e1af17d 100644 --- a/Eigen/src/Core/IO.h +++ b/Eigen/src/Core/IO.h @@ -26,15 +26,22 @@ #ifndef EIGEN_IO_H #define EIGEN_IO_H -enum { Raw, AlignCols }; +enum { DontAlignCols = 1 }; +enum { StreamPrecision = -1, + FullPrecision = -2 }; /** \class IOFormat * * \brief Stores a set of parameters controlling the way matrices are printed * * List of available parameters: - * - \b precision number of digits for floating point values. The default value -1 means that the current stream precision is used. - * - \b flags can be either Raw (default) or AlignCols which aligns all the columns + * - \b precision number of digits for floating point values, or one of the special constants \c StreamPrecision and \c FullPrecision. + * The default is the special value \c StreamPrecision which means to use the + * stream's own precision setting, as set for instance using \c cout.precision(3). The other special value + * \c FullPrecision means that the number of digits will be computed to match the full precision of each floating-point + * type. + * - \b flags an OR-ed combination of flags, the default value is 0, the only currently available flag is \c DontAlignCols which + * allows to disable the alignment of columns, resulting in faster code. * - \b coeffSeparator string printed between two coefficients of the same row * - \b rowSeparator string printed between two rows * - \b rowPrefix string printed at the beginning of each row @@ -50,7 +57,7 @@ enum { Raw, AlignCols }; struct IOFormat { /** Default contructor, see class IOFormat for the meaning of the parameters */ - IOFormat(int _precision=-1, int _flags=Raw, + IOFormat(int _precision = StreamPrecision, int _flags = 0, const std::string& _coeffSeparator = " ", const std::string& _rowSeparator = "\n", const std::string& _rowPrefix="", const std::string& _rowSuffix="", const std::string& _matPrefix="", const std::string& _matSuffix="") @@ -125,22 +132,41 @@ template std::ostream & ei_print_matrix(std::ostream & s, const Derived& _m, const IOFormat& fmt) { const typename Derived::Nested m = _m; - + typedef typename Derived::Scalar Scalar; + int width = 0; - if (fmt.flags & AlignCols) + + std::streamsize explicit_precision; + if(fmt.precision == StreamPrecision) + { + explicit_precision = 0; + } + else if(fmt.precision == FullPrecision) + { + explicit_precision = NumTraits::HasFloatingPoint + ? std::ceil(-ei_log(epsilon())/ei_log(10.0)) + : 0; + } + else + { + explicit_precision = fmt.precision; + } + + bool align_cols = !(fmt.flags & DontAlignCols); + if(align_cols) { // compute the largest width for(int j = 1; j < m.cols(); ++j) for(int i = 0; i < m.rows(); ++i) { std::stringstream sstr; - if(fmt.precision != -1) sstr.precision(fmt.precision); + if(explicit_precision) sstr.precision(explicit_precision); sstr << m.coeff(i,j); width = std::max(width, int(sstr.str().length())); } } std::streamsize old_precision; - if(fmt.precision != -1) old_precision = s.precision(fmt.precision); + if(explicit_precision) old_precision = s.precision(explicit_precision); s << fmt.matPrefix; for(int i = 0; i < m.rows(); ++i) { @@ -160,7 +186,7 @@ std::ostream & ei_print_matrix(std::ostream & s, const Derived& _m, const IOForm s << fmt.rowSeparator; } s << fmt.matSuffix; - if(fmt.precision != -1) s.precision(old_precision); + if(explicit_precision) s.precision(old_precision); return s; } diff --git a/Eigen/src/Core/MathFunctions.h b/Eigen/src/Core/MathFunctions.h index 16091caf0..1570f01e0 100644 --- a/Eigen/src/Core/MathFunctions.h +++ b/Eigen/src/Core/MathFunctions.h @@ -25,7 +25,7 @@ #ifndef EIGEN_MATHFUNCTIONS_H #define EIGEN_MATHFUNCTIONS_H -template typename NumTraits::Real epsilon() +template inline typename NumTraits::Real epsilon() { return std::numeric_limits::Real>::epsilon(); }