mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-04-22 01:29:35 +08:00
* 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:
parent
591d497b84
commit
f729fc1d70
@ -4,6 +4,7 @@
|
|||||||
#include "CoreDeclarations"
|
#include "CoreDeclarations"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#ifdef EIGEN_VECTORIZE
|
#ifdef EIGEN_VECTORIZE
|
||||||
// it seems we cannot assume posix_memalign is defined in the stdlib header
|
// it seems we cannot assume posix_memalign is defined in the stdlib header
|
||||||
|
@ -52,7 +52,7 @@ struct ei_traits<PartialReduxExpr<MatrixType, MemberOp, Direction> >
|
|||||||
typedef typename MemberOp::result_type Scalar;
|
typedef typename MemberOp::result_type Scalar;
|
||||||
typedef typename MatrixType::Scalar InputScalar;
|
typedef typename MatrixType::Scalar InputScalar;
|
||||||
typedef typename ei_nested<MatrixType>::type MatrixTypeNested;
|
typedef typename ei_nested<MatrixType>::type MatrixTypeNested;
|
||||||
typedef typename ei_unref<MatrixTypeNested>::type _MatrixTypeNested;
|
typedef typename ei_cleantype<MatrixTypeNested>::type _MatrixTypeNested;
|
||||||
enum {
|
enum {
|
||||||
RowsAtCompileTime = Direction==Vertical ? 1 : MatrixType::RowsAtCompileTime,
|
RowsAtCompileTime = Direction==Vertical ? 1 : MatrixType::RowsAtCompileTime,
|
||||||
ColsAtCompileTime = Direction==Horizontal ? 1 : MatrixType::ColsAtCompileTime,
|
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;
|
typedef typename MemberOp::template Cost<InputScalar,int(TraversalSize)> CostOpType;
|
||||||
enum {
|
enum {
|
||||||
CoeffReadCost = TraversalSize * _MatrixTypeNested::CoeffReadCost + CostOpType::value
|
CoeffReadCost = TraversalSize * ei_traits<_MatrixTypeNested>::CoeffReadCost + int(CostOpType::value)
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -347,7 +347,7 @@ static void ei_cache_friendly_product(
|
|||||||
* TODO: since rhs gets evaluated only once, no need to evaluate it
|
* TODO: since rhs gets evaluated only once, no need to evaluate it
|
||||||
*/
|
*/
|
||||||
template<typename Scalar, typename RhsType>
|
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,
|
int size,
|
||||||
const Scalar* lhs, int lhsStride,
|
const Scalar* lhs, int lhsStride,
|
||||||
const RhsType& rhs,
|
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
|
// TODO add peeling to mask unaligned load/stores
|
||||||
template<typename Scalar, typename ResType>
|
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* lhs, int lhsStride,
|
||||||
const Scalar* rhs, int rhsSize,
|
const Scalar* rhs, int rhsSize,
|
||||||
ResType& res)
|
ResType& res)
|
||||||
|
@ -25,19 +25,96 @@
|
|||||||
#ifndef EIGEN_IO_H
|
#ifndef EIGEN_IO_H
|
||||||
#define EIGEN_IO_H
|
#define EIGEN_IO_H
|
||||||
|
|
||||||
template<typename Derived>
|
enum { Raw, AlignCols };
|
||||||
std::ostream & ei_print_matrix
|
|
||||||
(std::ostream & s,
|
struct IoFormat
|
||||||
const MatrixBase<Derived> & m)
|
|
||||||
{
|
{
|
||||||
|
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++)
|
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);
|
s << m.coeff(i, 0);
|
||||||
for(int j = 1; j < m.cols(); j++)
|
for(int j = 1; j < m.cols(); j++)
|
||||||
s << " " << m.coeff(i, j);
|
{
|
||||||
if( i < m.rows() - 1)
|
s << fmt.coeffSeparator;
|
||||||
s << "\n";
|
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;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -525,6 +525,8 @@ template<typename Derived> class MatrixBase
|
|||||||
const Cwise<Derived> cwise() const;
|
const Cwise<Derived> cwise() const;
|
||||||
Cwise<Derived> cwise();
|
Cwise<Derived> cwise();
|
||||||
|
|
||||||
|
inline const WithFormat<Derived> format(const IoFormat& fmt) const;
|
||||||
|
|
||||||
/////////// Array module ///////////
|
/////////// Array module ///////////
|
||||||
|
|
||||||
bool all(void) const;
|
bool all(void) const;
|
||||||
|
@ -130,7 +130,7 @@ template<typename Derived>
|
|||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
void MatrixBase<Derived>::swap(const MatrixBase<OtherDerived>& other)
|
void MatrixBase<Derived>::swap(const MatrixBase<OtherDerived>& other)
|
||||||
{
|
{
|
||||||
SwapWrapper<Derived>(derived()).lazyAssign(other);
|
(SwapWrapper<Derived>(derived())).lazyAssign(other);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // EIGEN_SWAP_H
|
#endif // EIGEN_SWAP_H
|
||||||
|
@ -59,6 +59,7 @@ template<typename MatrixType, unsigned int Mode> class Extract;
|
|||||||
template<typename ExpressionType> class Cwise;
|
template<typename ExpressionType> class Cwise;
|
||||||
template<typename ExpressionType, int Direction> class PartialRedux;
|
template<typename ExpressionType, int Direction> class PartialRedux;
|
||||||
template<typename MatrixType, typename BinaryOp, int Direction> class PartialReduxExpr;
|
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> struct ei_product_mode;
|
||||||
template<typename Lhs, typename Rhs, int ProductMode = ei_product_mode<Lhs,Rhs>::value> struct ProductReturnType;
|
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_random_op;
|
||||||
template<typename Scalar> struct ei_scalar_add_op;
|
template<typename Scalar> struct ei_scalar_add_op;
|
||||||
|
|
||||||
|
struct IoFormat;
|
||||||
|
|
||||||
template<typename Scalar>
|
template<typename Scalar>
|
||||||
void ei_cache_friendly_product(
|
void ei_cache_friendly_product(
|
||||||
int _rows, int _cols, int depth,
|
int _rows, int _cols, int depth,
|
||||||
|
@ -110,5 +110,6 @@ EI_ADD_TEST(eigensolver)
|
|||||||
EI_ADD_TEST(geometry)
|
EI_ADD_TEST(geometry)
|
||||||
EI_ADD_TEST(regression)
|
EI_ADD_TEST(regression)
|
||||||
EI_ADD_TEST(svd)
|
EI_ADD_TEST(svd)
|
||||||
|
EI_ADD_TEST(ioformat)
|
||||||
|
|
||||||
ENDIF(BUILD_TESTS)
|
ENDIF(BUILD_TESTS)
|
||||||
|
44
test/ioformat.cpp
Normal file
44
test/ioformat.cpp
Normal 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;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user