aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Gael Guennebaud <g.gael@free.fr>2008-08-21 13:17:21 +0000
committerGravatar Gael Guennebaud <g.gael@free.fr>2008-08-21 13:17:21 +0000
commitf729fc1d70e69d547bd5bd48678823dd9580bb7e (patch)
tree8bda3fea98536ed0a0ae7f8597eadd3c01175e3b
parent591d497b848844dbae9ac3f38ad2d45241a05470 (diff)
* 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
-rw-r--r--Eigen/Core1
-rw-r--r--Eigen/src/Array/PartialRedux.h4
-rw-r--r--Eigen/src/Core/CacheFriendlyProduct.h4
-rw-r--r--Eigen/src/Core/IO.h87
-rw-r--r--Eigen/src/Core/MatrixBase.h12
-rw-r--r--Eigen/src/Core/Swap.h2
-rw-r--r--Eigen/src/Core/util/ForwardDeclarations.h3
-rw-r--r--test/CMakeLists.txt1
-rw-r--r--test/ioformat.cpp44
9 files changed, 143 insertions, 15 deletions
diff --git a/Eigen/Core b/Eigen/Core
index 0cb89bb60..102f23229 100644
--- a/Eigen/Core
+++ b/Eigen/Core
@@ -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
diff --git a/Eigen/src/Array/PartialRedux.h b/Eigen/src/Array/PartialRedux.h
index e34766aa8..265f206aa 100644
--- a/Eigen/src/Array/PartialRedux.h
+++ b/Eigen/src/Array/PartialRedux.h
@@ -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)
};
};
diff --git a/Eigen/src/Core/CacheFriendlyProduct.h b/Eigen/src/Core/CacheFriendlyProduct.h
index 320ec8992..a4cce99bf 100644
--- a/Eigen/src/Core/CacheFriendlyProduct.h
+++ b/Eigen/src/Core/CacheFriendlyProduct.h
@@ -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)
diff --git a/Eigen/src/Core/IO.h b/Eigen/src/Core/IO.h
index 705cc5605..5b503b590 100644
--- a/Eigen/src/Core/IO.h
+++ b/Eigen/src/Core/IO.h
@@ -25,19 +25,96 @@
#ifndef EIGEN_IO_H
#define EIGEN_IO_H
+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>
-std::ostream & ei_print_matrix
-(std::ostream & s,
- const MatrixBase<Derived> & m)
+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);
+ {
+ s << fmt.coeffSeparator;
+ if (width) s.width(width);
+ s << m.coeff(i, j);
+ }
+ s << fmt.rowSuffix;
if( i < m.rows() - 1)
- s << "\n";
+ s << fmt.rowSeparator;
}
+ s << fmt.matSuffix;
return s;
}
diff --git a/Eigen/src/Core/MatrixBase.h b/Eigen/src/Core/MatrixBase.h
index de31621ce..a60ae3ff5 100644
--- a/Eigen/src/Core/MatrixBase.h
+++ b/Eigen/src/Core/MatrixBase.h
@@ -176,7 +176,7 @@ template<typename Derived> class MatrixBase
int innerSize() const { return (int(Flags)&RowMajorBit) ? this->cols() : this->rows(); }
/** \internal the type to which the expression gets evaluated (needed by MSVC) */
- typedef typename ei_eval<Derived>::type EvalType;
+ typedef typename ei_eval<Derived>::type EvalType;
/** \internal Represents a constant matrix */
typedef CwiseNullaryOp<ei_scalar_constant_op<Scalar>,Derived> ConstantReturnType;
/** \internal Represents a scalar multiple of a matrix */
@@ -195,10 +195,10 @@ template<typename Derived> class MatrixBase
AdjointReturnType;
/** \internal the return type of MatrixBase::eigenvalues() */
typedef Matrix<typename NumTraits<typename ei_traits<Derived>::Scalar>::Real, ei_traits<Derived>::ColsAtCompileTime, 1> EigenvaluesReturnType;
- /** \internal expression tyepe of a column */
- typedef Block<Derived, ei_traits<Derived>::RowsAtCompileTime, 1> ColXpr;
- /** \internal expression tyepe of a column */
- typedef Block<Derived, 1, ei_traits<Derived>::ColsAtCompileTime> RowXpr;
+ /** \internal expression tyepe of a column */
+ typedef Block<Derived, ei_traits<Derived>::RowsAtCompileTime, 1> ColXpr;
+ /** \internal expression tyepe of a column */
+ typedef Block<Derived, 1, ei_traits<Derived>::ColsAtCompileTime> RowXpr;
/** \internal the return type of identity */
typedef CwiseNullaryOp<ei_scalar_identity_op<Scalar>,Derived> IdentityReturnType;
/** \internal the return type of unit vectors */
@@ -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;
diff --git a/Eigen/src/Core/Swap.h b/Eigen/src/Core/Swap.h
index 31e8170f5..835fa61b2 100644
--- a/Eigen/src/Core/Swap.h
+++ b/Eigen/src/Core/Swap.h
@@ -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
diff --git a/Eigen/src/Core/util/ForwardDeclarations.h b/Eigen/src/Core/util/ForwardDeclarations.h
index 694aa245d..459b2bd82 100644
--- a/Eigen/src/Core/util/ForwardDeclarations.h
+++ b/Eigen/src/Core/util/ForwardDeclarations.h
@@ -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,
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 917715eb0..e0f6f2664 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -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)
diff --git a/test/ioformat.cpp b/test/ioformat.cpp
new file mode 100644
index 000000000..74b1bd583
--- /dev/null
+++ b/test/ioformat.cpp
@@ -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;
+}