From 0be89a4796543a7e7b8c244d3f1aabcf672cf114 Mon Sep 17 00:00:00 2001 From: Gael Guennebaud Date: Thu, 5 Mar 2009 10:25:22 +0000 Subject: [PATCH] big addons: * add Homogeneous expression for vector and set of vectors (aka matrix) => the next step will be to overload operator* * add homogeneous normalization (again for vector and set of vectors) * add a Replicate expression (with uni-directional replication facilities) => for all of them I'll add examples once we agree on the API * fix gcc-4.4 warnings * rename reverse.cpp array_reverse.cpp --- Eigen/Array | 1 + Eigen/Core | 3 +- Eigen/Geometry | 1 + Eigen/src/Array/PartialRedux.h | 38 +++- Eigen/src/Array/Replicate.h | 159 +++++++++++++++++ Eigen/src/Core/Functors.h | 2 +- Eigen/src/Core/MatrixBase.h | 23 ++- Eigen/src/Core/ReturnByValue.h | 26 ++- Eigen/src/Core/products/GeneralMatrixMatrix.h | 1 + Eigen/src/Core/products/GeneralMatrixVector.h | 43 +++-- .../Core/products/SelfadjointMatrixVector.h | 31 ---- Eigen/src/Core/util/Constants.h | 8 + Eigen/src/Core/util/ForwardDeclarations.h | 6 +- Eigen/src/Core/util/XprHelper.h | 13 ++ Eigen/src/Geometry/Homogeneous.h | 168 ++++++++++++++++++ test/CMakeLists.txt | 4 +- test/array_replicate.cpp | 86 +++++++++ test/{reverse.cpp => array_reverse.cpp} | 2 +- test/geo_homogeneous.cpp | 79 ++++++++ test/packetmath.cpp | 4 +- 20 files changed, 623 insertions(+), 75 deletions(-) create mode 100644 Eigen/src/Array/Replicate.h create mode 100644 Eigen/src/Geometry/Homogeneous.h create mode 100644 test/array_replicate.cpp rename test/{reverse.cpp => array_reverse.cpp} (99%) create mode 100644 test/geo_homogeneous.cpp diff --git a/Eigen/Array b/Eigen/Array index eb61e7152..57bd39e9e 100644 --- a/Eigen/Array +++ b/Eigen/Array @@ -35,6 +35,7 @@ namespace Eigen { #include "src/Array/PartialRedux.h" #include "src/Array/Random.h" #include "src/Array/Norms.h" +#include "src/Array/Replicate.h" #include "src/Array/Reverse.h" } // namespace Eigen diff --git a/Eigen/Core b/Eigen/Core index e75b90931..89531e8da 100644 --- a/Eigen/Core +++ b/Eigen/Core @@ -129,7 +129,6 @@ namespace Eigen { #include "src/Core/CwiseUnaryOp.h" #include "src/Core/CwiseNullaryOp.h" #include "src/Core/Dot.h" -#include "src/Core/Product.h" #include "src/Core/DiagonalProduct.h" #include "src/Core/SolveTriangular.h" #include "src/Core/MapBase.h" @@ -146,9 +145,11 @@ namespace Eigen { #include "src/Core/Swap.h" #include "src/Core/CommaInitializer.h" #include "src/Core/Part.h" +#include "src/Core/Product.h" #include "src/Core/products/GeneralMatrixMatrix.h" #include "src/Core/products/GeneralMatrixVector.h" #include "src/Core/products/SelfadjointMatrixVector.h" +#include "src/Core/products/SelfadjointRank2Update.h" } // namespace Eigen diff --git a/Eigen/Geometry b/Eigen/Geometry index 617b25eb6..61aa70a91 100644 --- a/Eigen/Geometry +++ b/Eigen/Geometry @@ -32,6 +32,7 @@ namespace Eigen { */ #include "src/Geometry/OrthoMethods.h" +#include "src/Geometry/Homogeneous.h" #include "src/Geometry/RotationBase.h" #include "src/Geometry/Rotation2D.h" #include "src/Geometry/Quaternion.h" diff --git a/Eigen/src/Array/PartialRedux.h b/Eigen/src/Array/PartialRedux.h index d1ed33c38..37fe2b70f 100644 --- a/Eigen/src/Array/PartialRedux.h +++ b/Eigen/src/Array/PartialRedux.h @@ -175,8 +175,6 @@ template class PartialRedux > Type; }; - typedef typename ExpressionType::PlainMatrixType CrossReturnType; - inline PartialRedux(const ExpressionType& matrix) : m_matrix(matrix) {} /** \internal */ @@ -282,9 +280,45 @@ template class PartialRedux { return Reverse( _expression() ); } + +/////////// Geometry module /////////// + const Homogeneous homogeneous() const; + + const Replicate + replicate(int factor) const; + + template + const Replicate + replicate() const; + + typedef typename ExpressionType::PlainMatrixType CrossReturnType; template const CrossReturnType cross(const MatrixBase& other) const; + + enum { + HNormalized_Size = Direction==Vertical ? ei_traits::RowsAtCompileTime + : ei_traits::ColsAtCompileTime, + HNormalized_SizeMinusOne = HNormalized_Size==Dynamic ? Dynamic : HNormalized_Size-1 + }; + typedef Block::RowsAtCompileTime), + Direction==Horizontal ? int(HNormalized_SizeMinusOne) + : int(ei_traits::ColsAtCompileTime)> + HNormalized_Block; + typedef Block::RowsAtCompileTime), + Direction==Horizontal ? 1 : int(ei_traits::ColsAtCompileTime)> + HNormalized_Factors; + typedef CwiseBinaryOp::Scalar>, + NestByValue, + NestByValue, + Direction==Vertical ? HNormalized_SizeMinusOne : 1, + Direction==Horizontal ? HNormalized_SizeMinusOne : 1> > > + HNormalizedReturnType; + + const HNormalizedReturnType hnormalized() const; protected: ExpressionTypeNested m_matrix; diff --git a/Eigen/src/Array/Replicate.h b/Eigen/src/Array/Replicate.h new file mode 100644 index 000000000..09d64d067 --- /dev/null +++ b/Eigen/src/Array/Replicate.h @@ -0,0 +1,159 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. Eigen itself is part of the KDE project. +// +// Copyright (C) 2009 Gael Guennebaud +// +// 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_REPLICATE_H +#define EIGEN_REPLICATE_H + +/** \nonstableyet + * \class Replicate + * + * \brief Expression of the multiple replication of a matrix or vector + * + * \param MatrixType the type of the object we are replicating + * + * This class represents an expression of the multiple replication of a matrix or vector. + * It is the return type of MatrixBase::replicate() and most of the time + * this is the only way it is used. + * + * \sa MatrixBase::replicate() + */ +template +struct ei_traits > +{ + typedef typename MatrixType::Scalar Scalar; + typedef typename ei_nested::type MatrixTypeNested; + typedef typename ei_unref::type _MatrixTypeNested; + enum { + RowsPlusOne = (MatrixType::RowsAtCompileTime != Dynamic) ? + int(MatrixType::RowsAtCompileTime) + 1 : Dynamic, + ColsPlusOne = (MatrixType::ColsAtCompileTime != Dynamic) ? + int(MatrixType::ColsAtCompileTime) + 1 : Dynamic, + RowsAtCompileTime = RowFactor==Dynamic || MatrixType::RowsAtCompileTime==Dynamic + ? Dynamic + : RowFactor * MatrixType::RowsAtCompileTime, + ColsAtCompileTime = ColFactor==Dynamic || MatrixType::ColsAtCompileTime==Dynamic + ? Dynamic + : ColFactor * MatrixType::ColsAtCompileTime, + MaxRowsAtCompileTime = RowsAtCompileTime, + MaxColsAtCompileTime = ColsAtCompileTime, + Flags = _MatrixTypeNested::Flags & HereditaryBits, + CoeffReadCost = _MatrixTypeNested::CoeffReadCost + }; +}; + +template class Replicate + : public MatrixBase > +{ + public: + + EIGEN_GENERIC_PUBLIC_INTERFACE(Replicate) + + inline Replicate(const MatrixType& matrix) + : m_matrix(matrix) + { + ei_assert(RowFactor!=Dynamic && ColFactor!=Dynamic); + } + + inline Replicate(const MatrixType& matrix, int rowFactor, int colFactor) + : m_matrix(matrix), m_rowFactor(rowFactor), m_colFactor(colFactor) + {} + + inline int rows() const { return m_matrix.rows() * m_rowFactor.value(); } + inline int cols() const { return m_matrix.cols() * m_colFactor.value(); } + + inline Scalar coeff(int row, int col) const + { + return m_matrix.coeff(row%m_matrix.rows(), col%m_matrix.cols()); + } + + protected: + const typename MatrixType::Nested m_matrix; + const ei_int_if_dynamic m_rowFactor; + const ei_int_if_dynamic m_colFactor; +}; + +/** \nonstableyet + * \return an expression of the replication of \c *this + * + * Example: \include MatrixBase_replicate.cpp + * Output: \verbinclude MatrixBase_replicate.out + * + * \sa PartialRedux::replicate(), MatrixBase::replicate(int,int), class Replicate + */ +template +template +inline const Replicate +MatrixBase::replicate() const +{ + return derived(); +} + +/** \nonstableyet + * \return an expression of the replication of \c *this + * + * Example: \include MatrixBase_replicate_int_int.cpp + * Output: \verbinclude MatrixBase_replicate_int_int.out + * + * \sa PartialRedux::replicate(), MatrixBase::replicate(), class Replicate + */ +template +inline const Replicate +MatrixBase::replicate(int rowFactor,int colFactor) const +{ + return Replicate(derived(),rowFactor,colFactor); +} + +/** \nonstableyet + * \return an expression of the replication of each column (or row) of \c *this + * + * Example: \include DirectionWise_replicate_int.cpp + * Output: \verbinclude DirectionWise_replicate_int.out + * + * \sa PartialRedux::replicate(), MatrixBase::replicate(), class Replicate + */ +template +const Replicate +PartialRedux::replicate(int factor) const +{ + return Replicate + (_expression(),Direction==Vertical?factor:1,Direction==Horizontal?factor:1); +} + +/** \nonstableyet + * \return an expression of the replication of each column (or row) of \c *this + * + * Example: \include DirectionWise_replicate.cpp + * Output: \verbinclude DirectionWise_replicate.out + * + * \sa PartialRedux::replicate(int), MatrixBase::replicate(), class Replicate + */ +template +template +const Replicate +PartialRedux::replicate() const +{ + return _expression(); +} + +#endif // EIGEN_REPLICATE_H diff --git a/Eigen/src/Core/Functors.h b/Eigen/src/Core/Functors.h index 57a055662..41e94e28d 100644 --- a/Eigen/src/Core/Functors.h +++ b/Eigen/src/Core/Functors.h @@ -299,7 +299,7 @@ struct ei_functor_traits > * indeed it seems better to declare m_other as a PacketScalar and do the ei_pset1() once * in the constructor. However, in practice: * - GCC does not like m_other as a PacketScalar and generate a load every time it needs it - * - one the other hand GCC is able to moves the ei_pset1() away the loop :) + * - on the other hand GCC is able to moves the ei_pset1() away the loop :) * - simpler code ;) * (ICC and gcc 4.4 seems to perform well in both cases, the issue is visible with y = a*x + b*y) */ diff --git a/Eigen/src/Core/MatrixBase.h b/Eigen/src/Core/MatrixBase.h index 3a7f1a3e0..9b54ac28c 100644 --- a/Eigen/src/Core/MatrixBase.h +++ b/Eigen/src/Core/MatrixBase.h @@ -360,10 +360,6 @@ template class MatrixBase void transposeInPlace(); const AdjointReturnType adjoint() const; - Eigen::Reverse reverse(); - const Eigen::Reverse reverse() const; - void reverseInPlace(); - RowXpr row(int i); const RowXpr row(int i) const; @@ -589,6 +585,14 @@ template class MatrixBase select(typename ElseDerived::Scalar thenScalar, const MatrixBase& elseMatrix) const; template RealScalar lpNorm() const; + + template + const Replicate replicate() const; + const Replicate replicate(int rowFacor,int colFactor) const; + + Eigen::Reverse reverse(); + const Eigen::Reverse reverse() const; + void reverseInPlace(); /////////// LU module /////////// @@ -620,6 +624,17 @@ template class MatrixBase PlainMatrixType unitOrthogonal(void) const; Matrix eulerAngles(int a0, int a1, int a2) const; const ScalarMultipleReturnType operator*(const UniformScaling& s) const; + enum { + SizeMinusOne = SizeAtCompileTime==Dynamic ? Dynamic : SizeAtCompileTime-1 + }; + typedef Block::ColsAtCompileTime==1 ? SizeMinusOne : 1, + ei_traits::ColsAtCompileTime==1 ? 1 : SizeMinusOne> StartMinusOne; + typedef CwiseUnaryOp::Scalar>, + NestByValue > HNormalizedReturnType; + + const HNormalizedReturnType hnormalized() const; + const Homogeneous::ColsAtCompileTime==1?Vertical:Horizontal> homogeneous() const; /////////// Sparse module /////////// diff --git a/Eigen/src/Core/ReturnByValue.h b/Eigen/src/Core/ReturnByValue.h index e6d2b0d01..3613782ac 100644 --- a/Eigen/src/Core/ReturnByValue.h +++ b/Eigen/src/Core/ReturnByValue.h @@ -28,28 +28,38 @@ /** \class ReturnByValue * */ -template -struct ei_traits > : public ei_traits +template +struct ei_traits > > + : public ei_traits > { enum { - Flags = ei_traits::Flags | EvalBeforeNestingBit + Flags = ei_traits >::Flags | EvalBeforeNestingBit }; }; -template -struct ei_nested, n, EvalType> +template +struct ei_nested >, n, EvalTypeDerived> { - typedef EvalType type; + typedef EvalTypeDerived type; }; template class ReturnByValue - : public MatrixBase > +{ + public: + template + inline void evalTo(Dest& dst) const + { static_cast(this)->evalTo(dst); } +}; + +template + class ReturnByValue > + : public MatrixBase > > { public: EIGEN_GENERIC_PUBLIC_INTERFACE(ReturnByValue) template inline void evalTo(Dest& dst) const - { static_cast(this)->evalTo(dst); } + { static_cast(this)->evalTo(dst); } }; template diff --git a/Eigen/src/Core/products/GeneralMatrixMatrix.h b/Eigen/src/Core/products/GeneralMatrixMatrix.h index 7ec33d7f4..3543de9b8 100644 --- a/Eigen/src/Core/products/GeneralMatrixMatrix.h +++ b/Eigen/src/Core/products/GeneralMatrixMatrix.h @@ -262,6 +262,7 @@ static void ei_cache_friendly_product( blB += 4*nr*PacketSize; blA += 4*mr; } + // process remaining peeled loop for(int k=peeled_kc; k::type Packet; const int PacketSize = sizeof(Packet)/sizeof(Scalar); @@ -125,11 +124,11 @@ static EIGEN_DONT_INLINE void ei_cache_friendly_product_colmajor_times_vector( { case AllAligned: for (int j = alignedStart; j1) @@ -165,11 +164,11 @@ static EIGEN_DONT_INLINE void ei_cache_friendly_product_colmajor_times_vector( } } for (int j = peeledSize; j::type Packet; const int PacketSize = sizeof(Packet)/sizeof(Scalar); @@ -319,11 +318,11 @@ static EIGEN_DONT_INLINE void ei_cache_friendly_product_rowmajor_times_vector( { case AllAligned: for (int j = alignedStart; j1) @@ -362,11 +361,11 @@ static EIGEN_DONT_INLINE void ei_cache_friendly_product_rowmajor_times_vector( } } for (int j = peeledSize; j::Flags&DirectAccessBit ? DirectAccessBit : ei_traits::Flags&SparseBit> class Block; template class Transpose; -template class Reverse; template class Conjugate; template class CwiseNullaryOp; template class CwiseUnaryOp; @@ -104,6 +103,8 @@ void ei_cache_friendly_product( template class Select; template class PartialReduxExpr; template class PartialRedux; +template class Replicate; +template class Reverse; template class LU; template class QR; @@ -117,11 +118,12 @@ template class Cross; template class Quaternion; template class Rotation2D; template class AngleAxis; -template class Transform; +template class Transform; template class ParametrizedLine; template class Hyperplane; template class Translation; template class UniformScaling; +template class Homogeneous; // Sparse module: template class SparseProduct; diff --git a/Eigen/src/Core/util/XprHelper.h b/Eigen/src/Core/util/XprHelper.h index 12d6f9a3a..82e32f1f5 100644 --- a/Eigen/src/Core/util/XprHelper.h +++ b/Eigen/src/Core/util/XprHelper.h @@ -211,6 +211,19 @@ template stru typedef Block Type; }; +template struct HNormalizedReturnType { + + enum { + SizeAtCompileTime = ExpressionType::SizeAtCompileTime, + SizeMinusOne = SizeAtCompileTime==Dynamic ? Dynamic : SizeAtCompileTime-1 + }; + typedef Block::ColsAtCompileTime==1 ? SizeMinusOne : 1, + ei_traits::ColsAtCompileTime==1 ? 1 : SizeMinusOne> StartMinusOne; + typedef CwiseUnaryOp::Scalar>, + NestByValue > Type; +}; + template struct ei_cast_return_type { typedef typename ei_meta_if::ret,const CurrentType&,NewType>::ret type; diff --git a/Eigen/src/Geometry/Homogeneous.h b/Eigen/src/Geometry/Homogeneous.h new file mode 100644 index 000000000..7e1114474 --- /dev/null +++ b/Eigen/src/Geometry/Homogeneous.h @@ -0,0 +1,168 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. Eigen itself is part of the KDE project. +// +// Copyright (C) 2009 Gael Guennebaud +// +// 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_HOMOGENEOUS_H +#define EIGEN_HOMOGENEOUS_H + +/** \geometry_module \ingroup Geometry_Module + * \nonstableyet + * \class Homogeneous + * + * \brief Expression of one (or a set of) homogeneous vector(s) + * + * \param MatrixType the type of the object in which we are making homogeneous + * + * This class represents an expression of one (or a set of) homogeneous vector(s). + * It is the return type of MatrixBase::homogeneous() and most of the time + * this is the only way it is used. + * + * \sa MatrixBase::homogeneous() + */ +template +struct ei_traits > +{ + typedef typename MatrixType::Scalar Scalar; + typedef typename ei_nested::type MatrixTypeNested; + typedef typename ei_unref::type _MatrixTypeNested; + enum { + RowsPlusOne = (MatrixType::RowsAtCompileTime != Dynamic) ? + int(MatrixType::RowsAtCompileTime) + 1 : Dynamic, + ColsPlusOne = (MatrixType::ColsAtCompileTime != Dynamic) ? + int(MatrixType::ColsAtCompileTime) + 1 : Dynamic, + RowsAtCompileTime = Direction==Vertical ? RowsPlusOne : MatrixType::RowsAtCompileTime, + ColsAtCompileTime = Direction==Horizontal ? ColsPlusOne : MatrixType::ColsAtCompileTime, + MaxRowsAtCompileTime = RowsAtCompileTime, + MaxColsAtCompileTime = ColsAtCompileTime, + Flags = _MatrixTypeNested::Flags & HereditaryBits, + CoeffReadCost = _MatrixTypeNested::CoeffReadCost + }; +}; + +template class Homogeneous + : public MatrixBase > +{ + public: + + EIGEN_GENERIC_PUBLIC_INTERFACE(Homogeneous) + + inline Homogeneous(const MatrixType& matrix) + : m_matrix(matrix) + {} + + inline int rows() const { return m_matrix.rows() + (Direction==Vertical ? 1 : 0); } + inline int cols() const { return m_matrix.cols() + (Direction==Horizontal ? 1 : 0); } + + inline Scalar coeff(int row, int col) const + { + if( (Direction==Vertical && row==m_matrix.rows()) + || (Direction==Horizontal && col==m_matrix.cols())) + return 1; + return m_matrix.coeff(row, col); + } + + protected: + const typename MatrixType::Nested m_matrix; +}; + +/** \geometry_module + * \nonstableyet + * \return an expression of the equivalent homogeneous vector + * + * \vectoronly + * + * Example: \include MatrixBase_homogeneous.cpp + * Output: \verbinclude MatrixBase_homogeneous.out + * + * \sa class Homogeneous + */ +template +inline const Homogeneous::ColsAtCompileTime==1?Vertical:Horizontal> +MatrixBase::homogeneous() const +{ + EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived); + return derived(); +} + +/** \geometry_module + * \nonstableyet + * \returns a matrix expression of homogeneous column (or row) vectors + * + * Example: \include PartialRedux_homogeneous.cpp + * Output: \verbinclude PartialRedux_homogeneous.out + * + * \sa MatrixBase::homogeneous() */ +template +inline const Homogeneous +PartialRedux::homogeneous() const +{ + return _expression(); +} + +/** \geometry_module + * \nonstableyet + * \returns an expression of the homogeneous normalized vector of \c *this + * + * Example: \include MatrixBase_hnormalized.cpp + * Output: \verbinclude MatrixBase_hnormalized.out + * + * \sa PartialRedux::hnormalized() */ +template +inline const typename MatrixBase::HNormalizedReturnType +MatrixBase::hnormalized() const +{ + EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived); + return StartMinusOne(derived(),0,0, + ColsAtCompileTime==1?size()-1:1, + ColsAtCompileTime==1?1:size()-1).nestByValue() / coeff(size()-1); +} + +/** \geometry_module + * \nonstableyet + * \returns an expression of the homogeneous normalized vector of \c *this + * + * Example: \include DirectionWise_hnormalized.cpp + * Output: \verbinclude DirectionWise_hnormalized.out + * + * \sa MatrixBase::hnormalized() */ +template +inline const typename PartialRedux::HNormalizedReturnType +PartialRedux::hnormalized() const +{ + return HNormalized_Block(_expression(),0,0, + Direction==Vertical ? _expression().rows()-1 : _expression().rows(), + Direction==Horizontal ? _expression().cols()-1 : _expression().cols()).nestByValue() + .cwise()/ + Replicate, + Direction==Vertical ? HNormalized_SizeMinusOne : 1, + Direction==Horizontal ? HNormalized_SizeMinusOne : 1> + (HNormalized_Factors(_expression(), + Direction==Vertical ? _expression().rows()-1:0, + Direction==Horizontal ? _expression().cols()-1:0, + Direction==Vertical ? 1 : _expression().rows(), + Direction==Horizontal ? 1 : _expression().cols()).nestByValue(), + Direction==Vertical ? _expression().rows()-1 : 1, + Direction==Horizontal ? _expression().cols()-1 : 1).nestByValue(); +} + +#endif // EIGEN_HOMOGENEOUS_H diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 09c0d9a93..cc959d69a 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -105,6 +105,8 @@ ei_add_test(commainitializer) ei_add_test(smallvectors) ei_add_test(map) ei_add_test(array) +ei_add_test(array_replicate) +ei_add_test(array_reverse) ei_add_test(triangular) ei_add_test(cholesky " " "${GSL_LIBRARIES}") ei_add_test(lu ${EI_OFLAG}) @@ -114,6 +116,7 @@ ei_add_test(qr) ei_add_test(eigensolver " " "${GSL_LIBRARIES}") ei_add_test(svd) ei_add_test(geo_orthomethods) +ei_add_test(geo_homogeneous) ei_add_test(geo_quaternion) ei_add_test(geo_transformations) ei_add_test(geo_eulerangles) @@ -135,7 +138,6 @@ ei_add_test(sparse_vector) ei_add_test(sparse_basic) ei_add_test(sparse_product) ei_add_test(sparse_solvers " " "${SPARSE_LIBS}") -ei_add_test(reverse) ei_add_property(EIGEN_TESTING_SUMMARY "CXX: ${CMAKE_CXX_COMPILER}\n") diff --git a/test/array_replicate.cpp b/test/array_replicate.cpp new file mode 100644 index 000000000..e8d0f33cb --- /dev/null +++ b/test/array_replicate.cpp @@ -0,0 +1,86 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. Eigen itself is part of the KDE project. +// +// Copyright (C) 2009 Gael Guennebaud +// +// 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 . + +#include "main.h" +#include + +template void replicate(const MatrixType& m) +{ + /* this test covers the following files: + Replicate.cpp + */ + + typedef typename MatrixType::Scalar Scalar; + typedef typename NumTraits::Real RealScalar; + typedef Matrix VectorType; + typedef Matrix MatrixX; + typedef Matrix VectorX; + + int rows = m.rows(); + int cols = m.cols(); + + MatrixType m1 = MatrixType::Random(rows, cols), + m2 = MatrixType::Random(rows, cols); + + VectorType v1 = VectorType::Random(rows); + + MatrixX x1, x2; + VectorX vx1; + + int f1 = ei_random(1,10), + f2 = ei_random(1,10); + + x1.resize(rows*f1,cols*f2); + for(int j=0; j())); + + x2.resize(rows,f1); + for (int j=0; j()) ); + CALL_SUBTEST( replicate(Vector2f()) ); + CALL_SUBTEST( replicate(Vector3d()) ); + CALL_SUBTEST( replicate(Vector4f()) ); + CALL_SUBTEST( replicate(VectorXf(16)) ); + CALL_SUBTEST( replicate(VectorXcd(10)) ); + } +} diff --git a/test/reverse.cpp b/test/array_reverse.cpp similarity index 99% rename from test/reverse.cpp rename to test/array_reverse.cpp index ce1a48ed8..c69ff73e8 100644 --- a/test/reverse.cpp +++ b/test/array_reverse.cpp @@ -160,7 +160,7 @@ template void reverse(const MatrixType& m) */ } -void test_reverse() +void test_array_reverse() { for(int i = 0; i < g_repeat; i++) { CALL_SUBTEST( reverse(Matrix()) ); diff --git a/test/geo_homogeneous.cpp b/test/geo_homogeneous.cpp new file mode 100644 index 000000000..aea6f746e --- /dev/null +++ b/test/geo_homogeneous.cpp @@ -0,0 +1,79 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. Eigen itself is part of the KDE project. +// +// Copyright (C) 2009 Gael Guennebaud +// +// 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 . + +#include "main.h" +#include + +template void homogeneous(void) +{ + /* this test covers the following files: + Homogeneous.h + */ + + typedef Matrix MatrixType; + typedef Matrix VectorType; + + typedef Matrix HMatrixType; + typedef Matrix HVectorType; + + Scalar largeEps = test_precision(); + if (ei_is_same_type::ret) + largeEps = 1e-3f; + + Scalar eps = ei_random() * 1e-2; + + VectorType v0 = VectorType::Random(), + v1 = VectorType::Random(), + ones = VectorType::Ones(); + + HVectorType hv0 = HVectorType::Random(), + hv1 = HVectorType::Random(); + + MatrixType m0 = MatrixType::Random(), + m1 = MatrixType::Random(); + + HMatrixType hm0 = HMatrixType::Random(), + hm1 = HMatrixType::Random(); + + hv0 << v0, 1; + VERIFY_IS_APPROX(v0.homogeneous(), hv0); + VERIFY_IS_APPROX(v0, hv0.hnormalized()); + + hm0 << m0, ones.transpose(); + VERIFY_IS_APPROX(m0.colwise().homogeneous(), hm0); + VERIFY_IS_APPROX(m0, hm0.colwise().hnormalized()); + hm0.row(Size-1).setRandom(); + for(int j=0; j() )); + CALL_SUBTEST(( homogeneous() )); + CALL_SUBTEST(( homogeneous() )); + } +} diff --git a/test/packetmath.cpp b/test/packetmath.cpp index f56532f91..c7694b660 100644 --- a/test/packetmath.cpp +++ b/test/packetmath.cpp @@ -137,8 +137,8 @@ template void packetmath() ref[0] = data1[0]; for (int i=0; i