* Add the possibility to customize the output of matrices, e.g.:

IoFormat OctaveFmt(4, AlignCols, ", ", ";\n", "", "", "[", "]");
   cout << mat.format(OctaveFmt);
  The first "4" is the precision.
  Documentation missing.
* Some compilation fixes
This commit is contained in:
Gael Guennebaud 2008-08-21 13:17:21 +00:00
parent 591d497b84
commit f729fc1d70
9 changed files with 144 additions and 16 deletions

View File

@ -4,6 +4,7 @@
#include "CoreDeclarations"
#include <iostream>
#include <cstring>
#include <string>
#ifdef EIGEN_VECTORIZE
// it seems we cannot assume posix_memalign is defined in the stdlib header

View File

@ -52,7 +52,7 @@ struct ei_traits<PartialReduxExpr<MatrixType, MemberOp, Direction> >
typedef typename MemberOp::result_type Scalar;
typedef typename MatrixType::Scalar InputScalar;
typedef typename ei_nested<MatrixType>::type MatrixTypeNested;
typedef typename ei_unref<MatrixTypeNested>::type _MatrixTypeNested;
typedef typename ei_cleantype<MatrixTypeNested>::type _MatrixTypeNested;
enum {
RowsAtCompileTime = Direction==Vertical ? 1 : MatrixType::RowsAtCompileTime,
ColsAtCompileTime = Direction==Horizontal ? 1 : MatrixType::ColsAtCompileTime,
@ -65,7 +65,7 @@ struct ei_traits<PartialReduxExpr<MatrixType, MemberOp, Direction> >
};
typedef typename MemberOp::template Cost<InputScalar,int(TraversalSize)> CostOpType;
enum {
CoeffReadCost = TraversalSize * _MatrixTypeNested::CoeffReadCost + CostOpType::value
CoeffReadCost = TraversalSize * ei_traits<_MatrixTypeNested>::CoeffReadCost + int(CostOpType::value)
};
};

View File

@ -347,7 +347,7 @@ static void ei_cache_friendly_product(
* TODO: since rhs gets evaluated only once, no need to evaluate it
*/
template<typename Scalar, typename RhsType>
EIGEN_DONT_INLINE static void ei_cache_friendly_product_colmajor_times_vector(
static EIGEN_DONT_INLINE void ei_cache_friendly_product_colmajor_times_vector(
int size,
const Scalar* lhs, int lhsStride,
const RhsType& rhs,
@ -536,7 +536,7 @@ EIGEN_DONT_INLINE static void ei_cache_friendly_product_colmajor_times_vector(
// TODO add peeling to mask unaligned load/stores
template<typename Scalar, typename ResType>
EIGEN_DONT_INLINE static void ei_cache_friendly_product_rowmajor_times_vector(
static EIGEN_DONT_INLINE void ei_cache_friendly_product_rowmajor_times_vector(
const Scalar* lhs, int lhsStride,
const Scalar* rhs, int rhsSize,
ResType& res)

View File

@ -25,19 +25,96 @@
#ifndef EIGEN_IO_H
#define EIGEN_IO_H
template<typename Derived>
std::ostream & ei_print_matrix
(std::ostream & s,
const MatrixBase<Derived> & m)
enum { Raw, AlignCols };
struct IoFormat
{
IoFormat(int _precision=4, int _flags=Raw,
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="")
: matPrefix(_matPrefix), matSuffix(_matSuffix), rowPrefix(_rowPrefix), rowSuffix(_rowSuffix), rowSeparator(_rowSeparator),
coeffSeparator(_coeffSeparator), precision(_precision), flags(_flags)
{
rowSpacer = "";
int i=matSuffix.length()-1;
while (i>=0 && matSuffix[i]!='\n')
{
rowSpacer += ' ';
i--;
}
}
std::string matPrefix, matSuffix;
std::string rowPrefix, rowSuffix, rowSeparator, rowSpacer;
std::string coeffSeparator;
int precision;
int flags;
};
template<typename ExpressionType>
class WithFormat
{
public:
WithFormat(const ExpressionType& matrix, const IoFormat& format)
: m_matrix(matrix), m_format(format)
{}
friend std::ostream & operator << (std::ostream & s, const WithFormat& wf)
{
return ei_print_matrix(s, wf.m_matrix.eval(), wf.m_format);
}
protected:
const typename ExpressionType::Nested m_matrix;
IoFormat m_format;
};
template<typename Derived>
inline const WithFormat<Derived>
MatrixBase<Derived>::format(const IoFormat& fmt) const
{
return WithFormat<Derived>(derived(), fmt);
}
template<typename Derived>
std::ostream & ei_print_matrix(std::ostream & s, const MatrixBase<Derived> & _m,
const IoFormat& fmt = IoFormat())
{
const typename Derived::Nested m = _m;
int width = 0;
if (fmt.flags & AlignCols)
{
// compute the largest width
for(int j = 1; j < m.cols(); j++)
for(int i = 0; i < m.rows(); i++)
{
std::stringstream sstr;
sstr.precision(fmt.precision);
sstr << m.coeff(i,j);
width = std::max<int>(width, sstr.str().length());
}
}
s.precision(fmt.precision);
s << fmt.matPrefix;
for(int i = 0; i < m.rows(); i++)
{
if (i)
s << fmt.rowSpacer;
s << fmt.rowPrefix;
if(width) s.width(width);
s << m.coeff(i, 0);
for(int j = 1; j < m.cols(); j++)
s << " " << m.coeff(i, j);
if( i < m.rows() - 1)
s << "\n";
{
s << fmt.coeffSeparator;
if (width) s.width(width);
s << m.coeff(i, j);
}
s << fmt.rowSuffix;
if( i < m.rows() - 1)
s << fmt.rowSeparator;
}
s << fmt.matSuffix;
return s;
}

View File

@ -525,6 +525,8 @@ template<typename Derived> class MatrixBase
const Cwise<Derived> cwise() const;
Cwise<Derived> cwise();
inline const WithFormat<Derived> format(const IoFormat& fmt) const;
/////////// Array module ///////////
bool all(void) const;

View File

@ -130,7 +130,7 @@ template<typename Derived>
template<typename OtherDerived>
void MatrixBase<Derived>::swap(const MatrixBase<OtherDerived>& other)
{
SwapWrapper<Derived>(derived()).lazyAssign(other);
(SwapWrapper<Derived>(derived())).lazyAssign(other);
}
#endif // EIGEN_SWAP_H

View File

@ -59,6 +59,7 @@ template<typename MatrixType, unsigned int Mode> class Extract;
template<typename ExpressionType> class Cwise;
template<typename ExpressionType, int Direction> class PartialRedux;
template<typename MatrixType, typename BinaryOp, int Direction> class PartialReduxExpr;
template<typename ExpressionType> class WithFormat;
template<typename Lhs, typename Rhs> struct ei_product_mode;
template<typename Lhs, typename Rhs, int ProductMode = ei_product_mode<Lhs,Rhs>::value> struct ProductReturnType;
@ -89,6 +90,8 @@ template<typename Scalar> struct ei_scalar_max_op;
template<typename Scalar> struct ei_scalar_random_op;
template<typename Scalar> struct ei_scalar_add_op;
struct IoFormat;
template<typename Scalar>
void ei_cache_friendly_product(
int _rows, int _cols, int depth,

View File

@ -110,5 +110,6 @@ EI_ADD_TEST(eigensolver)
EI_ADD_TEST(geometry)
EI_ADD_TEST(regression)
EI_ADD_TEST(svd)
EI_ADD_TEST(ioformat)
ENDIF(BUILD_TESTS)

44
test/ioformat.cpp Normal file
View File

@ -0,0 +1,44 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra. Eigen itself is part of the KDE project.
//
// Copyright (C) 2006-2008 Benoit Jacob <jacob@math.jussieu.fr>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#include "main.h"
void test_ioformat()
{
std::string sep = "\n\n----------------------------------------\n\n";
Matrix4f m1;
m1 << 0, 1.111111, 2, 3.33333, 4, 5, 6, 7, 8.888888, 9, 10, 11, 12, 13, 14, 15;
IoFormat CommaInitFmt(4, Raw, ", ", ", ", "", "", " << ", ";");
IoFormat CleanFmt(4, AlignCols, ", ", "\n", "[", "]");
IoFormat OctaveFmt(4, AlignCols, ", ", ";\n", "", "", "[", "]");
IoFormat HeavyFmt(4, AlignCols, ", ", ";\n", "[", "]", "[", "]");
std::cout << m1 << sep;
std::cout << m1.format(CommaInitFmt) << sep;
std::cout << m1.format(CleanFmt) << sep;
std::cout << m1.format(OctaveFmt) << sep;
std::cout << m1.format(HeavyFmt) << sep;
}