cart-elc

Source code for CART-ELC
git clone git://git.laack.co/cart-elc.git
Log | Files | Refs | README | LICENSE

IO.h (8238B)


      1 // This file is part of Eigen, a lightweight C++ template library
      2 // for linear algebra.
      3 //
      4 // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
      5 // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
      6 //
      7 // This Source Code Form is subject to the terms of the Mozilla
      8 // Public License v. 2.0. If a copy of the MPL was not distributed
      9 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
     10 
     11 #ifndef EIGEN_IO_H
     12 #define EIGEN_IO_H
     13 
     14 namespace Eigen { 
     15 
     16 enum { DontAlignCols = 1 };
     17 enum { StreamPrecision = -1,
     18        FullPrecision = -2 };
     19 
     20 namespace internal {
     21 template<typename Derived>
     22 std::ostream & print_matrix(std::ostream & s, const Derived& _m, const IOFormat& fmt);
     23 }
     24 
     25 /** \class IOFormat
     26   * \ingroup Core_Module
     27   *
     28   * \brief Stores a set of parameters controlling the way matrices are printed
     29   *
     30   * List of available parameters:
     31   *  - \b precision number of digits for floating point values, or one of the special constants \c StreamPrecision and \c FullPrecision.
     32   *                 The default is the special value \c StreamPrecision which means to use the
     33   *                 stream's own precision setting, as set for instance using \c cout.precision(3). The other special value
     34   *                 \c FullPrecision means that the number of digits will be computed to match the full precision of each floating-point
     35   *                 type.
     36   *  - \b flags an OR-ed combination of flags, the default value is 0, the only currently available flag is \c DontAlignCols which
     37   *             allows to disable the alignment of columns, resulting in faster code.
     38   *  - \b coeffSeparator string printed between two coefficients of the same row
     39   *  - \b rowSeparator string printed between two rows
     40   *  - \b rowPrefix string printed at the beginning of each row
     41   *  - \b rowSuffix string printed at the end of each row
     42   *  - \b matPrefix string printed at the beginning of the matrix
     43   *  - \b matSuffix string printed at the end of the matrix
     44   *  - \b fill character printed to fill the empty space in aligned columns
     45   *
     46   * Example: \include IOFormat.cpp
     47   * Output: \verbinclude IOFormat.out
     48   *
     49   * \sa DenseBase::format(), class WithFormat
     50   */
     51 struct IOFormat
     52 {
     53   /** Default constructor, see class IOFormat for the meaning of the parameters */
     54   IOFormat(int _precision = StreamPrecision, int _flags = 0,
     55     const std::string& _coeffSeparator = " ",
     56     const std::string& _rowSeparator = "\n", const std::string& _rowPrefix="", const std::string& _rowSuffix="",
     57     const std::string& _matPrefix="", const std::string& _matSuffix="", const char _fill=' ')
     58   : matPrefix(_matPrefix), matSuffix(_matSuffix), rowPrefix(_rowPrefix), rowSuffix(_rowSuffix), rowSeparator(_rowSeparator),
     59     rowSpacer(""), coeffSeparator(_coeffSeparator), fill(_fill), precision(_precision), flags(_flags)
     60   {
     61     // TODO check if rowPrefix, rowSuffix or rowSeparator contains a newline
     62     // don't add rowSpacer if columns are not to be aligned
     63     if((flags & DontAlignCols))
     64       return;
     65     int i = int(matSuffix.length())-1;
     66     while (i>=0 && matSuffix[i]!='\n')
     67     {
     68       rowSpacer += ' ';
     69       i--;
     70     }
     71   }
     72   std::string matPrefix, matSuffix;
     73   std::string rowPrefix, rowSuffix, rowSeparator, rowSpacer;
     74   std::string coeffSeparator;
     75   char fill;
     76   int precision;
     77   int flags;
     78 };
     79 
     80 /** \class WithFormat
     81   * \ingroup Core_Module
     82   *
     83   * \brief Pseudo expression providing matrix output with given format
     84   *
     85   * \tparam ExpressionType the type of the object on which IO stream operations are performed
     86   *
     87   * This class represents an expression with stream operators controlled by a given IOFormat.
     88   * It is the return type of DenseBase::format()
     89   * and most of the time this is the only way it is used.
     90   *
     91   * See class IOFormat for some examples.
     92   *
     93   * \sa DenseBase::format(), class IOFormat
     94   */
     95 template<typename ExpressionType>
     96 class WithFormat
     97 {
     98   public:
     99 
    100     WithFormat(const ExpressionType& matrix, const IOFormat& format)
    101       : m_matrix(matrix), m_format(format)
    102     {}
    103 
    104     friend std::ostream & operator << (std::ostream & s, const WithFormat& wf)
    105     {
    106       return internal::print_matrix(s, wf.m_matrix.eval(), wf.m_format);
    107     }
    108 
    109   protected:
    110     typename ExpressionType::Nested m_matrix;
    111     IOFormat m_format;
    112 };
    113 
    114 namespace internal {
    115 
    116 // NOTE: This helper is kept for backward compatibility with previous code specializing
    117 //       this internal::significant_decimals_impl structure. In the future we should directly
    118 //       call digits10() which has been introduced in July 2016 in 3.3.
    119 template<typename Scalar>
    120 struct significant_decimals_impl
    121 {
    122   static inline int run()
    123   {
    124     return NumTraits<Scalar>::digits10();
    125   }
    126 };
    127 
    128 /** \internal
    129   * print the matrix \a _m to the output stream \a s using the output format \a fmt */
    130 template<typename Derived>
    131 std::ostream & print_matrix(std::ostream & s, const Derived& _m, const IOFormat& fmt)
    132 {
    133   using internal::is_same;
    134   using internal::conditional;
    135 
    136   if(_m.size() == 0)
    137   {
    138     s << fmt.matPrefix << fmt.matSuffix;
    139     return s;
    140   }
    141   
    142   typename Derived::Nested m = _m;
    143   typedef typename Derived::Scalar Scalar;
    144   typedef typename
    145       conditional<
    146           is_same<Scalar, char>::value ||
    147             is_same<Scalar, unsigned char>::value ||
    148             is_same<Scalar, numext::int8_t>::value ||
    149             is_same<Scalar, numext::uint8_t>::value,
    150           int,
    151           typename conditional<
    152               is_same<Scalar, std::complex<char> >::value ||
    153                 is_same<Scalar, std::complex<unsigned char> >::value ||
    154                 is_same<Scalar, std::complex<numext::int8_t> >::value ||
    155                 is_same<Scalar, std::complex<numext::uint8_t> >::value,
    156               std::complex<int>,
    157               const Scalar&
    158             >::type
    159         >::type PrintType;
    160 
    161   Index width = 0;
    162 
    163   std::streamsize explicit_precision;
    164   if(fmt.precision == StreamPrecision)
    165   {
    166     explicit_precision = 0;
    167   }
    168   else if(fmt.precision == FullPrecision)
    169   {
    170     if (NumTraits<Scalar>::IsInteger)
    171     {
    172       explicit_precision = 0;
    173     }
    174     else
    175     {
    176       explicit_precision = significant_decimals_impl<Scalar>::run();
    177     }
    178   }
    179   else
    180   {
    181     explicit_precision = fmt.precision;
    182   }
    183 
    184   std::streamsize old_precision = 0;
    185   if(explicit_precision) old_precision = s.precision(explicit_precision);
    186 
    187   bool align_cols = !(fmt.flags & DontAlignCols);
    188   if(align_cols)
    189   {
    190     // compute the largest width
    191     for(Index j = 0; j < m.cols(); ++j)
    192       for(Index i = 0; i < m.rows(); ++i)
    193       {
    194         std::stringstream sstr;
    195         sstr.copyfmt(s);
    196         sstr << static_cast<PrintType>(m.coeff(i,j));
    197         width = std::max<Index>(width, Index(sstr.str().length()));
    198       }
    199   }
    200   std::streamsize old_width = s.width();
    201   char old_fill_character = s.fill();
    202   s << fmt.matPrefix;
    203   for(Index i = 0; i < m.rows(); ++i)
    204   {
    205     if (i)
    206       s << fmt.rowSpacer;
    207     s << fmt.rowPrefix;
    208     if(width) {
    209       s.fill(fmt.fill);
    210       s.width(width);
    211     }
    212     s << static_cast<PrintType>(m.coeff(i, 0));
    213     for(Index j = 1; j < m.cols(); ++j)
    214     {
    215       s << fmt.coeffSeparator;
    216       if(width) {
    217         s.fill(fmt.fill);
    218         s.width(width);
    219       }
    220       s << static_cast<PrintType>(m.coeff(i, j));
    221     }
    222     s << fmt.rowSuffix;
    223     if( i < m.rows() - 1)
    224       s << fmt.rowSeparator;
    225   }
    226   s << fmt.matSuffix;
    227   if(explicit_precision) s.precision(old_precision);
    228   if(width) {
    229     s.fill(old_fill_character);
    230     s.width(old_width);
    231   }
    232   return s;
    233 }
    234 
    235 } // end namespace internal
    236 
    237 /** \relates DenseBase
    238   *
    239   * Outputs the matrix, to the given stream.
    240   *
    241   * If you wish to print the matrix with a format different than the default, use DenseBase::format().
    242   *
    243   * It is also possible to change the default format by defining EIGEN_DEFAULT_IO_FORMAT before including Eigen headers.
    244   * If not defined, this will automatically be defined to Eigen::IOFormat(), that is the Eigen::IOFormat with default parameters.
    245   *
    246   * \sa DenseBase::format()
    247   */
    248 template<typename Derived>
    249 std::ostream & operator <<
    250 (std::ostream & s,
    251  const DenseBase<Derived> & m)
    252 {
    253   return internal::print_matrix(s, m.eval(), EIGEN_DEFAULT_IO_FORMAT);
    254 }
    255 
    256 } // end namespace Eigen
    257 
    258 #endif // EIGEN_IO_H