From 255689231d4267d8a254fef5b59162d92c3cab4d Mon Sep 17 00:00:00 2001 From: Gael Guennebaud Date: Mon, 3 Mar 2008 10:52:44 +0000 Subject: [PATCH] * Added generic unary operators (replace Opposite and Conjugate) * functor templates are not template template parameter anymore (this allows to make templated functors !) * Main page: extented compiler discussion * A small hack to support gcc 3.4 and 4.0 (see the main page) * Fix a cast type issue in Cast * Various doxygen updates (mainly Cwise stuff and added doxygen groups in MatrixBase to split the huge memeber list, still not perfect though) * Updated Gael's email address --- Eigen/Core | 15 ++- Eigen/src/Core/Block.h | 5 +- Eigen/src/Core/Cast.h | 4 +- Eigen/src/Core/Conjugate.h | 95 --------------- Eigen/src/Core/CwiseBinaryOp.h | 48 +++++--- Eigen/src/Core/CwiseUnaryOp.h | 171 +++++++++++++++++++++++++++ Eigen/src/Core/ForwardDeclarations.h | 11 +- Eigen/src/Core/MatrixBase.h | 118 +++++++++++------- Eigen/src/Core/MatrixStorage.h | 2 +- Eigen/src/Core/Opposite.h | 81 ------------- Eigen/src/Core/Transpose.h | 13 ++ Eigen/src/Core/Util.h | 6 +- doc/Mainpage.dox | 11 +- doc/examples/class_CwiseBinaryOp.cpp | 27 +++++ test/cwiseop.cpp | 19 ++- test/submatrices.cpp | 38 ++++-- 16 files changed, 397 insertions(+), 267 deletions(-) delete mode 100644 Eigen/src/Core/Conjugate.h create mode 100644 Eigen/src/Core/CwiseUnaryOp.h delete mode 100644 Eigen/src/Core/Opposite.h create mode 100644 doc/examples/class_CwiseBinaryOp.cpp diff --git a/Eigen/Core b/Eigen/Core index 3ced3e88a..e4dcfc96e 100644 --- a/Eigen/Core +++ b/Eigen/Core @@ -4,6 +4,14 @@ #include #include +#if ((defined __GNUC__) && ( (__GNUC__==3) || (__GNUC__==4) && __GNUC_MINOR__==0)) +/* This very ugly hack to fix a bug of gcc <4.1 with the Curiously recurring template pattern and friend class. + Note that gcc-4.0.1 is still the default compiler on MACOSX Leopard. +*/ +#define private public +#warning "Your compiler (gcc<4.1) has issue with friend and CRT, all private members of Eigen's classes are made public" +#endif + namespace Eigen { #include "src/Core/Util.h" @@ -19,7 +27,7 @@ namespace Eigen { #include "src/Core/Cast.h" #include "src/Core/Eval.h" #include "src/Core/CwiseBinaryOp.h" -#include "src/Core/Opposite.h" +#include "src/Core/CwiseUnaryOp.h" #include "src/Core/ScalarMultiple.h" #include "src/Core/Product.h" #include "src/Core/Row.h" @@ -27,7 +35,6 @@ namespace Eigen { #include "src/Core/Block.h" #include "src/Core/Minor.h" #include "src/Core/Transpose.h" -#include "src/Core/Conjugate.h" #include "src/Core/Trace.h" #include "src/Core/Dot.h" #include "src/Core/Random.h" @@ -42,3 +49,7 @@ namespace Eigen { #include "src/Core/Swap.h" } // namespace Eigen + +#if ((defined __GNUC__) && (__GNUC_MINOR__==0)) +#undef private +#endif diff --git a/Eigen/src/Core/Block.h b/Eigen/src/Core/Block.h index 9ed69d03f..74e1cd1c5 100644 --- a/Eigen/src/Core/Block.h +++ b/Eigen/src/Core/Block.h @@ -1,7 +1,7 @@ // This file is part of Eigen, a lightweight C++ template library // for linear algebra. Eigen itself is part of the KDE project. // -// Copyright (C) 2008 Gael Guennebaud +// Copyright (C) 2008 Gael Guennebaud // Copyright (C) 2006-2008 Benoit Jacob // // Eigen is free software; you can redistribute it and/or @@ -328,6 +328,9 @@ const Block MatrixBase * Example: \include MatrixBase_block_int_int.cpp * Output: \verbinclude MatrixBase_block_int_int.out * + * \note since block is a templated member, the keyword template as to be used + * if the matrix type is also a template parameter: \code m.template block<3,3>(1,1); \endcode + * * \sa class Block, block(int,int,int,int) */ template diff --git a/Eigen/src/Core/Cast.h b/Eigen/src/Core/Cast.h index cf1466476..42c0a7f0f 100644 --- a/Eigen/src/Core/Cast.h +++ b/Eigen/src/Core/Cast.h @@ -67,9 +67,9 @@ template class Cast : NoOperatorEquals, int _rows() const { return m_matrix.rows(); } int _cols() const { return m_matrix.cols(); } - Scalar _coeff(int row, int col) const + NewScalar _coeff(int row, int col) const { - return static_cast(m_matrix.coeff(row, col)); + return static_cast(m_matrix.coeff(row, col)); } protected: diff --git a/Eigen/src/Core/Conjugate.h b/Eigen/src/Core/Conjugate.h deleted file mode 100644 index a95caf75b..000000000 --- a/Eigen/src/Core/Conjugate.h +++ /dev/null @@ -1,95 +0,0 @@ -// 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 -// -// 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 . - -#ifndef EIGEN_CONJUGATE_H -#define EIGEN_CONJUGATE_H - -/** \class Conjugate - * - * \brief Expression of the complex conjugate of a matrix - * - * \param MatrixType the type of the object of which we are taking the complex conjugate - * - * This class represents an expression of the complex conjugate of a matrix. - * It is the return type of MatrixBase::conjugate() and is also used by - * MatrixBase::adjoint() and most of the time these are the only ways it is used. - * - * \sa MatrixBase::conjugate(), MatrixBase::adjoint() - */ -template class Conjugate : NoOperatorEquals, - public MatrixBase > -{ - public: - typedef typename MatrixType::Scalar Scalar; - typedef typename MatrixType::Ref MatRef; - friend class MatrixBase; - typedef MatrixBase Base; - - Conjugate(const MatRef& matrix) : m_matrix(matrix) {} - - private: - enum { - RowsAtCompileTime = MatrixType::Traits::RowsAtCompileTime, - ColsAtCompileTime = MatrixType::Traits::ColsAtCompileTime, - MaxRowsAtCompileTime = MatrixType::Traits::MaxRowsAtCompileTime, - MaxColsAtCompileTime = MatrixType::Traits::MaxColsAtCompileTime - }; - - const Conjugate& _ref() const { return *this; } - int _rows() const { return m_matrix.rows(); } - int _cols() const { return m_matrix.cols(); } - - Scalar _coeff(int row, int col) const - { - return ei_conj(m_matrix.coeff(row, col)); - } - - protected: - const MatRef m_matrix; -}; - -/** \returns an expression of the complex conjugate of *this. - * - * \sa adjoint(), class Conjugate */ -template -const Conjugate -MatrixBase::conjugate() const -{ - return Conjugate(ref()); -} - -/** \returns an expression of the adjoint (i.e. conjugate transpose) of *this. - * - * Example: \include MatrixBase_adjoint.cpp - * Output: \verbinclude MatrixBase_adjoint.out - * - * \sa transpose(), conjugate(), class Transpose, class Conjugate */ -template -const Transpose > -MatrixBase::adjoint() const -{ - return conjugate().transpose(); -} - -#endif // EIGEN_CONJUGATE_H diff --git a/Eigen/src/Core/CwiseBinaryOp.h b/Eigen/src/Core/CwiseBinaryOp.h index 8a344b540..348f1f393 100644 --- a/Eigen/src/Core/CwiseBinaryOp.h +++ b/Eigen/src/Core/CwiseBinaryOp.h @@ -1,7 +1,7 @@ // This file is part of Eigen, a lightweight C++ template library // for linear algebra. Eigen itself is part of the KDE project. // -// Copyright (C) 2008 Gael Guennebaud +// Copyright (C) 2008 Gael Guennebaud // Copyright (C) 2006-2008 Benoit Jacob // // Eigen is free software; you can redistribute it and/or @@ -35,12 +35,18 @@ * \param Rhs the type of the right-hand side * * This class represents an expression of a generic binary operator of two matrices or vectors. - * It is the return type of the operator+, operator-, cwiseiseProduct, cwiseQuotient between matrices or vectors, and most + * It is the return type of the operator+, operator-, cwiseProduct, cwiseQuotient between matrices or vectors, and most * of the time this is the only way it is used. * + * However, if you want to write a function returning such an expression, you + * will need to use this class. + * + * Here is an example illustrating this: + * \include class_CwiseBinaryOp.cpp + * * \sa class CwiseProductOp, class CwiseQuotientOp */ -template class BinaryOp, typename Lhs, typename Rhs> +template class CwiseBinaryOp : NoOperatorEquals, public MatrixBase > { @@ -71,7 +77,7 @@ class CwiseBinaryOp : NoOperatorEquals, Scalar _coeff(int row, int col) const { - return BinaryOp::op(m_lhs.coeff(row, col), m_rhs.coeff(row, col)); + return BinaryOp::template op(m_lhs.coeff(row, col), m_rhs.coeff(row, col)); } protected: @@ -83,32 +89,32 @@ class CwiseBinaryOp : NoOperatorEquals, * * \sa class CwiseBinaryOp, MatrixBase::operator+ */ -template struct CwiseSumOp { - static Scalar op(const Scalar& a, const Scalar& b) { return a + b; } +struct CwiseSumOp { + template static Scalar op(const Scalar& a, const Scalar& b) { return a + b; } }; /** \brief Template functor to compute the difference of two scalars * * \sa class CwiseBinaryOp, MatrixBase::operator- */ -template struct CwiseDifferenceOp { - static Scalar op(const Scalar& a, const Scalar& b) { return a - b; } +struct CwiseDifferenceOp { + template static Scalar op(const Scalar& a, const Scalar& b) { return a - b; } }; /** \brief Template functor to compute the product of two scalars * * \sa class CwiseBinaryOp, MatrixBase::cwiseProduct() */ -template struct CwiseProductOp { - static Scalar op(const Scalar& a, const Scalar& b) { return a * b; } +struct CwiseProductOp { + template static Scalar op(const Scalar& a, const Scalar& b) { return a * b; } }; /** \brief Template functor to compute the quotient of two scalars * * \sa class CwiseBinaryOp, MatrixBase::cwiseQuotient() */ -template struct CwiseQuotientOp { - static Scalar op(const Scalar& a, const Scalar& b) { return a / b; } +struct CwiseQuotientOp { + template static Scalar op(const Scalar& a, const Scalar& b) { return a / b; } }; /** \relates MatrixBase @@ -193,11 +199,12 @@ MatrixBase::cwiseQuotient(const MatrixBase class CustomBinaryOp, typename Scalar, typename Derived1, typename Derived2> +template const CwiseBinaryOp cwise(const MatrixBase &mat1, const MatrixBase &mat2) { @@ -206,12 +213,21 @@ cwise(const MatrixBase &mat1, const MatrixBase void foo(const MatrixType& m1, const MatrixType& m2) { + * m1.template cwise(m2); + * } + * \endcode * * \sa class CwiseBinaryOp, MatrixBase::operator+, MatrixBase::operator-, MatrixBase::cwiseProduct, MatrixBase::cwiseQuotient */ template -template class CustomBinaryOp, typename OtherDerived> +template const CwiseBinaryOp MatrixBase::cwise(const MatrixBase &other) const { diff --git a/Eigen/src/Core/CwiseUnaryOp.h b/Eigen/src/Core/CwiseUnaryOp.h new file mode 100644 index 000000000..27e8c288f --- /dev/null +++ b/Eigen/src/Core/CwiseUnaryOp.h @@ -0,0 +1,171 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. Eigen itself is part of the KDE project. +// +// Copyright (C) 2008 Gael Guennebaud +// Copyright (C) 2006-2008 Benoit Jacob +// +// 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 . + +#ifndef EIGEN_CWISE_UNARY_OP_H +#define EIGEN_CWISE_UNARY_OP_H + +/** \class CwiseUnaryOp + * + * \brief Generic expression of a coefficient-wise unary operator of a matrix or a vector + * + * \param UnaryOp template functor implementing the operator + * \param MatrixType the type of the matrix we are applying the unary operator + * + * This class represents an expression of a generic unary operator of a matrix or a vector. + * It is the return type of the unary operator-, of a matrix or a vector, and most + * of the time this is the only way it is used. + * + * \sa class CwiseBinaryOp + */ +template +class CwiseUnaryOp : NoOperatorEquals, + public MatrixBase > +{ + public: + typedef typename MatrixType::Scalar Scalar; + typedef typename MatrixType::Ref MatRef; + friend class MatrixBase; + typedef MatrixBase Base; + + CwiseUnaryOp(const MatRef& mat) : m_matrix(mat) {} + + private: + enum { + RowsAtCompileTime = MatrixType::Traits::RowsAtCompileTime, + ColsAtCompileTime = MatrixType::Traits::ColsAtCompileTime, + MaxRowsAtCompileTime = MatrixType::Traits::MaxRowsAtCompileTime, + MaxColsAtCompileTime = MatrixType::Traits::MaxColsAtCompileTime + }; + + const CwiseUnaryOp& _ref() const { return *this; } + int _rows() const { return m_matrix.rows(); } + int _cols() const { return m_matrix.cols(); } + + Scalar _coeff(int row, int col) const + { + return UnaryOp::template op(m_matrix.coeff(row, col)); + } + + protected: + const MatRef m_matrix; +}; + +/** \brief Template functor to compute the opposite of a scalar + * + * \sa class CwiseUnaryOp, MatrixBase::operator- + */ +struct CwiseOppositeOp { + template static Scalar op(const Scalar& a) { return -a; } +}; + +/** \brief Template functor to compute the absolute value of a scalar + * + * \sa class CwiseUnaryOp, MatrixBase::cwiseAbs + */ +struct CwiseAbsOp { + template static Scalar op(const Scalar& a) { return ei_abs(a); } +}; + + +/** \returns an expression of the opposite of \c *this + */ +template +const CwiseUnaryOp +MatrixBase::operator-() const +{ + return CwiseUnaryOp(ref()); +} + +/** \returns an expression of the opposite of \c *this + */ +template +const CwiseUnaryOp +MatrixBase::cwiseAbs() const +{ + return CwiseUnaryOp(ref()); +} + + +/** \relates MatrixBase + * + * \returns an expression of a custom coefficient-wise unary operator of \a mat + * + * The template parameter \a CustomUnaryOp is the template functor + * of the custom unary operator. + * + * \sa class CwiseUnaryOp, class CwiseBinarOp, MatrixBase::cwise, MatrixBase::operator-, MatrixBase::cwiseAbs + */ +template +const CwiseUnaryOp +cwise(const MatrixBase &mat) +{ + return CwiseUnaryOp(mat.ref()); +} + +/** \returns an expression of a custom coefficient-wise unary operator of *this + * + * The template parameter \a CustomUnaryOp is the template functor + * of the custom unary operator. + * + * \note since cwise is a templated member with a mandatory template parameter, + * the keyword template as to be used if the matrix type is also a template parameter: + * \code + * template void foo(const MatrixType& m) { + * m.template cwise(); + * } + * \endcode + * + * \sa class CwiseUnaryOp, class CwiseBinarOp, MatrixBase::operator-, MatrixBase::cwiseAbs + */ +template +template +const CwiseUnaryOp +MatrixBase::cwise() const +{ + return CwiseUnaryOp(ref()); +} + + +/** \brief Template functor to compute the conjugate of a complex value + * + * \sa class CwiseUnaryOp, MatrixBase::conjugate() + */ +struct ConjugateOp { + template static Scalar op(const Scalar& a) { return ei_conj(a); } +}; + +/** \returns an expression of the complex conjugate of *this. + * + * \sa adjoint(), class Conjugate */ +template +const CwiseUnaryOp +MatrixBase::conjugate() const +{ + return CwiseUnaryOp(ref()); +} + + + +#endif // EIGEN_CWISE_UNARY_OP_H diff --git a/Eigen/src/Core/ForwardDeclarations.h b/Eigen/src/Core/ForwardDeclarations.h index 59c088c19..9561abc51 100644 --- a/Eigen/src/Core/ForwardDeclarations.h +++ b/Eigen/src/Core/ForwardDeclarations.h @@ -34,10 +34,13 @@ template class Minor; template class Block; template class Transpose; template class Conjugate; -template class Opposite; -template class BinaryOp, typename Lhs, typename Rhs> class CwiseBinaryOp; -template struct CwiseProductOp; -template struct CwiseQuotientOp; +template class CwiseBinaryOp; +struct CwiseProductOp; +struct CwiseQuotientOp; +template class CwiseUnaryOp; +struct CwiseOppositeOp; +struct ConjugateOp; +struct CwiseAbsOp; template class Product; template class ScalarMultiple; template class Random; diff --git a/Eigen/src/Core/MatrixBase.h b/Eigen/src/Core/MatrixBase.h index 1d3e90d40..b53a74290 100644 --- a/Eigen/src/Core/MatrixBase.h +++ b/Eigen/src/Core/MatrixBase.h @@ -144,6 +144,8 @@ template class MatrixBase */ typedef typename NumTraits::Real RealScalar; + /// \name a - matrix properties + //@{ /** \returns the number of rows. \sa cols(), Traits::RowsAtCompileTime */ int rows() const { return static_cast(this)->_rows(); } /** \returns the number of columns. \sa row(), Traits::ColsAtCompileTime*/ @@ -156,10 +158,13 @@ template class MatrixBase * \code rows()==1 || cols()==1 \endcode * \sa rows(), cols(), Traits::IsVectorAtCompileTime. */ bool isVector() const { return rows()==1 || cols()==1; } + //@} + /** \returns a Ref to *this. \sa Ref */ Ref ref() const { return static_cast(this)->_ref(); } + //@{ /** Copies \a other into *this. \returns a reference to *this. */ template Derived& operator=(const MatrixBase& other); @@ -172,8 +177,18 @@ template class MatrixBase return this->operator=(other); } - template const Cast cast() const; + /** swaps *this with the expression \a other. + * + * \note \a other is only marked const because I couln't find another way + * to get g++ 4.2 to accept that template parameter resolution. It gets const_cast'd + * of course. TODO: get rid of const here. + */ + template + void swap(const MatrixBase& other); + //@} + /// \name c - sub-matrices + //@{ Row row(int i); const Row row(int i) const; @@ -204,22 +219,34 @@ template class MatrixBase template const Block block(int startRow, int startCol) const; + DiagonalCoeffs diagonal(); + const DiagonalCoeffs diagonal() const; + //@} + + /// \name d - matrix transformation + //@{ + template const Cast cast() const; + + const DiagonalMatrix asDiagonal() const; + Transpose transpose(); const Transpose transpose() const; - const Conjugate conjugate() const; - const Transpose > adjoint() const; + const CwiseUnaryOp conjugate() const; + const Transpose > adjoint() const; + + const ScalarMultiple normalized() const; + //@} + + /// \name f - metrics (??) + //@{ Scalar trace() const; template Scalar dot(const MatrixBase& other) const; RealScalar norm2() const; RealScalar norm() const; - const ScalarMultiple normalized() const; - template - bool isOrtho(const MatrixBase& other, - RealScalar prec = precision()) const; - bool isOrtho(RealScalar prec = precision()) const; + //@} static const Eval > random(int rows, int cols); static const Eval > random(int size); @@ -233,20 +260,22 @@ template class MatrixBase static const Identity identity(); static const Identity identity(int rows, int cols); - bool isZero(RealScalar prec = precision()) const; - bool isOnes(RealScalar prec = precision()) const; - bool isIdentity(RealScalar prec = precision()) const; - bool isDiagonal(RealScalar prec = precision()) const; - Derived& setZero(); Derived& setOnes(); Derived& setRandom(); Derived& setIdentity(); - const DiagonalMatrix asDiagonal() const; + /// \name g - matrix diagnostic and comparison + //@{ + bool isZero(RealScalar prec = precision()) const; + bool isOnes(RealScalar prec = precision()) const; + bool isIdentity(RealScalar prec = precision()) const; + bool isDiagonal(RealScalar prec = precision()) const; - DiagonalCoeffs diagonal(); - const DiagonalCoeffs diagonal() const; + template + bool isOrtho(const MatrixBase& other, + RealScalar prec = precision()) const; + bool isOrtho(RealScalar prec = precision()) const; template bool isApprox(const OtherDerived& other, @@ -256,24 +285,11 @@ template class MatrixBase template bool isMuchSmallerThan(const MatrixBase& other, RealScalar prec = precision()) const; + //@} - template - const Product - lazyProduct(const MatrixBase& other) const EIGEN_ALWAYS_INLINE; - - const Opposite operator-() const; - - template - const CwiseBinaryOp - cwiseProduct(const MatrixBase &other) const; - - template - const CwiseBinaryOp - cwiseQuotient(const MatrixBase &other) const; - - template class CustomBinaryOp, typename OtherDerived> - const CwiseBinaryOp - cwise(const MatrixBase &other) const; + /// \name e - arithemetic operators + //@{ + const CwiseUnaryOp operator-() const; template Derived& operator+=(const MatrixBase& other); @@ -293,6 +309,23 @@ template class MatrixBase const MatrixBase& matrix) { return matrix*scalar; } + template + const Product + lazyProduct(const MatrixBase& other) const EIGEN_ALWAYS_INLINE; + + const CwiseUnaryOp cwiseAbs() const; + + template + const CwiseBinaryOp + cwiseProduct(const MatrixBase &other) const; + + template + const CwiseBinaryOp + cwiseQuotient(const MatrixBase &other) const; + //@} + + /// \name b - coefficient accessors + //@{ Scalar coeff(int row, int col) const; Scalar operator()(int row, int col) const; @@ -313,9 +346,20 @@ template class MatrixBase Scalar& y(); Scalar& z(); Scalar& w(); + //@} + /// \name h - special functions + //@{ const Eval eval() const EIGEN_ALWAYS_INLINE; + template + const CwiseUnaryOp cwise() const; + + template + const CwiseBinaryOp + cwise(const MatrixBase &other) const; + //@} + /** puts in *row and *col the location of the coefficient of *this * which has the biggest absolute value. */ @@ -335,14 +379,6 @@ template class MatrixBase } } - /** swaps *this with the expression \a other. - * - * \note \a other is only marked const because I couln't find another way - * to get g++ 4.2 to accept that template parameter resolution. It gets const_cast'd - * of course. TODO: get rid of const here. - */ - template - void swap(const MatrixBase& other); }; #endif // EIGEN_MATRIXBASE_H diff --git a/Eigen/src/Core/MatrixStorage.h b/Eigen/src/Core/MatrixStorage.h index e441f0a77..a3ffc4064 100644 --- a/Eigen/src/Core/MatrixStorage.h +++ b/Eigen/src/Core/MatrixStorage.h @@ -1,7 +1,7 @@ // This file is part of Eigen, a lightweight C++ template library // for linear algebra. Eigen itself is part of the KDE project. // -// Copyright (C) 2008 Gael Guennebaud +// Copyright (C) 2008 Gael Guennebaud // Copyright (C) 2006-2008 Benoit Jacob // // Eigen is free software; you can redistribute it and/or diff --git a/Eigen/src/Core/Opposite.h b/Eigen/src/Core/Opposite.h deleted file mode 100644 index 43ed8cb57..000000000 --- a/Eigen/src/Core/Opposite.h +++ /dev/null @@ -1,81 +0,0 @@ -// 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 -// -// 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 . - -#ifndef EIGEN_OPPOSITE_H -#define EIGEN_OPPOSITE_H - -/** \class Opposite - * - * \brief Expression of the opposite of a matrix or vector - * - * \param MatrixType the type of which we are taking the opposite - * - * This class represents an expression of the opposite of a matrix or vector. - * It is the return type of the unary operator- for matrices or vectors, and most - * of the time this is the only way it is used. - * - * \sa class Difference - */ -template class Opposite : NoOperatorEquals, - public MatrixBase > -{ - public: - typedef typename MatrixType::Scalar Scalar; - typedef typename MatrixType::Ref MatRef; - friend class MatrixBase; - typedef MatrixBase Base; - - Opposite(const MatRef& matrix) : m_matrix(matrix) {} - - private: - enum { - RowsAtCompileTime = MatrixType::Traits::RowsAtCompileTime, - ColsAtCompileTime = MatrixType::Traits::ColsAtCompileTime, - MaxRowsAtCompileTime = MatrixType::Traits::MaxRowsAtCompileTime, - MaxColsAtCompileTime = MatrixType::Traits::MaxColsAtCompileTime - }; - - const Opposite& _ref() const { return *this; } - int _rows() const { return m_matrix.rows(); } - int _cols() const { return m_matrix.cols(); } - - Scalar _coeff(int row, int col) const - { - return -(m_matrix.coeff(row, col)); - } - - protected: - const MatRef m_matrix; -}; - -/** \returns an expression of the opposite of \c *this - */ -template -const Opposite -MatrixBase::operator-() const -{ - return Opposite(ref()); -} - -#endif // EIGEN_OPPOSITE_H diff --git a/Eigen/src/Core/Transpose.h b/Eigen/src/Core/Transpose.h index 94c068db7..5320ad522 100644 --- a/Eigen/src/Core/Transpose.h +++ b/Eigen/src/Core/Transpose.h @@ -97,4 +97,17 @@ MatrixBase::transpose() const return Transpose(ref()); } +/** \returns an expression of the adjoint (i.e. conjugate transpose) of *this. + * + * Example: \include MatrixBase_adjoint.cpp + * Output: \verbinclude MatrixBase_adjoint.out + * + * \sa transpose(), conjugate(), class Transpose, class ConjugateOp */ +template +const Transpose > +MatrixBase::adjoint() const +{ + return conjugate().transpose(); +} + #endif // EIGEN_TRANSPOSE_H diff --git a/Eigen/src/Core/Util.h b/Eigen/src/Core/Util.h index 42177dfb5..b11c27653 100644 --- a/Eigen/src/Core/Util.h +++ b/Eigen/src/Core/Util.h @@ -56,7 +56,11 @@ using Eigen::MatrixBase; #define EIGEN_ONLY_USED_FOR_DEBUG(x) #endif -#ifdef __GNUC__ +// FIXME with the always_inline attribute, +// gcc 3.4.x reports the following compilation error: +// Eval.h:91: sorry, unimplemented: inlining failed in call to 'const Eigen::Eval Eigen::MatrixBase::eval() const' +// : function body not available +#if (defined __GNUC__) && (__GNUC__!=3) #define EIGEN_ALWAYS_INLINE __attribute__((always_inline)) #else #define EIGEN_ALWAYS_INLINE diff --git a/doc/Mainpage.dox b/doc/Mainpage.dox index 755027f81..8dde22963 100644 --- a/doc/Mainpage.dox +++ b/doc/Mainpage.dox @@ -71,9 +71,16 @@ The To-do wiki for Eigen is here:

News

diff --git a/doc/examples/class_CwiseBinaryOp.cpp b/doc/examples/class_CwiseBinaryOp.cpp new file mode 100644 index 000000000..2a0f11a75 --- /dev/null +++ b/doc/examples/class_CwiseBinaryOp.cpp @@ -0,0 +1,27 @@ +#include +USING_PART_OF_NAMESPACE_EIGEN +using namespace std; + +// define a custom template binary functor +struct CwiseMinOp { + template + static Scalar op(const Scalar& a, const Scalar& b) { return std::min(a,b); } +}; + +// define a custom binary operator between two matrices +template +const Eigen::CwiseBinaryOp +cwiseMin(const MatrixBase &mat1, const MatrixBase &mat2) +{ + return Eigen::CwiseBinaryOp(mat1.ref(), mat2.ref()); + // Note that the above is equivalent to: + // return mat1.template cwise(mat2); +} + +int main(int, char**) +{ + Matrix4d m1 = Matrix4d::random(), m2 = Matrix4d::random(); + cout << cwiseMin(m1,m2) << endl; // use our new global operator + cout << m1.cwise(m2) << endl; // directly use the generic expression member + return 0; +} diff --git a/test/cwiseop.cpp b/test/cwiseop.cpp index 3e8179aa3..b8dac7884 100644 --- a/test/cwiseop.cpp +++ b/test/cwiseop.cpp @@ -29,8 +29,8 @@ namespace Eigen { -template struct AddIfNull { - static Scalar op(const Scalar a, const Scalar b) {return a<1e-3 ? b : a;} +struct AddIfNull { + template static Scalar op(const Scalar a, const Scalar b) {return a<=1e-3 ? b : a;} }; template void cwiseops(const MatrixType& m) @@ -54,10 +54,7 @@ template void cwiseops(const MatrixType& m) v2 = VectorType::random(rows), vzero = VectorType::zero(rows); - - m2 = m2.cwise(mones); - //m2 = cwise(m2,mones); - std::cout << m2 << "\n"; + m2 = m2.template cwise(mones); VERIFY_IS_APPROX( mzero, m1-m1); VERIFY_IS_APPROX( m2, m1+m2-m1); @@ -72,12 +69,12 @@ template void cwiseops(const MatrixType& m) void EigenTest::testCwiseops() { - for(int i = 0; i < 1/*m_repeat*/ ; i++) { -// cwiseops(Matrix()); -// cwiseops(Matrix4d()); -// cwiseops(MatrixXcf(3, 3)); + for(int i = 0; i < m_repeat ; i++) { + cwiseops(Matrix()); + cwiseops(Matrix4d()); + cwiseops(MatrixXf(3, 3)); cwiseops(MatrixXi(8, 12)); -// cwiseops(MatrixXcd(20, 20)); + cwiseops(MatrixXd(20, 20)); } } diff --git a/test/submatrices.cpp b/test/submatrices.cpp index c3b4aac3b..6955a55ed 100644 --- a/test/submatrices.cpp +++ b/test/submatrices.cpp @@ -26,12 +26,38 @@ namespace Eigen { +// check minor separately in order to avoid the possible creation of a zero-sized +// array. Comes from a compilation error with gcc-3.4 or gcc-4 with -ansi -pedantic. +// Another solution would be to declare the array like this: T m_data[Size==0?1:Size]; in MatrixStorage +// but this is probably not bad to raise such an error at compile time... +template struct CheckMinor +{ + typedef Matrix MatrixType; + CheckMinor(MatrixType& m1, int r1, int c1) + { + int rows = m1.rows(); + int cols = m1.cols(); + + Matrix mi = m1.minor(0,0).eval(); + VERIFY_IS_APPROX(mi, m1.block(1,1,rows-1,cols-1)); + mi = m1.minor(r1,c1); + VERIFY_IS_APPROX(mi.transpose(), m1.transpose().minor(c1,r1)); + //check operator(), both constant and non-constant, on minor() + m1.minor(r1,c1)(0,0) = m1.minor(0,0)(0,0); + } +}; + +template struct CheckMinor +{ + typedef Matrix MatrixType; + CheckMinor(MatrixType&, int, int) {} +}; + template void submatrices(const MatrixType& m) { /* this test covers the following files: Row.h Column.h Block.h Minor.h DiagonalCoeffs.h */ - typedef typename MatrixType::Scalar Scalar; typedef Matrix VectorType; typedef Matrix RowVectorType; @@ -77,15 +103,7 @@ template void submatrices(const MatrixType& m) m1.block(r1,c1,r2-r1+1,c2-c1+1)(r2-r1,c2-c1) = m2.block(0, 0, r2-r1+1,c2-c1+1)(0,0); //check minor() - if(rows > 1 && cols > 1) - { - Matrix mi = m1.minor(0,0).eval(); - VERIFY_IS_APPROX(mi, m1.block(1,1,rows-1,cols-1)); - mi = m1.minor(r1,c1); - VERIFY_IS_APPROX(mi.transpose(), m1.transpose().minor(c1,r1)); - //check operator(), both constant and non-constant, on minor() - m1.minor(r1,c1)(0,0) = m1.minor(0,0)(0,0); - } + CheckMinor checkminor(m1,r1,c1); //check diagonal() VERIFY_IS_APPROX(m1.diagonal(), m1.transpose().diagonal());