From fb3438e609be743c066af9167e6ed83cd17af394 Mon Sep 17 00:00:00 2001 From: Benoit Jacob Date: Fri, 14 Mar 2008 10:38:37 +0000 Subject: [PATCH] - expand MathFunctions.h to provide more functions, like exp, log... - add cwiseExp(), cwiseLog()... --> for example, doing a gamma-correction on a bitmap image stored as an array of floats is a simple matter of: Eigen::Map m = VectorXf::map(bitmap,size); m = m.cwisePow(gamma); - apidoc improvements, reorganization of the \name's - remove obsolete examples - remove EIGEN_ALWAYS_INLINE on lazyProduct(), it seems useless. --- Eigen/src/Core/CwiseBinaryOp.h | 24 +- Eigen/src/Core/CwiseUnaryOp.h | 208 +++++++++++--- Eigen/src/Core/ForwardDeclarations.h | 7 + Eigen/src/Core/MathFunctions.h | 60 ++-- Eigen/src/Core/MatrixBase.h | 414 +++++++++++++++------------ Eigen/src/Core/Product.h | 16 +- doc/Doxyfile.in | 8 +- doc/examples/class_Block.cpp | 4 +- doc/examples/class_Cast.cpp | 27 -- doc/examples/class_Column.cpp | 26 -- doc/examples/class_FixedBlock.cpp | 4 +- doc/examples/class_Row.cpp | 26 -- 12 files changed, 451 insertions(+), 373 deletions(-) delete mode 100644 doc/examples/class_Cast.cpp delete mode 100644 doc/examples/class_Column.cpp delete mode 100644 doc/examples/class_Row.cpp diff --git a/Eigen/src/Core/CwiseBinaryOp.h b/Eigen/src/Core/CwiseBinaryOp.h index 76e4f0659..131e98362 100644 --- a/Eigen/src/Core/CwiseBinaryOp.h +++ b/Eigen/src/Core/CwiseBinaryOp.h @@ -129,17 +129,16 @@ struct ei_scalar_quotient_op EIGEN_EMPTY_STRUCT { template Scalar operator() (const Scalar& a, const Scalar& b) const { return a / b; } }; -/** \relates MatrixBase - * - * \returns an expression of the difference of \a mat1 and \a mat2 +/**\returns an expression of the difference of \c *this and \a other * * \sa class CwiseBinaryOp, MatrixBase::operator-=() */ -template -const CwiseBinaryOp -operator-(const MatrixBase &mat1, const MatrixBase &mat2) +template +template +const CwiseBinaryOp +MatrixBase::operator-(const MatrixBase &other) const { - return CwiseBinaryOp(mat1.derived(), mat2.derived()); + return CwiseBinaryOp(derived(), other.derived()); } /** replaces \c *this by \c *this - \a other. @@ -156,15 +155,16 @@ MatrixBase::operator-=(const MatrixBase &other) /** \relates MatrixBase * - * \returns an expression of the sum of \a mat1 and \a mat2 + * \returns an expression of the sum of \c *this and \a other * * \sa class CwiseBinaryOp, MatrixBase::operator+=() */ -template -const CwiseBinaryOp -operator+(const MatrixBase &mat1, const MatrixBase &mat2) +template +template +const CwiseBinaryOp +MatrixBase::operator+(const MatrixBase &other) const { - return CwiseBinaryOp(mat1.derived(), mat2.derived()); + return CwiseBinaryOp(derived(), other.derived()); } /** replaces \c *this by \c *this + \a other. diff --git a/Eigen/src/Core/CwiseUnaryOp.h b/Eigen/src/Core/CwiseUnaryOp.h index 2943f5826..6958ca248 100644 --- a/Eigen/src/Core/CwiseUnaryOp.h +++ b/Eigen/src/Core/CwiseUnaryOp.h @@ -79,43 +79,6 @@ class CwiseUnaryOp : ei_no_assignment_operator, const UnaryOp m_functor; }; -/** \internal - * \brief Template functor to compute the opposite of a scalar - * - * \sa class CwiseUnaryOp, MatrixBase::operator- - */ -struct ei_scalar_opposite_op EIGEN_EMPTY_STRUCT { - template Scalar operator() (const Scalar& a) const { return -a; } -}; - -/** \internal - * \brief Template functor to compute the absolute value of a scalar - * - * \sa class CwiseUnaryOp, MatrixBase::cwiseAbs - */ -struct ei_scalar_abs_op EIGEN_EMPTY_STRUCT { - template Scalar operator() (const Scalar& a) const { return ei_abs(a); } -}; - - -/** \returns an expression of the opposite of \c *this - */ -template -const CwiseUnaryOp -MatrixBase::operator-() const -{ - return CwiseUnaryOp(derived()); -} - -/** \returns an expression of the opposite of \c *this - */ -template -const CwiseUnaryOp -MatrixBase::cwiseAbs() const -{ - return CwiseUnaryOp(derived()); -} - /** \returns an expression of a custom coefficient-wise unary operator \a func of *this * * The template parameter \a CustomUnaryOp is the type of the functor @@ -134,6 +97,60 @@ MatrixBase::cwise(const CustomUnaryOp& func) const return CwiseUnaryOp(derived(), func); } +/** \internal + * \brief Template functor to compute the opposite of a scalar + * + * \sa class CwiseUnaryOp, MatrixBase::operator- + */ +struct ei_scalar_opposite_op EIGEN_EMPTY_STRUCT { + template Scalar operator() (const Scalar& a) const { return -a; } +}; + +/** \returns an expression of the opposite of \c *this + */ +template +const CwiseUnaryOp +MatrixBase::operator-() const +{ + return CwiseUnaryOp(derived()); +} + +/** \internal + * \brief Template functor to compute the absolute value of a scalar + * + * \sa class CwiseUnaryOp, MatrixBase::cwiseAbs + */ +struct ei_scalar_abs_op EIGEN_EMPTY_STRUCT { + template Scalar operator() (const Scalar& a) const { return ei_abs(a); } +}; + +/** \returns an expression of the coefficient-wise absolute value of \c *this + */ +template +const CwiseUnaryOp +MatrixBase::cwiseAbs() const +{ + return CwiseUnaryOp(derived()); +} + +/** \internal + * \brief Template functor to compute the squared absolute value of a scalar + * + * \sa class CwiseUnaryOp, MatrixBase::cwiseAbs2 + */ +struct ei_scalar_abs2_op EIGEN_EMPTY_STRUCT { + template Scalar operator() (const Scalar& a) const { return ei_abs2(a); } +}; + +/** \returns an expression of the coefficient-wise squared absolute value of \c *this + */ +template +const CwiseUnaryOp +MatrixBase::cwiseAbs2() const +{ + return CwiseUnaryOp(derived()); +} + /** \internal * \brief Template functor to compute the conjugate of a complex value * @@ -169,10 +186,7 @@ struct ei_scalar_cast_op EIGEN_EMPTY_STRUCT { * * The template parameter \a NewScalar is the type we are casting the scalars to. * - * Example: \include MatrixBase_cast.cpp - * Output: \verbinclude MatrixBase_cast.out - * - * \sa class CwiseUnaryOp, class ei_scalar_cast_op + * \sa class CwiseUnaryOp */ template template @@ -194,7 +208,7 @@ struct ei_scalar_multiple_op { const Scalar m_other; }; -/** \relates MatrixBase \sa class ei_scalar_multiple_op */ +/** \relates MatrixBase */ template const CwiseUnaryOp::Scalar>, Derived> MatrixBase::operator*(const Scalar& scalar) const @@ -203,7 +217,7 @@ MatrixBase::operator*(const Scalar& scalar) const (derived(), ei_scalar_multiple_op(scalar)); } -/** \relates MatrixBase \sa class ei_scalar_multiple_op */ +/** \relates MatrixBase */ template const CwiseUnaryOp::Scalar>, Derived> MatrixBase::operator/(const Scalar& scalar) const @@ -213,7 +227,6 @@ MatrixBase::operator/(const Scalar& scalar) const (derived(), ei_scalar_multiple_op(static_cast(1) / scalar)); } -/** \sa ei_scalar_multiple_op */ template Derived& MatrixBase::operator*=(const Scalar& other) @@ -221,7 +234,6 @@ MatrixBase::operator*=(const Scalar& other) return *this = *this * other; } -/** \sa ei_scalar_multiple_op */ template Derived& MatrixBase::operator/=(const Scalar& other) @@ -229,4 +241,110 @@ MatrixBase::operator/=(const Scalar& other) return *this = *this / other; } +/** \internal + * \brief Template functor to compute the square root of a scalar + * + * \sa class CwiseUnaryOp, MatrixBase::cwiseSqrt() + */ +struct ei_scalar_sqrt_op EIGEN_EMPTY_STRUCT { + template Scalar operator() (const Scalar& a) const { return ei_sqrt(a); } +}; + +/** \returns an expression of the coefficient-wise square root of *this. */ +template +const CwiseUnaryOp +MatrixBase::cwiseSqrt() const +{ + return CwiseUnaryOp(derived()); +} + +/** \internal + * \brief Template functor to compute the exponential of a scalar + * + * \sa class CwiseUnaryOp, MatrixBase::cwiseExp() + */ +struct ei_scalar_exp_op EIGEN_EMPTY_STRUCT { + template Scalar operator() (const Scalar& a) const { return ei_exp(a); } +}; + +/** \returns an expression of the coefficient-wise exponential of *this. */ +template +const CwiseUnaryOp +MatrixBase::cwiseExp() const +{ + return CwiseUnaryOp(derived()); +} + +/** \internal + * \brief Template functor to compute the logarithm of a scalar + * + * \sa class CwiseUnaryOp, MatrixBase::cwiseLog() + */ +struct ei_scalar_log_op EIGEN_EMPTY_STRUCT { + template Scalar operator() (const Scalar& a) const { return ei_log(a); } +}; + +/** \returns an expression of the coefficient-wise logarithm of *this. */ +template +const CwiseUnaryOp +MatrixBase::cwiseLog() const +{ + return CwiseUnaryOp(derived()); +} + +/** \internal + * \brief Template functor to compute the cosine of a scalar + * + * \sa class CwiseUnaryOp, MatrixBase::cwiseCos() + */ +struct ei_scalar_cos_op EIGEN_EMPTY_STRUCT { + template Scalar operator() (const Scalar& a) const { return ei_cos(a); } +}; + +/** \returns an expression of the coefficient-wise cosine of *this. */ +template +const CwiseUnaryOp +MatrixBase::cwiseCos() const +{ + return CwiseUnaryOp(derived()); +} + +/** \internal + * \brief Template functor to compute the sine of a scalar + * + * \sa class CwiseUnaryOp, MatrixBase::cwiseSin() + */ +struct ei_scalar_sin_op EIGEN_EMPTY_STRUCT { + template Scalar operator() (const Scalar& a) const { return ei_sin(a); } +}; + +/** \returns an expression of the coefficient-wise sine of *this. */ +template +const CwiseUnaryOp +MatrixBase::cwiseSin() const +{ + return CwiseUnaryOp(derived()); +} + +/** \internal + * \brief Template functor to raise a scalar to a power + * + * \sa class CwiseUnaryOp, MatrixBase::cwisePow + */ +template +struct ei_scalar_pow_op { + ei_scalar_pow_op(const Scalar& exponent) : m_exponent(exponent) {} + Scalar operator() (const Scalar& a) const { return ei_pow(a, m_exponent); } + const Scalar m_exponent; +}; + +/** \relates MatrixBase */ +template +const CwiseUnaryOp::Scalar>, Derived> +MatrixBase::cwisePow(const Scalar& exponent) const +{ + return CwiseUnaryOp, Derived> + (derived(), ei_scalar_pow_op(exponent)); +} + #endif // EIGEN_CWISE_UNARY_OP_H diff --git a/Eigen/src/Core/ForwardDeclarations.h b/Eigen/src/Core/ForwardDeclarations.h index 114362784..69b8cab7b 100644 --- a/Eigen/src/Core/ForwardDeclarations.h +++ b/Eigen/src/Core/ForwardDeclarations.h @@ -53,6 +53,13 @@ struct ei_scalar_quotient_op; struct ei_scalar_opposite_op; struct ei_scalar_conjugate_op; struct ei_scalar_abs_op; +struct ei_scalar_abs2_op; +struct ei_scalar_sqrt_op; +struct ei_scalar_exp_op; +struct ei_scalar_log_op; +struct ei_scalar_cos_op; +struct ei_scalar_sin_op; +template struct ei_scalar_pow_op; template struct ei_scalar_cast_op; template struct ei_scalar_multiple_op; diff --git a/Eigen/src/Core/MathFunctions.h b/Eigen/src/Core/MathFunctions.h index b320d228f..13bd549f4 100644 --- a/Eigen/src/Core/MathFunctions.h +++ b/Eigen/src/Core/MathFunctions.h @@ -35,14 +35,13 @@ inline int ei_imag(int) { return 0; } inline int ei_conj(int x) { return x; } inline int ei_abs(int x) { return abs(x); } inline int ei_abs2(int x) { return x*x; } -inline int ei_sqrt(int) -{ - // Taking the square root of integers is not allowed - // (the square root does not always exist within the integers). - // Please cast to a floating-point type. - assert(false); - return 0; -} +inline int ei_sqrt(int) { assert(false); return 0; } +inline int ei_exp(int) { assert(false); return 0; } +inline int ei_log(int) { assert(false); return 0; } +inline int ei_sin(int) { assert(false); return 0; } +inline int ei_cos(int) { assert(false); return 0; } +inline int ei_pow(int x, int y) { return std::pow(x, y); } + template<> inline int ei_random(int a, int b) { // We can't just do rand()%n as only the high-order bits are really random @@ -72,6 +71,12 @@ inline float ei_conj(float x) { return x; } inline float ei_abs(float x) { return std::abs(x); } inline float ei_abs2(float x) { return x*x; } inline float ei_sqrt(float x) { return std::sqrt(x); } +inline float ei_exp(float x) { return std::exp(x); } +inline float ei_log(float x) { return std::log(x); } +inline float ei_sin(float x) { return std::sin(x); } +inline float ei_cos(float x) { return std::cos(x); } +inline float ei_pow(float x, float y) { return std::pow(x, y); } + template<> inline float ei_random(float a, float b) { return a + (b-a) * std::rand() / RAND_MAX; @@ -100,6 +105,12 @@ inline double ei_conj(double x) { return x; } inline double ei_abs(double x) { return std::abs(x); } inline double ei_abs2(double x) { return x*x; } inline double ei_sqrt(double x) { return std::sqrt(x); } +inline double ei_exp(double x) { return std::exp(x); } +inline double ei_log(double x) { return std::log(x); } +inline double ei_sin(double x) { return std::sin(x); } +inline double ei_cos(double x) { return std::cos(x); } +inline double ei_pow(double x, double y) { return std::pow(x, y); } + template<> inline double ei_random(double a, double b) { return a + (b-a) * std::rand() / RAND_MAX; @@ -127,14 +138,10 @@ inline float ei_imag(const std::complex& x) { return std::imag(x); } inline std::complex ei_conj(const std::complex& x) { return std::conj(x); } inline float ei_abs(const std::complex& x) { return std::abs(x); } inline float ei_abs2(const std::complex& x) { return std::norm(x); } -inline std::complex ei_sqrt(const std::complex&) -{ - // Taking the square roots of complex numbers is not allowed, - // as this is ambiguous (there are two square roots). - // What were you trying to do? - assert(false); - return 0; -} +inline std::complex ei_exp(std::complex x) { return std::exp(x); } +inline std::complex ei_sin(std::complex x) { return std::sin(x); } +inline std::complex ei_cos(std::complex x) { return std::cos(x); } + template<> inline std::complex ei_random() { return std::complex(ei_random(), ei_random()); @@ -160,6 +167,10 @@ inline double ei_imag(const std::complex& x) { return std::imag(x); } inline std::complex ei_conj(const std::complex& x) { return std::conj(x); } inline double ei_abs(const std::complex& x) { return std::abs(x); } inline double ei_abs2(const std::complex& x) { return std::norm(x); } +inline std::complex ei_exp(std::complex x) { return std::exp(x); } +inline std::complex ei_sin(std::complex x) { return std::sin(x); } +inline std::complex ei_cos(std::complex x) { return std::cos(x); } + template<> inline std::complex ei_random() { return std::complex(ei_random(), ei_random()); @@ -179,21 +190,4 @@ inline bool ei_isApprox(const std::complex& a, const std::complex operator*(U a, const std::complex& b) \ -{ \ - return std::complex(static_cast(a)*b.real(), \ - static_cast(a)*b.imag()); \ -} \ -inline std::complex operator*(const std::complex& b, U a) \ -{ \ - return std::complex(static_cast(a)*b.real(), \ - static_cast(a)*b.imag()); \ -} - -EIGEN_MAKE_MORE_OVERLOADED_COMPLEX_OPERATOR_STAR(int, float) -EIGEN_MAKE_MORE_OVERLOADED_COMPLEX_OPERATOR_STAR(int, double) -EIGEN_MAKE_MORE_OVERLOADED_COMPLEX_OPERATOR_STAR(float, double) -EIGEN_MAKE_MORE_OVERLOADED_COMPLEX_OPERATOR_STAR(double, float) - #endif // EIGEN_MATHFUNCTIONS_H diff --git a/Eigen/src/Core/MatrixBase.h b/Eigen/src/Core/MatrixBase.h index d5f8decee..f51c06d6c 100644 --- a/Eigen/src/Core/MatrixBase.h +++ b/Eigen/src/Core/MatrixBase.h @@ -55,80 +55,76 @@ template class MatrixBase public: + /// \name Compile-time traits + //@{ typedef typename ei_traits::Scalar Scalar; - const Derived& derived() const { return *static_cast(this); } - Derived& derived() { return *static_cast(this); } - Derived& const_cast_derived() const - { return *static_cast(const_cast(this)); } + enum { + RowsAtCompileTime = ei_traits::RowsAtCompileTime, + /**< The number of rows at compile-time. This is just a copy of the value provided + * by the \a Derived type. If a value is not known at compile-time, + * it is set to the \a Dynamic constant. + * \sa MatrixBase::rows(), MatrixBase::cols(), ColsAtCompileTime, SizeAtCompileTime */ - /** The number of rows at compile-time. This is just a copy of the value provided - * by the \a Derived type. If a value is not known at compile-time, - * it is set to the \a Dynamic constant. - * \sa MatrixBase::rows(), MatrixBase::cols(), ColsAtCompileTime, SizeAtCompileTime */ - enum { RowsAtCompileTime = ei_traits::RowsAtCompileTime }; + ColsAtCompileTime = ei_traits::ColsAtCompileTime, + /**< The number of columns at compile-time. This is just a copy of the value provided + * by the \a Derived type. If a value is not known at compile-time, + * it is set to the \a Dynamic constant. + * \sa MatrixBase::rows(), MatrixBase::cols(), RowsAtCompileTime, SizeAtCompileTime */ - /** The number of columns at compile-time. This is just a copy of the value provided - * by the \a Derived type. If a value is not known at compile-time, - * it is set to the \a Dynamic constant. - * \sa MatrixBase::rows(), MatrixBase::cols(), RowsAtCompileTime, SizeAtCompileTime */ - enum { ColsAtCompileTime = ei_traits::ColsAtCompileTime }; + SizeAtCompileTime + = ei_traits::RowsAtCompileTime == Dynamic + || ei_traits::ColsAtCompileTime == Dynamic + ? Dynamic + : ei_traits::RowsAtCompileTime * ei_traits::ColsAtCompileTime, + /**< This is equal to the number of coefficients, i.e. the number of + * rows times the number of columns, or to \a Dynamic if this is not + * known at compile-time. \sa RowsAtCompileTime, ColsAtCompileTime */ + + MaxRowsAtCompileTime = ei_traits::MaxRowsAtCompileTime, + /**< This value is equal to the maximum possible number of rows that this expression + * might have. If this expression might have an arbitrarily high number of rows, + * this value is set to \a Dynamic. + * + * This value is useful to know when evaluating an expression, in order to determine + * whether it is possible to avoid doing a dynamic memory allocation. + * + * \sa RowsAtCompileTime, MaxColsAtCompileTime, MaxSizeAtCompileTime + */ - /** This is equal to the number of coefficients, i.e. the number of - * rows times the number of columns, or to \a Dynamic if this is not - * known at compile-time. \sa RowsAtCompileTime, ColsAtCompileTime */ - enum { SizeAtCompileTime - = ei_traits::RowsAtCompileTime == Dynamic - || ei_traits::ColsAtCompileTime == Dynamic - ? Dynamic - : ei_traits::RowsAtCompileTime * ei_traits::ColsAtCompileTime - }; + MaxColsAtCompileTime = ei_traits::MaxColsAtCompileTime, + /**< This value is equal to the maximum possible number of columns that this expression + * might have. If this expression might have an arbitrarily high number of columns, + * this value is set to \a Dynamic. + * + * This value is useful to know when evaluating an expression, in order to determine + * whether it is possible to avoid doing a dynamic memory allocation. + * + * \sa ColsAtCompileTime, MaxRowsAtCompileTime, MaxSizeAtCompileTime + */ - /** This value is equal to the maximum possible number of rows that this expression - * might have. If this expression might have an arbitrarily high number of rows, - * this value is set to \a Dynamic. - * - * This value is useful to know when evaluating an expression, in order to determine - * whether it is possible to avoid doing a dynamic memory allocation. - * - * \sa RowsAtCompileTime, MaxColsAtCompileTime, MaxSizeAtCompileTime - */ - enum { MaxRowsAtCompileTime = ei_traits::MaxRowsAtCompileTime }; + MaxSizeAtCompileTime + = ei_traits::MaxRowsAtCompileTime == Dynamic + || ei_traits::MaxColsAtCompileTime == Dynamic + ? Dynamic + : ei_traits::MaxRowsAtCompileTime * ei_traits::MaxColsAtCompileTime, + /**< This value is equal to the maximum possible number of coefficients that this expression + * might have. If this expression might have an arbitrarily high number of coefficients, + * this value is set to \a Dynamic. + * + * This value is useful to know when evaluating an expression, in order to determine + * whether it is possible to avoid doing a dynamic memory allocation. + * + * \sa SizeAtCompileTime, MaxRowsAtCompileTime, MaxColsAtCompileTime + */ - /** This value is equal to the maximum possible number of columns that this expression - * might have. If this expression might have an arbitrarily high number of columns, - * this value is set to \a Dynamic. - * - * This value is useful to know when evaluating an expression, in order to determine - * whether it is possible to avoid doing a dynamic memory allocation. - * - * \sa ColsAtCompileTime, MaxRowsAtCompileTime, MaxSizeAtCompileTime - */ - enum { MaxColsAtCompileTime = ei_traits::MaxColsAtCompileTime }; - - /** This value is equal to the maximum possible number of coefficients that this expression - * might have. If this expression might have an arbitrarily high number of coefficients, - * this value is set to \a Dynamic. - * - * This value is useful to know when evaluating an expression, in order to determine - * whether it is possible to avoid doing a dynamic memory allocation. - * - * \sa SizeAtCompileTime, MaxRowsAtCompileTime, MaxColsAtCompileTime - */ - enum { MaxSizeAtCompileTime - = ei_traits::MaxRowsAtCompileTime == Dynamic - || ei_traits::MaxColsAtCompileTime == Dynamic - ? Dynamic - : ei_traits::MaxRowsAtCompileTime * ei_traits::MaxColsAtCompileTime - }; - - /** This is set to true if either the number of rows or the number of - * columns is known at compile-time to be equal to 1. Indeed, in that case, - * we are dealing with a column-vector (if there is only one column) or with - * a row-vector (if there is only one row). */ - enum { IsVectorAtCompileTime - = ei_traits::RowsAtCompileTime == 1 || ei_traits::ColsAtCompileTime == 1 + IsVectorAtCompileTime + = ei_traits::RowsAtCompileTime == 1 || ei_traits::ColsAtCompileTime == 1 + /**< This is set to true if either the number of rows or the number of + * columns is known at compile-time to be equal to 1. Indeed, in that case, + * we are dealing with a column-vector (if there is only one column) or with + * a row-vector (if there is only one row). */ }; /** This is the "real scalar" type; if the \a Scalar type is already real numbers @@ -141,13 +137,14 @@ template class MatrixBase * \sa class NumTraits */ typedef typename NumTraits::Real RealScalar; + //@} - /// \name matrix properties + /// \name Run-time traits //@{ /** \returns the number of rows. \sa cols(), RowsAtCompileTime */ - int rows() const { return static_cast(this)->_rows(); } + int rows() const { return derived()._rows(); } /** \returns the number of columns. \sa row(), ColsAtCompileTime*/ - int cols() const { return static_cast(this)->_cols(); } + int cols() const { return derived()._cols(); } /** \returns the number of coefficients, which is \a rows()*cols(). * \sa rows(), cols(), SizeAtCompileTime. */ int size() const { return rows() * cols(); } @@ -158,6 +155,9 @@ template class MatrixBase bool isVector() const { return rows()==1 || cols()==1; } //@} + /// \name Copying and initialization + //@{ + /** Copies \a other into *this. \returns a reference to *this. */ template Derived& operator=(const MatrixBase& other); @@ -174,17 +174,96 @@ template class MatrixBase template CommaInitializer operator<< (const MatrixBase& other); + //@} - /** 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. + /// \name Coefficient accessors + //@{ + Scalar coeff(int row, int col) const; + Scalar operator()(int row, int col) const; + + Scalar& coeffRef(int row, int col); + Scalar& operator()(int row, int col); + + Scalar coeff(int index) const; + Scalar operator[](int index) const; + + Scalar& coeffRef(int index); + Scalar& operator[](int index); + + Scalar x() const; + Scalar y() const; + Scalar z() const; + Scalar w() const; + Scalar& x(); + Scalar& y(); + Scalar& z(); + Scalar& w(); + //@} + + /** \name Linear structure + * sum, scalar multiple, ... */ - template - void swap(const MatrixBase& other); + //@{ + const CwiseUnaryOp operator-() const; - /// \name sub-matrices + template + const CwiseBinaryOp + operator+(const MatrixBase &other) const; + + template + const CwiseBinaryOp + operator-(const MatrixBase &other) const; + + template + Derived& operator+=(const MatrixBase& other); + template + Derived& operator-=(const MatrixBase& other); + + Derived& operator*=(const Scalar& other); + Derived& operator/=(const Scalar& other); + + const CwiseUnaryOp, Derived> operator*(const Scalar& scalar) const; + const CwiseUnaryOp, Derived> operator/(const Scalar& scalar) const; + + friend const CwiseUnaryOp, Derived> + operator*(const Scalar& scalar, const MatrixBase& matrix) + { return matrix*scalar; } + //@} + + /** \name Matrix product and related notions + * including the trace... + */ + //@{ + template + const Product + lazyProduct(const MatrixBase& other) const; + + template + const Eval > + operator*(const MatrixBase &other) const; + + template + Derived& operator*=(const MatrixBase& other); + + Scalar trace() const; + //@} + + /** \name Dot product and related notions + * including vector norm, adjoint, transpose ... + */ + //@{ + template + Scalar dot(const MatrixBase& other) const; + RealScalar norm2() const; + RealScalar norm() const; + const CwiseUnaryOp, Derived> normalized() const; + + Transpose transpose(); + const Transpose transpose() const; + const Transpose > adjoint() const; + //@} + + /// \name Sub-matrices //@{ Block::ColsAtCompileTime> row(int i); const Block::ColsAtCompileTime> row(int i) const; @@ -220,33 +299,8 @@ template class MatrixBase const DiagonalCoeffs diagonal() const; //@} - /// \name matrix transformation + /// \name Generating special matrices //@{ - template - const CwiseUnaryOp, Derived> cast() const; - - const DiagonalMatrix asDiagonal() const; - - Transpose transpose(); - const Transpose transpose() const; - - const CwiseUnaryOp conjugate() const; - const Transpose > adjoint() const; - - const CwiseUnaryOp, Derived> normalized() const; - //@} - - // FIXME not sure about the following name - /// \name metrics - //@{ - Scalar trace() const; - - template - Scalar dot(const MatrixBase& other) const; - RealScalar norm2() const; - RealScalar norm() const; - //@} - static const Eval > random(int rows, int cols); static const Eval > random(int size); static const Eval > random(); @@ -259,13 +313,25 @@ template class MatrixBase static const Identity identity(); static const Identity identity(int rows, int cols); + const DiagonalMatrix asDiagonal() const; + Derived& setZero(); Derived& setOnes(); Derived& setRandom(); Derived& setIdentity(); + //@} - /// \name matrix diagnostic and comparison + /// \name Comparison and diagnostic //@{ + template + bool isApprox(const OtherDerived& other, + RealScalar prec = precision()) const; + bool isMuchSmallerThan(const RealScalar& other, + RealScalar prec = precision()) const; + template + bool isMuchSmallerThan(const MatrixBase& other, + RealScalar prec = precision()) const; + bool isZero(RealScalar prec = precision()) const; bool isOnes(RealScalar prec = precision()) const; bool isIdentity(RealScalar prec = precision()) const; @@ -276,89 +342,6 @@ template class MatrixBase RealScalar prec = precision()) const; bool isOrtho(RealScalar prec = precision()) const; - template - bool isApprox(const OtherDerived& other, - RealScalar prec = precision()) const; - bool isMuchSmallerThan(const RealScalar& other, - RealScalar prec = precision()) const; - template - bool isMuchSmallerThan(const MatrixBase& other, - RealScalar prec = precision()) const; - //@} - - /// \name arithemetic operators - //@{ - const CwiseUnaryOp operator-() const; - - template - Derived& operator+=(const MatrixBase& other); - template - Derived& operator-=(const MatrixBase& other); - template - Derived& operator*=(const MatrixBase& other); - - Derived& operator*=(const Scalar& other); - Derived& operator/=(const Scalar& other); - - const CwiseUnaryOp, Derived> operator*(const Scalar& scalar) const; - const CwiseUnaryOp, Derived> operator/(const Scalar& scalar) const; - - friend const CwiseUnaryOp, Derived> - operator*(const Scalar& scalar, 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 coefficient accessors - //@{ - Scalar coeff(int row, int col) const; - Scalar operator()(int row, int col) const; - - Scalar& coeffRef(int row, int col); - Scalar& operator()(int row, int col); - - Scalar coeff(int index) const; - Scalar operator[](int index) const; - - Scalar& coeffRef(int index); - Scalar& operator[](int index); - - Scalar x() const; - Scalar y() const; - Scalar z() const; - Scalar w() const; - Scalar& x(); - Scalar& y(); - Scalar& z(); - Scalar& w(); - //@} - - /// \name special functions - //@{ - const Eval eval() const EIGEN_ALWAYS_INLINE; - const EvalOMP evalOMP() const EIGEN_ALWAYS_INLINE; - - template - const CwiseUnaryOp cwise(const CustomUnaryOp& func = CustomUnaryOp()) const; - - template - const CwiseBinaryOp - cwise(const MatrixBase &other, const CustomBinaryOp& func = CustomBinaryOp()) const; - //@} - /** puts in *row and *col the location of the coefficient of *this * which has the biggest absolute value. */ @@ -377,6 +360,63 @@ template class MatrixBase } } } + //@} + + /// \name Special functions + //@{ + template + const CwiseUnaryOp, Derived> cast() const; + + const Eval eval() const EIGEN_ALWAYS_INLINE; + const EvalOMP evalOMP() const EIGEN_ALWAYS_INLINE; + + /** 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 Coefficient-wise operations + //@{ + const CwiseUnaryOp conjugate() const; + + template + const CwiseBinaryOp + cwiseProduct(const MatrixBase &other) const; + + template + const CwiseBinaryOp + cwiseQuotient(const MatrixBase &other) const; + + const CwiseUnaryOp cwiseAbs() const; + const CwiseUnaryOp cwiseAbs2() const; + const CwiseUnaryOp cwiseSqrt() const; + const CwiseUnaryOp cwiseExp() const; + const CwiseUnaryOp cwiseLog() const; + const CwiseUnaryOp cwiseCos() const; + const CwiseUnaryOp cwiseSin() const; + const CwiseUnaryOp::Scalar>, Derived> + cwisePow(const Scalar& exponent) const; + + template + const CwiseUnaryOp cwise(const CustomUnaryOp& func = CustomUnaryOp()) const; + + template + const CwiseBinaryOp + cwise(const MatrixBase &other, const CustomBinaryOp& func = CustomBinaryOp()) const; + //@} + + /// \name Casting to the derived type + //@{ + const Derived& derived() const { return *static_cast(this); } + Derived& derived() { return *static_cast(this); } + Derived& const_cast_derived() const + { return *static_cast(const_cast(this)); } + //@} }; diff --git a/Eigen/src/Core/Product.h b/Eigen/src/Core/Product.h index cbc60f1ed..4999a1a4e 100644 --- a/Eigen/src/Core/Product.h +++ b/Eigen/src/Core/Product.h @@ -144,21 +144,19 @@ MatrixBase::lazyProduct(const MatrixBase &other) const return Product(derived(), other.derived()); } -/** \relates MatrixBase - * - * \returns the matrix product of \a mat1 and \a mat2. More precisely, the return statement is: - * \code return mat1.lazyProduct(mat2).eval(); \endcode +/** \returns the matrix product of \c *this and \a other. * * \note This function causes an immediate evaluation. If you want to perform a matrix product * without immediate evaluation, use MatrixBase::lazyProduct() instead. * - * \sa MatrixBase::lazyProduct(), MatrixBase::operator*=(const MatrixBase&) + * \sa lazyProduct(), operator*=(const MatrixBase&) */ -template -const Eval > -operator*(const MatrixBase &mat1, const MatrixBase &mat2) +template +template +const Eval > +MatrixBase::operator*(const MatrixBase &other) const { - return mat1.lazyProduct(mat2).eval(); + return lazyProduct(other).eval(); } /** replaces \c *this by \c *this * \a other. diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in index a8dc339c1..ec3841482 100644 --- a/doc/Doxyfile.in +++ b/doc/Doxyfile.in @@ -70,7 +70,7 @@ GENERATE_TESTLIST = YES GENERATE_BUGLIST = YES GENERATE_DEPRECATEDLIST= YES ENABLED_SECTIONS = -MAX_INITIALIZER_LINES = 30 +MAX_INITIALIZER_LINES = 0 SHOW_USED_FILES = YES SHOW_DIRECTORIES = NO FILE_VERSION_FILTER = @@ -91,9 +91,9 @@ INPUT = ${CMAKE_SOURCE_DIR}/doc ${CMAKE_SOURCE_DIR}/Eigen INPUT_ENCODING = UTF-8 FILE_PATTERNS = * RECURSIVE = NO -EXCLUDE = CMake* *.txt +EXCLUDE = EXCLUDE_SYMLINKS = NO -EXCLUDE_PATTERNS = +EXCLUDE_PATTERNS = CMake* *.txt *~ EXCLUDE_SYMBOLS = EXAMPLE_PATH = ${CMAKE_SOURCE_DIR}/doc/snippets \ ${CMAKE_BINARY_DIR}/doc/snippets \ @@ -140,7 +140,7 @@ GENERATE_CHI = NO BINARY_TOC = NO TOC_EXPAND = NO DISABLE_INDEX = NO -ENUM_VALUES_PER_LINE = 4 +ENUM_VALUES_PER_LINE = 1 GENERATE_TREEVIEW = NO TREEVIEW_WIDTH = 250 #--------------------------------------------------------------------------- diff --git a/doc/examples/class_Block.cpp b/doc/examples/class_Block.cpp index fd5ae816c..79cc314bf 100644 --- a/doc/examples/class_Block.cpp +++ b/doc/examples/class_Block.cpp @@ -6,14 +6,14 @@ template Eigen::Block topLeftCorner(MatrixBase& m, int rows, int cols) { - return Eigen::Block(m, 0, 0, rows, cols); + return Eigen::Block(m.derived(), 0, 0, rows, cols); } template const Eigen::Block topLeftCorner(const MatrixBase& m, int rows, int cols) { - return Eigen::Block(m, 0, 0, rows, cols); + return Eigen::Block(m.derived(), 0, 0, rows, cols); } int main(int, char**) diff --git a/doc/examples/class_Cast.cpp b/doc/examples/class_Cast.cpp deleted file mode 100644 index 7e752be1b..000000000 --- a/doc/examples/class_Cast.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include -USING_PART_OF_NAMESPACE_EIGEN -using namespace std; - -template -const Eigen::CwiseUnaryOp< - Eigen::ei_scalar_cast_op< - typename Eigen::ei_traits::FloatingPoint - >, Derived -> -castToFloatingPoint(const MatrixBase& m) -{ - return m.template cast< - typename Eigen::ei_traits< - typename Derived::Scalar - >::FloatingPoint - >(); -} - -int main(int, char**) -{ - Matrix2i m = Matrix2i::random(); - cout << "Here's the matrix m. It has coefficients of type int." - << endl << m << endl; - cout << "Here's m/20:" << endl << castToFloatingPoint(m)/20 << endl; - return 0; -} diff --git a/doc/examples/class_Column.cpp b/doc/examples/class_Column.cpp deleted file mode 100644 index 1394324fa..000000000 --- a/doc/examples/class_Column.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include -USING_PART_OF_NAMESPACE_EIGEN -using namespace std; - -template -Eigen::Block -firstColumn(MatrixBase& m) -{ - return typename Eigen::Block(m, 0); -} - -template -const Eigen::Block -firstColumn(const MatrixBase& m) -{ - return typename Eigen::Block(m, 0); -} - -int main(int, char**) -{ - Matrix4d m = Matrix4d::identity(); - cout << firstColumn(2*m) << endl; // calls the const version - firstColumn(m) *= 5; // calls the non-const version - cout << "Now the matrix m is:" << endl << m << endl; - return 0; -} diff --git a/doc/examples/class_FixedBlock.cpp b/doc/examples/class_FixedBlock.cpp index 644f420bd..e3e9532bc 100644 --- a/doc/examples/class_FixedBlock.cpp +++ b/doc/examples/class_FixedBlock.cpp @@ -6,14 +6,14 @@ template Eigen::Block topLeft2x2Corner(MatrixBase& m) { - return Eigen::Block(m, 0, 0); + return Eigen::Block(m.derived(), 0, 0); } template const Eigen::Block topLeft2x2Corner(const MatrixBase& m) { - return Eigen::Block(m, 0, 0); + return Eigen::Block(m.derived(), 0, 0); } int main(int, char**) diff --git a/doc/examples/class_Row.cpp b/doc/examples/class_Row.cpp deleted file mode 100644 index eed1dbdb4..000000000 --- a/doc/examples/class_Row.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include -USING_PART_OF_NAMESPACE_EIGEN -using namespace std; - -template -Eigen::Block -firstRow(MatrixBase& m) -{ - return Eigen::Block(m, 0); -} - -template -const Eigen::Block -firstRow(const MatrixBase& m) -{ - return Eigen::Block(m, 0); -} - -int main(int, char**) -{ - Matrix4d m = Matrix4d::identity(); - cout << firstRow(2*m) << endl; // calls the const version - firstRow(m) *= 5; // calls the non-const version - cout << "Now the matrix m is:" << endl << m << endl; - return 0; -}