diff --git a/Eigen/src/Array/PartialRedux.h b/Eigen/src/Array/PartialRedux.h index 37fe2b70f..0f868677c 100644 --- a/Eigen/src/Array/PartialRedux.h +++ b/Eigen/src/Array/PartialRedux.h @@ -281,16 +281,16 @@ template class PartialRedux return Reverse( _expression() ); } + template + const Replicate + replicate(int factor = Factor) const; + /////////// Geometry module /////////// const Homogeneous homogeneous() const; const Replicate replicate(int factor) const; - - template - const Replicate - replicate() const; typedef typename ExpressionType::PlainMatrixType CrossReturnType; template diff --git a/Eigen/src/Array/Replicate.h b/Eigen/src/Array/Replicate.h index 09d64d067..d3220c154 100644 --- a/Eigen/src/Array/Replicate.h +++ b/Eigen/src/Array/Replicate.h @@ -151,9 +151,10 @@ PartialRedux::replicate(int factor) const template template const Replicate -PartialRedux::replicate() const +PartialRedux::replicate(int factor) const { - return _expression(); + return Replicate + (_expression(),Direction==Vertical?factor:1,Direction==Horizontal?factor:1); } #endif // EIGEN_REPLICATE_H diff --git a/Eigen/src/Geometry/Homogeneous.h b/Eigen/src/Geometry/Homogeneous.h index 7e1114474..ef80da7ca 100644 --- a/Eigen/src/Geometry/Homogeneous.h +++ b/Eigen/src/Geometry/Homogeneous.h @@ -59,6 +59,9 @@ struct ei_traits > }; }; +template struct ei_homogeneous_left_product_impl; +template struct ei_homogeneous_right_product_impl; + template class Homogeneous : public MatrixBase > { @@ -80,6 +83,22 @@ template class Homogeneous return 1; return m_matrix.coeff(row, col); } + + template + inline const ei_homogeneous_right_product_impl + operator* (const MatrixBase& rhs) const + { + ei_assert(Direction==Horizontal); + return ei_homogeneous_right_product_impl(m_matrix,rhs.derived()); + } + + template friend + inline const ei_homogeneous_left_product_impl + operator* (const MatrixBase& lhs, const Homogeneous& rhs) + { + ei_assert(Direction==Vertical); + return ei_homogeneous_left_product_impl(lhs.derived(),rhs.m_matrix); + } protected: const typename MatrixType::Nested m_matrix; @@ -165,4 +184,57 @@ PartialRedux::hnormalized() const Direction==Horizontal ? _expression().cols()-1 : 1).nestByValue(); } +template +struct ei_homogeneous_left_product_impl,Lhs> + : public ReturnByValue,Lhs>, + Matrix::Scalar, + Lhs::RowsAtCompileTime,MatrixType::ColsAtCompileTime> > +{ + typedef typename ei_cleantype::type LhsNested; + ei_homogeneous_left_product_impl(const Lhs& lhs, const MatrixType& rhs) + : m_lhs(lhs), m_rhs(rhs) + {} + + template void evalTo(Dest& dst) const + { + // FIXME investigate how to allow lazy evaluation of this product when possible + dst = Block + (m_lhs,0,0,m_lhs.rows(),m_lhs.cols()-1) * m_rhs; + dst += m_lhs.col(m_lhs.cols()-1).rowwise() + .template replicate(m_rhs.cols()); + } + + const typename Lhs::Nested m_lhs; + const typename MatrixType::Nested m_rhs; +}; + +template +struct ei_homogeneous_right_product_impl,Rhs> + : public ReturnByValue,Rhs>, + Matrix::Scalar, + MatrixType::RowsAtCompileTime, Rhs::ColsAtCompileTime> > +{ + typedef typename ei_cleantype::type RhsNested; + ei_homogeneous_right_product_impl(const MatrixType& lhs, const Rhs& rhs) + : m_lhs(lhs), m_rhs(rhs) + {} + + template void evalTo(Dest& dst) const + { + // FIXME investigate how to allow lazy evaluation of this product when possible + dst = m_lhs * Block + (m_rhs,0,0,m_rhs.rows()-1,m_rhs.cols()); + dst += m_rhs.row(m_rhs.rows()-1).colwise() + .template replicate(m_lhs.rows()); + } + + const typename MatrixType::Nested m_lhs; + const typename Rhs::Nested m_rhs; + +}; + #endif // EIGEN_HOMOGENEOUS_H diff --git a/test/geo_homogeneous.cpp b/test/geo_homogeneous.cpp index aea6f746e..5deb0d530 100644 --- a/test/geo_homogeneous.cpp +++ b/test/geo_homogeneous.cpp @@ -36,13 +36,15 @@ template void homogeneous(void) typedef Matrix HMatrixType; typedef Matrix HVectorType; + + typedef Matrix T1MatrixType; + typedef Matrix T2MatrixType; + typedef Matrix T3MatrixType; 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(); @@ -67,13 +69,32 @@ template void homogeneous(void) for(int j=0; j() )); +// CALL_SUBTEST(( homogeneous() )); CALL_SUBTEST(( homogeneous() )); - CALL_SUBTEST(( homogeneous() )); +// CALL_SUBTEST(( homogeneous() )); } }