diff options
Diffstat (limited to 'test/evaluators.cpp')
-rw-r--r-- | test/evaluators.cpp | 142 |
1 files changed, 138 insertions, 4 deletions
diff --git a/test/evaluators.cpp b/test/evaluators.cpp index e3922c1be..f41968da8 100644 --- a/test/evaluators.cpp +++ b/test/evaluators.cpp @@ -1,7 +1,78 @@ -#define EIGEN_ENABLE_EVALUATORS + #include "main.h" -using internal::copy_using_evaluator; +namespace Eigen { + + template<typename DstXprType, typename SrcXprType> + EIGEN_STRONG_INLINE + DstXprType& copy_using_evaluator(const EigenBase<DstXprType> &dst, const SrcXprType &src) + { + call_assignment(dst.const_cast_derived(), src.derived(), internal::assign_op<typename DstXprType::Scalar>()); + return dst.const_cast_derived(); + } + + template<typename DstXprType, template <typename> class StorageBase, typename SrcXprType> + EIGEN_STRONG_INLINE + const DstXprType& copy_using_evaluator(const NoAlias<DstXprType, StorageBase>& dst, const SrcXprType &src) + { + call_assignment(dst, src.derived(), internal::assign_op<typename DstXprType::Scalar>()); + return dst.expression(); + } + + template<typename DstXprType, typename SrcXprType> + EIGEN_STRONG_INLINE + DstXprType& copy_using_evaluator(const PlainObjectBase<DstXprType> &dst, const SrcXprType &src) + { + #ifdef EIGEN_NO_AUTOMATIC_RESIZING + eigen_assert((dst.size()==0 || (IsVectorAtCompileTime ? (dst.size() == src.size()) + : (dst.rows() == src.rows() && dst.cols() == src.cols()))) + && "Size mismatch. Automatic resizing is disabled because EIGEN_NO_AUTOMATIC_RESIZING is defined"); + #else + dst.const_cast_derived().resizeLike(src.derived()); + #endif + + call_assignment(dst.const_cast_derived(), src.derived(), internal::assign_op<typename DstXprType::Scalar>()); + return dst.const_cast_derived(); + } + + template<typename DstXprType, typename SrcXprType> + void add_assign_using_evaluator(const DstXprType& dst, const SrcXprType& src) + { + typedef typename DstXprType::Scalar Scalar; + call_assignment(const_cast<DstXprType&>(dst), src.derived(), internal::add_assign_op<Scalar>()); + } + + template<typename DstXprType, typename SrcXprType> + void subtract_assign_using_evaluator(const DstXprType& dst, const SrcXprType& src) + { + typedef typename DstXprType::Scalar Scalar; + call_assignment(const_cast<DstXprType&>(dst), src.derived(), internal::sub_assign_op<Scalar>()); + } + + template<typename DstXprType, typename SrcXprType> + void multiply_assign_using_evaluator(const DstXprType& dst, const SrcXprType& src) + { + typedef typename DstXprType::Scalar Scalar; + call_assignment(dst.const_cast_derived(), src.derived(), internal::mul_assign_op<Scalar>()); + } + + template<typename DstXprType, typename SrcXprType> + void divide_assign_using_evaluator(const DstXprType& dst, const SrcXprType& src) + { + typedef typename DstXprType::Scalar Scalar; + call_assignment(dst.const_cast_derived(), src.derived(), internal::div_assign_op<Scalar>()); + } + + template<typename DstXprType, typename SrcXprType> + void swap_using_evaluator(const DstXprType& dst, const SrcXprType& src) + { + typedef typename DstXprType::Scalar Scalar; + call_assignment(dst.const_cast_derived(), src.const_cast_derived(), internal::swap_assign_op<Scalar>()); + } + +} + + using namespace std; #define VERIFY_IS_APPROX_EVALUATOR(DEST,EXPR) VERIFY_IS_APPROX(copy_using_evaluator(DEST,(EXPR)), (EXPR).eval()); @@ -72,8 +143,19 @@ void test_evaluators() c = a*a; copy_using_evaluator(a, prod(a,a)); VERIFY_IS_APPROX(a,c); + + // check compound assignment of products + d = c; + add_assign_using_evaluator(c.noalias(), prod(a,b)); + d.noalias() += a*b; + VERIFY_IS_APPROX(c, d); + + d = c; + subtract_assign_using_evaluator(c.noalias(), prod(a,b)); + d.noalias() -= a*b; + VERIFY_IS_APPROX(c, d); } - + { // test product with all possible sizes int s = internal::random<int>(1,100); @@ -124,7 +206,7 @@ void test_evaluators() // this does not work because Random is eval-before-nested: // copy_using_evaluator(w, Vector2d::Random().transpose()); - + // test CwiseUnaryOp VERIFY_IS_APPROX_EVALUATOR(v2, 3 * v); VERIFY_IS_APPROX_EVALUATOR(w, (3 * v).transpose()); @@ -327,4 +409,56 @@ void test_evaluators() arr_ref.row(1) /= (arr_ref.row(2) + 1); VERIFY_IS_APPROX(arr, arr_ref); } + + { + // test triangular shapes + MatrixXd A = MatrixXd::Random(6,6), B(6,6), C(6,6), D(6,6); + A.setRandom();B.setRandom(); + VERIFY_IS_APPROX_EVALUATOR2(B, A.triangularView<Upper>(), MatrixXd(A.triangularView<Upper>())); + + A.setRandom();B.setRandom(); + VERIFY_IS_APPROX_EVALUATOR2(B, A.triangularView<UnitLower>(), MatrixXd(A.triangularView<UnitLower>())); + + A.setRandom();B.setRandom(); + VERIFY_IS_APPROX_EVALUATOR2(B, A.triangularView<UnitUpper>(), MatrixXd(A.triangularView<UnitUpper>())); + + A.setRandom();B.setRandom(); + C = B; C.triangularView<Upper>() = A; + copy_using_evaluator(B.triangularView<Upper>(), A); + VERIFY(B.isApprox(C) && "copy_using_evaluator(B.triangularView<Upper>(), A)"); + + A.setRandom();B.setRandom(); + C = B; C.triangularView<Lower>() = A.triangularView<Lower>(); + copy_using_evaluator(B.triangularView<Lower>(), A.triangularView<Lower>()); + VERIFY(B.isApprox(C) && "copy_using_evaluator(B.triangularView<Lower>(), A.triangularView<Lower>())"); + + + A.setRandom();B.setRandom(); + C = B; C.triangularView<Lower>() = A.triangularView<Upper>().transpose(); + copy_using_evaluator(B.triangularView<Lower>(), A.triangularView<Upper>().transpose()); + VERIFY(B.isApprox(C) && "copy_using_evaluator(B.triangularView<Lower>(), A.triangularView<Lower>().transpose())"); + + + A.setRandom();B.setRandom(); C = B; D = A; + C.triangularView<Upper>().swap(D.triangularView<Upper>()); + swap_using_evaluator(B.triangularView<Upper>(), A.triangularView<Upper>()); + VERIFY(B.isApprox(C) && "swap_using_evaluator(B.triangularView<Upper>(), A.triangularView<Upper>())"); + + + VERIFY_IS_APPROX_EVALUATOR2(B, prod(A.triangularView<Upper>(),A), MatrixXd(A.triangularView<Upper>()*A)); + + VERIFY_IS_APPROX_EVALUATOR2(B, prod(A.selfadjointView<Upper>(),A), MatrixXd(A.selfadjointView<Upper>()*A)); + + } + + { + // test diagonal shapes + VectorXd d = VectorXd::Random(6); + MatrixXd A = MatrixXd::Random(6,6), B(6,6); + A.setRandom();B.setRandom(); + + VERIFY_IS_APPROX_EVALUATOR2(B, lazyprod(d.asDiagonal(),A), MatrixXd(d.asDiagonal()*A)); + VERIFY_IS_APPROX_EVALUATOR2(B, lazyprod(A,d.asDiagonal()), MatrixXd(A*d.asDiagonal())); + + } } |