From db183ca7b31a366fa1a870927d68c3bf6de15c4d Mon Sep 17 00:00:00 2001 From: Gael Guennebaud Date: Thu, 31 Jul 2014 14:54:54 +0200 Subject: [PATCH] Make minimal changes to make homogenous compatible with evaluators --- Eigen/src/Core/util/Constants.h | 1 + Eigen/src/Geometry/Homogeneous.h | 94 +++++++++----------------------- test/geo_homogeneous.cpp | 3 +- 3 files changed, 27 insertions(+), 71 deletions(-) diff --git a/Eigen/src/Core/util/Constants.h b/Eigen/src/Core/util/Constants.h index c0463583d..86817a989 100644 --- a/Eigen/src/Core/util/Constants.h +++ b/Eigen/src/Core/util/Constants.h @@ -454,6 +454,7 @@ struct ArrayXpr {}; // An evaluator must define its shape. By default, it can be one of the following: struct DenseShape { static std::string debugName() { return "DenseShape"; } }; +struct HomogeneousShape { static std::string debugName() { return "HomogeneousShape"; } }; struct DiagonalShape { static std::string debugName() { return "DiagonalShape"; } }; struct BandShape { static std::string debugName() { return "BandShape"; } }; struct TriangularShape { static std::string debugName() { return "TriangularShape"; } }; diff --git a/Eigen/src/Geometry/Homogeneous.h b/Eigen/src/Geometry/Homogeneous.h index 07bc22154..7a3b5de80 100644 --- a/Eigen/src/Geometry/Homogeneous.h +++ b/Eigen/src/Geometry/Homogeneous.h @@ -332,6 +332,18 @@ struct homogeneous_right_product_impl,Rhs> }; #ifdef EIGEN_TEST_EVALUATORS + +template +struct evaluator_traits > +{ + typedef typename storage_kind_to_evaluator_kind::Kind Kind; + typedef HomogeneousShape Shape; + static const int AssumeAliasing = 0; +}; + +template<> struct AssignmentKind { typedef Dense2Dense Kind; }; + + template struct unary_evaluator, IndexBased> : evaluator::PlainObject >::type @@ -355,10 +367,13 @@ template< typename DstXprType, typename ArgType, typename Scalar> struct Assignment, internal::assign_op, Dense2Dense, Scalar> { typedef Homogeneous SrcXprType; + // TODO clang generates garbage if this function is inlined. no valgrind error though. +#ifdef __clang__ + EIGEN_DONT_INLINE +#endif static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op &) { dst.template topRows(src.nestedExpression().rows()) = src.nestedExpression(); -// dst.topRows(src.nestedExpression().rows()) = src.nestedExpression(); dst.row(dst.rows()-1).setOnes(); } }; @@ -368,16 +383,19 @@ template< typename DstXprType, typename ArgType, typename Scalar> struct Assignment, internal::assign_op, Dense2Dense, Scalar> { typedef Homogeneous SrcXprType; + // TODO clang generates garbage if this function is inlined. no valgrind error though. +#ifdef __clang__ + EIGEN_DONT_INLINE +#endif static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op &) { dst.template leftCols(src.nestedExpression().cols()) = src.nestedExpression(); -// dst.leftCols(src.nestedExpression().cols()) = src.nestedExpression(); dst.col(dst.cols()-1).setOnes(); } }; template -struct generic_product_impl, Rhs, DenseShape, DenseShape, ProductTag> +struct generic_product_impl, Rhs, HomogeneousShape, DenseShape, ProductTag> { template static void evalTo(Dest& dst, const Homogeneous& lhs, const Rhs& rhs) @@ -387,88 +405,26 @@ struct generic_product_impl, Rhs, DenseShape, Den }; template -struct generic_product_impl, DenseShape, DenseShape, ProductTag> +struct generic_product_impl, DenseShape, HomogeneousShape, ProductTag> { template static void evalTo(Dest& dst, const Lhs& lhs, const Homogeneous& rhs) { - homogeneous_left_product_impl, Lhs>(rhs.nestedExpression(), lhs).evalTo(dst); + homogeneous_left_product_impl, Lhs>(lhs, rhs.nestedExpression()).evalTo(dst); } }; template -struct generic_product_impl, Homogeneous, DenseShape, DenseShape, ProductTag> +struct generic_product_impl, Homogeneous, DenseShape, HomogeneousShape, ProductTag> { typedef Transform TransformType; template static void evalTo(Dest& dst, const TransformType& lhs, const Homogeneous& rhs) { - homogeneous_left_product_impl, TransformType>(rhs.nestedExpression(), lhs).evalTo(dst); + homogeneous_left_product_impl, TransformType>(lhs, rhs.nestedExpression()).evalTo(dst); } }; - -template -struct product_evaluator, Rhs, DefaultProduct>, ProductTag, DenseShape, DenseShape, typename traits::Scalar, typename traits::Scalar> - : public evaluator, Rhs, DefaultProduct>::PlainObject>::type -{ - typedef Homogeneous Lhs; - typedef Product XprType; - typedef typename XprType::PlainObject PlainObject; - typedef typename evaluator::type Base; - - product_evaluator(const XprType& xpr) - : m_result(xpr.rows(), xpr.cols()) - { - ::new (static_cast(this)) Base(m_result); - generic_product_impl::evalTo(m_result, xpr.lhs(), xpr.rhs()); - } - -protected: - PlainObject m_result; -}; - -template -struct product_evaluator, DefaultProduct>, ProductTag, DenseShape, DenseShape, typename traits::Scalar, typename traits::Scalar> - : public evaluator, DefaultProduct>::PlainObject>::type -{ - typedef Homogeneous Rhs; - typedef Product XprType; - typedef typename XprType::PlainObject PlainObject; - typedef typename evaluator::type Base; - - product_evaluator(const XprType& xpr) - : m_result(xpr.rows(), xpr.cols()) - { - ::new (static_cast(this)) Base(m_result); - generic_product_impl::evalTo(m_result, xpr.lhs(), xpr.rhs()); - } - -protected: - PlainObject m_result; -}; - -template -struct product_evaluator, Homogeneous, DefaultProduct>, ProductTag, DenseShape, DenseShape, Scalar, typename traits::Scalar> - : public evaluator, Homogeneous, DefaultProduct>::PlainObject>::type -{ - typedef Transform Lhs; - typedef Homogeneous Rhs; - typedef Product XprType; - typedef typename XprType::PlainObject PlainObject; - typedef typename evaluator::type Base; - - product_evaluator(const XprType& xpr) - : m_result(xpr.rows(), xpr.cols()) - { - ::new (static_cast(this)) Base(m_result); - generic_product_impl::evalTo(m_result, xpr.lhs(), xpr.rhs()); - } - -protected: - PlainObject m_result; -}; - #endif // EIGEN_TEST_EVALUATORS } // end namespace internal diff --git a/test/geo_homogeneous.cpp b/test/geo_homogeneous.cpp index c91bde819..078894035 100644 --- a/test/geo_homogeneous.cpp +++ b/test/geo_homogeneous.cpp @@ -57,7 +57,6 @@ template void homogeneous(void) VERIFY_IS_APPROX((v0.transpose().rowwise().homogeneous().eval()) * t2, v0.transpose().rowwise().homogeneous() * t2); - m0.transpose().rowwise().homogeneous().eval(); VERIFY_IS_APPROX((m0.transpose().rowwise().homogeneous().eval()) * t2, m0.transpose().rowwise().homogeneous() * t2); @@ -82,7 +81,7 @@ template void homogeneous(void) VERIFY_IS_APPROX(aff * pts.colwise().homogeneous(), (aff * pts1).colwise().hnormalized()); VERIFY_IS_APPROX(caff * pts.colwise().homogeneous(), (caff * pts1).colwise().hnormalized()); VERIFY_IS_APPROX(proj * pts.colwise().homogeneous(), (proj * pts1)); - + VERIFY_IS_APPROX((aff * pts1).colwise().hnormalized(), aff * pts); VERIFY_IS_APPROX((caff * pts1).colwise().hnormalized(), caff * pts);