diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/CMakeLists.txt | 44 | ||||
-rw-r--r-- | test/block.cpp | 8 | ||||
-rw-r--r-- | test/evaluators.cpp | 152 | ||||
-rw-r--r-- | test/geo_homogeneous.cpp | 7 | ||||
-rw-r--r-- | test/geo_orthomethods.cpp | 9 | ||||
-rw-r--r-- | test/inverse.cpp | 8 | ||||
-rw-r--r-- | test/main.h | 9 | ||||
-rw-r--r-- | test/mixingtypes.cpp | 5 | ||||
-rw-r--r-- | test/nesting_ops.cpp | 5 | ||||
-rw-r--r-- | test/product_notemporary.cpp | 3 | ||||
-rw-r--r-- | test/qr_fullpivoting.cpp | 6 | ||||
-rw-r--r-- | test/sparse_basic.cpp | 9 | ||||
-rw-r--r-- | test/sparse_product.cpp | 22 | ||||
-rw-r--r-- | test/sparse_vector.cpp | 4 | ||||
-rw-r--r-- | test/vectorization_logic.cpp | 67 | ||||
-rw-r--r-- | test/vectorwiseop.cpp | 4 |
16 files changed, 302 insertions, 60 deletions
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 47aefddb8..075b8d3de 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -139,17 +139,17 @@ endif(TEST_LIB) set_property(GLOBAL PROPERTY EIGEN_CURRENT_SUBPROJECT "Official") add_custom_target(BuildOfficial) -option(EIGEN_TEST_EVALUATORS "Enable work in progress evaluators" OFF) -if(EIGEN_TEST_EVALUATORS) - add_definitions("-DEIGEN_TEST_EVALUATORS=1") - add_definitions("-DEIGEN_ENABLE_EVALUATORS=1") -endif(EIGEN_TEST_EVALUATORS) +option(EIGEN_TEST_NO_EVALUATORS "Disable evaluators in unit tests" OFF) +if(EIGEN_TEST_NO_EVALUATORS) + add_definitions("-DEIGEN_TEST_NO_EVALUATORS=1") +endif(EIGEN_TEST_NO_EVALUATORS) ei_add_test(meta) ei_add_test(sizeof) ei_add_test(dynalloc) ei_add_test(nomalloc) ei_add_test(first_aligned) +ei_add_test(nullary) ei_add_test(mixingtypes) ei_add_test(packetmath) ei_add_test(unalignedassert) @@ -165,6 +165,9 @@ ei_add_test(redux) ei_add_test(visitor) ei_add_test(block) ei_add_test(corners) +ei_add_test(swap) +ei_add_test(resize) +ei_add_test(conservative_resize) ei_add_test(product_small) ei_add_test(product_large) ei_add_test(product_extra) @@ -193,6 +196,7 @@ ei_add_test(product_trsolve) ei_add_test(product_mmtr) ei_add_test(product_notemporary) ei_add_test(stable_norm) +ei_add_test(permutationmatrices) ei_add_test(bandmatrix) ei_add_test(cholesky) ei_add_test(lu) @@ -212,30 +216,30 @@ ei_add_test(real_qz) ei_add_test(eigensolver_generalized_real) ei_add_test(jacobi) ei_add_test(jacobisvd) +ei_add_test(householder) 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) -ei_add_test(geo_hyperplane) ei_add_test(geo_parametrizedline) ei_add_test(geo_alignedbox) +ei_add_test(geo_hyperplane) +ei_add_test(geo_transformations) +ei_add_test(geo_homogeneous) ei_add_test(stdvector) ei_add_test(stdvector_overload) ei_add_test(stdlist) ei_add_test(stddeque) -ei_add_test(resize) -ei_add_test(sparse_vector) ei_add_test(sparse_basic) +ei_add_test(sparse_vector) ei_add_test(sparse_product) ei_add_test(sparse_solvers) -ei_add_test(umeyama) -ei_add_test(householder) -ei_add_test(swap) -ei_add_test(conservative_resize) -ei_add_test(permutationmatrices) ei_add_test(sparse_permutations) -ei_add_test(nullary) +ei_add_test(simplicial_cholesky) +ei_add_test(conjugate_gradient) +ei_add_test(bicgstab) +ei_add_test(sparselu) +ei_add_test(sparseqr) +ei_add_test(umeyama) ei_add_test(nesting_ops "${CMAKE_CXX_FLAGS_DEBUG}") ei_add_test(zerosized) ei_add_test(dontalign) @@ -249,13 +253,7 @@ ei_add_test(special_numbers) ei_add_test(rvalue_types) ei_add_test(dense_storage) -ei_add_test(simplicial_cholesky) -ei_add_test(conjugate_gradient) -ei_add_test(bicgstab) -ei_add_test(sparselu) -ei_add_test(sparseqr) - -# ei_add_test(denseLM) +# # ei_add_test(denseLM) if(QT4_FOUND) ei_add_test(qtvector "" "${QT_QTCORE_LIBRARY}") diff --git a/test/block.cpp b/test/block.cpp index 269acd28e..3b77b704a 100644 --- a/test/block.cpp +++ b/test/block.cpp @@ -130,6 +130,14 @@ template<typename MatrixType> void block(const MatrixType& m) VERIFY(numext::real(ones.col(c1).dot(ones.col(c2))) == RealScalar(rows)); VERIFY(numext::real(ones.row(r1).dot(ones.row(r2))) == RealScalar(cols)); + + // chekc that linear acccessors works on blocks + m1 = m1_copy; + if((MatrixType::Flags&RowMajorBit)==0) + VERIFY_IS_EQUAL(m1.leftCols(c1).coeff(r1+c1*rows), m1(r1,c1)); + else + VERIFY_IS_EQUAL(m1.topRows(r1).coeff(c1+r1*cols), m1(r1,c1)); + // now test some block-inside-of-block. diff --git a/test/evaluators.cpp b/test/evaluators.cpp index e3922c1be..2ca453b1c 100644 --- a/test/evaluators.cpp +++ b/test/evaluators.cpp @@ -1,7 +1,90 @@ + +#ifndef EIGEN_ENABLE_EVALUATORS #define EIGEN_ENABLE_EVALUATORS +#endif + +#ifdef EIGEN_TEST_EVALUATORS +#undef EIGEN_TEST_EVALUATORS +#endif + +#ifdef EIGEN_TEST_NO_EVALUATORS +#undef EIGEN_TEST_NO_EVALUATORS +#endif + #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 +155,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 +218,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 +421,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())); + + } } diff --git a/test/geo_homogeneous.cpp b/test/geo_homogeneous.cpp index c91bde819..2f9d18c0f 100644 --- a/test/geo_homogeneous.cpp +++ b/test/geo_homogeneous.cpp @@ -38,6 +38,10 @@ template<typename Scalar,int Size> void homogeneous(void) hv0 << v0, 1; VERIFY_IS_APPROX(v0.homogeneous(), hv0); VERIFY_IS_APPROX(v0, hv0.hnormalized()); + + VERIFY_IS_APPROX(v0.homogeneous().sum(), hv0.sum()); + VERIFY_IS_APPROX(v0.homogeneous().minCoeff(), hv0.minCoeff()); + VERIFY_IS_APPROX(v0.homogeneous().maxCoeff(), hv0.maxCoeff()); hm0 << m0, ones.transpose(); VERIFY_IS_APPROX(m0.colwise().homogeneous(), hm0); @@ -57,7 +61,6 @@ template<typename Scalar,int Size> 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 +85,7 @@ template<typename Scalar,int Size> 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); diff --git a/test/geo_orthomethods.cpp b/test/geo_orthomethods.cpp index c836dae40..7f8beb205 100644 --- a/test/geo_orthomethods.cpp +++ b/test/geo_orthomethods.cpp @@ -33,6 +33,7 @@ template<typename Scalar> void orthomethods_3() VERIFY_IS_MUCH_SMALLER_THAN(v1.dot(v1.cross(v2)), Scalar(1)); VERIFY_IS_MUCH_SMALLER_THAN(v1.cross(v2).dot(v2), Scalar(1)); VERIFY_IS_MUCH_SMALLER_THAN(v2.dot(v1.cross(v2)), Scalar(1)); + VERIFY_IS_MUCH_SMALLER_THAN(v1.cross(Vector3::Random()).dot(v1), Scalar(1)); Matrix3 mat3; mat3 << v0.normalized(), (v0.cross(v1)).normalized(), @@ -47,6 +48,13 @@ template<typename Scalar> void orthomethods_3() int i = internal::random<int>(0,2); mcross = mat3.colwise().cross(vec3); VERIFY_IS_APPROX(mcross.col(i), mat3.col(i).cross(vec3)); + + VERIFY_IS_MUCH_SMALLER_THAN((mat3.adjoint() * mat3.colwise().cross(vec3)).diagonal().cwiseAbs().sum(), Scalar(1)); + VERIFY_IS_MUCH_SMALLER_THAN((mat3.adjoint() * mat3.colwise().cross(Vector3::Random())).diagonal().cwiseAbs().sum(), Scalar(1)); + + VERIFY_IS_MUCH_SMALLER_THAN((vec3.adjoint() * mat3.colwise().cross(vec3)).cwiseAbs().sum(), Scalar(1)); + VERIFY_IS_MUCH_SMALLER_THAN((vec3.adjoint() * Matrix3::Random().colwise().cross(vec3)).cwiseAbs().sum(), Scalar(1)); + mcross = mat3.rowwise().cross(vec3); VERIFY_IS_APPROX(mcross.row(i), mat3.row(i).cross(vec3)); @@ -57,6 +65,7 @@ template<typename Scalar> void orthomethods_3() v40.w() = v41.w() = v42.w() = 0; v42.template head<3>() = v40.template head<3>().cross(v41.template head<3>()); VERIFY_IS_APPROX(v40.cross3(v41), v42); + VERIFY_IS_MUCH_SMALLER_THAN(v40.cross3(Vector4::Random()).dot(v40), Scalar(1)); // check mixed product typedef Matrix<RealScalar, 3, 1> RealVector3; diff --git a/test/inverse.cpp b/test/inverse.cpp index 8187b088d..1195bcc76 100644 --- a/test/inverse.cpp +++ b/test/inverse.cpp @@ -68,6 +68,14 @@ template<typename MatrixType> void inverse(const MatrixType& m) VERIFY_IS_MUCH_SMALLER_THAN(abs(det-m3.determinant()), RealScalar(1)); m3.computeInverseWithCheck(m4, invertible); VERIFY( rows==1 ? invertible : !invertible ); + + // check with submatrices + { + Matrix<Scalar, MatrixType::RowsAtCompileTime+1, MatrixType::RowsAtCompileTime+1, MatrixType::Options> m3; + m3.setRandom(); + m2 = m3.template topLeftCorner<MatrixType::RowsAtCompileTime,MatrixType::ColsAtCompileTime>().inverse(); + VERIFY_IS_APPROX( (m3.template topLeftCorner<MatrixType::RowsAtCompileTime,MatrixType::ColsAtCompileTime>()), m2.inverse() ); + } #endif // check in-place inversion diff --git a/test/main.h b/test/main.h index 773873a0d..85f951db4 100644 --- a/test/main.h +++ b/test/main.h @@ -94,6 +94,9 @@ namespace Eigen static bool g_has_set_repeat, g_has_set_seed; } +#define TRACK std::cerr << __FILE__ << " " << __LINE__ << std::endl +// #define TRACK while() + #define EI_PP_MAKE_STRING2(S) #S #define EI_PP_MAKE_STRING(S) EI_PP_MAKE_STRING2(S) @@ -311,13 +314,7 @@ inline bool test_isApproxOrLessThan(const long double& a, const long double& b) template<typename Type1, typename Type2> inline bool test_isApprox(const Type1& a, const Type2& b) { -#ifdef EIGEN_TEST_EVALUATORS - typename internal::eval<Type1>::type a_eval(a); - typename internal::eval<Type2>::type b_eval(b); - return a_eval.isApprox(b_eval, test_precision<typename Type1::Scalar>()); -#else return a.isApprox(b, test_precision<typename Type1::Scalar>()); -#endif } // The idea behind this function is to compare the two scalars a and b where diff --git a/test/mixingtypes.cpp b/test/mixingtypes.cpp index 1e0e2d4c1..976e21e37 100644 --- a/test/mixingtypes.cpp +++ b/test/mixingtypes.cpp @@ -53,10 +53,13 @@ template<int SizeAtCompileType> void mixingtypes(int size = SizeAtCompileType) mf+mf; VERIFY_RAISES_ASSERT(mf+md); VERIFY_RAISES_ASSERT(mf+mcf); +#ifndef EIGEN_TEST_EVALUATORS + // they do not even compile when using evaluators VERIFY_RAISES_ASSERT(vf=vd); VERIFY_RAISES_ASSERT(vf+=vd); VERIFY_RAISES_ASSERT(mcd=md); - +#endif + // check scalar products VERIFY_IS_APPROX(vcf * sf , vcf * complex<float>(sf)); VERIFY_IS_APPROX(sd * vcd, complex<double>(sd) * vcd); diff --git a/test/nesting_ops.cpp b/test/nesting_ops.cpp index 1e8523283..114dd5e41 100644 --- a/test/nesting_ops.cpp +++ b/test/nesting_ops.cpp @@ -11,7 +11,12 @@ template <typename MatrixType> void run_nesting_ops(const MatrixType& _m) { +#ifndef EIGEN_TEST_EVALUATORS + // TODO, with evaluator, the following is not correct anymore: typename MatrixType::Nested m(_m); +#else + typename internal::nested_eval<MatrixType,2>::type m(_m); +#endif // Make really sure that we are in debug mode! VERIFY_RAISES_ASSERT(eigen_assert(false)); diff --git a/test/product_notemporary.cpp b/test/product_notemporary.cpp index 3a9df618b..805cc8939 100644 --- a/test/product_notemporary.cpp +++ b/test/product_notemporary.cpp @@ -113,8 +113,7 @@ template<typename MatrixType> void product_notemporary(const MatrixType& m) VERIFY_EVALUATION_COUNT( Scalar tmp = 0; tmp += Scalar(RealScalar(1)) / (m3.transpose() * m3).diagonal().array().abs().sum(), 0 ); // Zero temporaries for ... CoeffBasedProductMode - // - does not work with GCC because of the <..>, we'ld need variadic macros ... - //VERIFY_EVALUATION_COUNT( m3.col(0).head<5>() * m3.col(0).transpose() + m3.col(0).head<5>() * m3.col(0).transpose(), 0 ); + VERIFY_EVALUATION_COUNT( m3.col(0).template head<5>() * m3.col(0).transpose() + m3.col(0).template head<5>() * m3.col(0).transpose(), 0 ); // Check matrix * vectors VERIFY_EVALUATION_COUNT( cvres.noalias() = m1 * cv1, 0 ); diff --git a/test/qr_fullpivoting.cpp b/test/qr_fullpivoting.cpp index 511f2473f..601773404 100644 --- a/test/qr_fullpivoting.cpp +++ b/test/qr_fullpivoting.cpp @@ -40,7 +40,11 @@ template<typename MatrixType> void qr() MatrixType c = qr.matrixQ() * r * qr.colsPermutation().inverse(); VERIFY_IS_APPROX(m1, c); - + + // stress the ReturnByValue mechanism + MatrixType tmp; + VERIFY_IS_APPROX(tmp.noalias() = qr.matrixQ() * r, (qr.matrixQ() * r).eval()); + MatrixType m2 = MatrixType::Random(cols,cols2); MatrixType m3 = m1*m2; m2 = MatrixType::Random(cols,cols2); diff --git a/test/sparse_basic.cpp b/test/sparse_basic.cpp index 4c9b9111e..c86534bad 100644 --- a/test/sparse_basic.cpp +++ b/test/sparse_basic.cpp @@ -201,9 +201,9 @@ template<typename SparseMatrixType> void sparse_basic(const SparseMatrixType& re VERIFY(m3.innerVector(j0).nonZeros() == m3.transpose().innerVector(j0).nonZeros()); - //m2.innerVector(j0) = 2*m2.innerVector(j1); - //refMat2.col(j0) = 2*refMat2.col(j1); - //VERIFY_IS_APPROX(m2, refMat2); +// m2.innerVector(j0) = 2*m2.innerVector(j1); +// refMat2.col(j0) = 2*refMat2.col(j1); +// VERIFY_IS_APPROX(m2, refMat2); } // test innerVectors() @@ -239,7 +239,7 @@ template<typename SparseMatrixType> void sparse_basic(const SparseMatrixType& re VERIFY_IS_APPROX(m2, refMat2); } - + // test basic computations { DenseMatrix refM1 = DenseMatrix::Zero(rows, rows); @@ -255,6 +255,7 @@ template<typename SparseMatrixType> void sparse_basic(const SparseMatrixType& re initSparse<Scalar>(density, refM3, m3); initSparse<Scalar>(density, refM4, m4); + VERIFY_IS_APPROX(m1*s1, refM1*s1); VERIFY_IS_APPROX(m1+m2, refM1+refM2); VERIFY_IS_APPROX(m1+m2+m3, refM1+refM2+refM3); VERIFY_IS_APPROX(m3.cwiseProduct(m1+m2), refM3.cwiseProduct(refM1+refM2)); diff --git a/test/sparse_product.cpp b/test/sparse_product.cpp index 0f52164c8..fa9be5440 100644 --- a/test/sparse_product.cpp +++ b/test/sparse_product.cpp @@ -19,7 +19,7 @@ template<typename SparseMatrixType> void sparse_product() typedef typename SparseMatrixType::Scalar Scalar; enum { Flags = SparseMatrixType::Flags }; - double density = (std::max)(8./(rows*cols), 0.1); + double density = (std::max)(8./(rows*cols), 0.2); typedef Matrix<Scalar,Dynamic,Dynamic> DenseMatrix; typedef Matrix<Scalar,Dynamic,1> DenseVector; typedef Matrix<Scalar,1,Dynamic> RowDenseVector; @@ -77,17 +77,27 @@ template<typename SparseMatrixType> void sparse_product() m4 = m2; refMat4 = refMat2; VERIFY_IS_APPROX(m4=m4*m3, refMat4=refMat4*refMat3); - // sparse * dense + // sparse * dense matrix VERIFY_IS_APPROX(dm4=m2*refMat3, refMat4=refMat2*refMat3); VERIFY_IS_APPROX(dm4=m2*refMat3t.transpose(), refMat4=refMat2*refMat3t.transpose()); VERIFY_IS_APPROX(dm4=m2t.transpose()*refMat3, refMat4=refMat2t.transpose()*refMat3); VERIFY_IS_APPROX(dm4=m2t.transpose()*refMat3t.transpose(), refMat4=refMat2t.transpose()*refMat3t.transpose()); + VERIFY_IS_APPROX(dm4=m2*refMat3, refMat4=refMat2*refMat3); + VERIFY_IS_APPROX(dm4=dm4+m2*refMat3, refMat4=refMat4+refMat2*refMat3); VERIFY_IS_APPROX(dm4=m2*(refMat3+refMat3), refMat4=refMat2*(refMat3+refMat3)); VERIFY_IS_APPROX(dm4=m2t.transpose()*(refMat3+refMat5)*0.5, refMat4=refMat2t.transpose()*(refMat3+refMat5)*0.5); + + // sparse * dense vector + VERIFY_IS_APPROX(dm4.col(0)=m2*refMat3.col(0), refMat4.col(0)=refMat2*refMat3.col(0)); + VERIFY_IS_APPROX(dm4.col(0)=m2*refMat3t.transpose().col(0), refMat4.col(0)=refMat2*refMat3t.transpose().col(0)); + VERIFY_IS_APPROX(dm4.col(0)=m2t.transpose()*refMat3.col(0), refMat4.col(0)=refMat2t.transpose()*refMat3.col(0)); + VERIFY_IS_APPROX(dm4.col(0)=m2t.transpose()*refMat3t.transpose().col(0), refMat4.col(0)=refMat2t.transpose()*refMat3t.transpose().col(0)); // dense * sparse VERIFY_IS_APPROX(dm4=refMat2*m3, refMat4=refMat2*refMat3); + VERIFY_IS_APPROX(dm4=dm4+refMat2*m3, refMat4=refMat4+refMat2*refMat3); + VERIFY_IS_APPROX(dm4+=refMat2*m3, refMat4+=refMat2*refMat3); VERIFY_IS_APPROX(dm4=refMat2*m3t.transpose(), refMat4=refMat2*refMat3t.transpose()); VERIFY_IS_APPROX(dm4=refMat2t.transpose()*m3, refMat4=refMat2t.transpose()*refMat3); VERIFY_IS_APPROX(dm4=refMat2t.transpose()*m3t.transpose(), refMat4=refMat2t.transpose()*refMat3t.transpose()); @@ -99,7 +109,7 @@ template<typename SparseMatrixType> void sparse_product() Index c1 = internal::random<Index>(0,cols-1); Index r1 = internal::random<Index>(0,depth-1); DenseMatrix dm5 = DenseMatrix::Random(depth, cols); - + VERIFY_IS_APPROX( m4=m2.col(c)*dm5.col(c1).transpose(), refMat4=refMat2.col(c)*dm5.col(c1).transpose()); VERIFY_IS_EQUAL(m4.nonZeros(), (refMat4.array()!=0).count()); VERIFY_IS_APPROX( m4=m2.middleCols(c,1)*dm5.col(c1).transpose(), refMat4=refMat2.col(c)*dm5.col(c1).transpose()); @@ -143,11 +153,11 @@ template<typename SparseMatrixType> void sparse_product() RowSpVector rv0(depth), rv1; RowDenseVector drv0(depth), drv1(rv1); initSparse(2*density,drv0, rv0); - - VERIFY_IS_APPROX(cv1=rv0*m3, dcv1=drv0*refMat3); + + VERIFY_IS_APPROX(cv1=m3*cv0, dcv1=refMat3*dcv0); VERIFY_IS_APPROX(rv1=rv0*m3, drv1=drv0*refMat3); - VERIFY_IS_APPROX(cv1=m3*cv0, dcv1=refMat3*dcv0); VERIFY_IS_APPROX(cv1=m3t.adjoint()*cv0, dcv1=refMat3t.adjoint()*dcv0); + VERIFY_IS_APPROX(cv1=rv0*m3, dcv1=drv0*refMat3); VERIFY_IS_APPROX(rv1=m3*cv0, drv1=refMat3*dcv0); } diff --git a/test/sparse_vector.cpp b/test/sparse_vector.cpp index 0c9476803..6cd5a9a8c 100644 --- a/test/sparse_vector.cpp +++ b/test/sparse_vector.cpp @@ -71,6 +71,10 @@ template<typename Scalar,typename Index> void sparse_vector(int rows, int cols) VERIFY_IS_APPROX(v1.dot(v2), refV1.dot(refV2)); VERIFY_IS_APPROX(v1.dot(refV2), refV1.dot(refV2)); +#ifdef EIGEN_TEST_EVALUATORS + // the following did not compiled without evaluators + VERIFY_IS_APPROX(m1*v2, refM1*refV2); +#endif VERIFY_IS_APPROX(v1.dot(m1*v2), refV1.dot(refM1*refV2)); int i = internal::random<int>(0,rows-1); VERIFY_IS_APPROX(v1.dot(m1.col(i)), refV1.dot(refM1.col(i))); diff --git a/test/vectorization_logic.cpp b/test/vectorization_logic.cpp index b069f0771..42015e21b 100644 --- a/test/vectorization_logic.cpp +++ b/test/vectorization_logic.cpp @@ -27,19 +27,43 @@ std::string demangle_unrolling(int t) if(t==CompleteUnrolling) return "CompleteUnrolling"; return "?"; } +std::string demangle_flags(int f) +{ + std::string res; + if(f&RowMajorBit) res += " | RowMajor"; + if(f&PacketAccessBit) res += " | Packet"; + if(f&LinearAccessBit) res += " | Linear"; + if(f&LvalueBit) res += " | Lvalue"; + if(f&DirectAccessBit) res += " | Direct"; + if(f&AlignedBit) res += " | Aligned"; + if(f&NestByRefBit) res += " | NestByRef"; + return res; +} template<typename Dst, typename Src> bool test_assign(const Dst&, const Src&, int traversal, int unrolling) { - internal::assign_traits<Dst,Src>::debug(); - bool res = internal::assign_traits<Dst,Src>::Traversal==traversal - && internal::assign_traits<Dst,Src>::Unrolling==unrolling; +#ifdef EIGEN_TEST_EVALUATORS + typedef internal::copy_using_evaluator_traits<internal::evaluator<Dst>,internal::evaluator<Src>, internal::assign_op<typename Dst::Scalar> > traits; +#else + typedef internal::assign_traits<Dst,Src> traits; +#endif + bool res = traits::Traversal==traversal && traits::Unrolling==unrolling; if(!res) { + std::cerr << "Src: " << demangle_flags(Src::Flags) << std::endl; +#ifdef EIGEN_TEST_EVALUATORS + std::cerr << " " << demangle_flags(internal::evaluator<Src>::Flags) << std::endl; +#endif + std::cerr << "Dst: " << demangle_flags(Dst::Flags) << std::endl; +#ifdef EIGEN_TEST_EVALUATORS + std::cerr << " " << demangle_flags(internal::evaluator<Dst>::Flags) << std::endl; +#endif + traits::debug(); std::cerr << " Expected Traversal == " << demangle_traversal(traversal) - << " got " << demangle_traversal(internal::assign_traits<Dst,Src>::Traversal) << "\n"; + << " got " << demangle_traversal(traits::Traversal) << "\n"; std::cerr << " Expected Unrolling == " << demangle_unrolling(unrolling) - << " got " << demangle_unrolling(internal::assign_traits<Dst,Src>::Unrolling) << "\n"; + << " got " << demangle_unrolling(traits::Unrolling) << "\n"; } return res; } @@ -47,15 +71,27 @@ bool test_assign(const Dst&, const Src&, int traversal, int unrolling) template<typename Dst, typename Src> bool test_assign(int traversal, int unrolling) { - internal::assign_traits<Dst,Src>::debug(); - bool res = internal::assign_traits<Dst,Src>::Traversal==traversal - && internal::assign_traits<Dst,Src>::Unrolling==unrolling; +#ifdef EIGEN_TEST_EVALUATORS + typedef internal::copy_using_evaluator_traits<internal::evaluator<Dst>,internal::evaluator<Src>, internal::assign_op<typename Dst::Scalar> > traits; +#else + typedef internal::assign_traits<Dst,Src> traits; +#endif + bool res = traits::Traversal==traversal && traits::Unrolling==unrolling; if(!res) { + std::cerr << "Src: " << demangle_flags(Src::Flags) << std::endl; +#ifdef EIGEN_TEST_EVALUATORS + std::cerr << " " << demangle_flags(internal::evaluator<Src>::Flags) << std::endl; +#endif + std::cerr << "Dst: " << demangle_flags(Dst::Flags) << std::endl; +#ifdef EIGEN_TEST_EVALUATORS + std::cerr << " " << demangle_flags(internal::evaluator<Dst>::Flags) << std::endl; +#endif + traits::debug(); std::cerr << " Expected Traversal == " << demangle_traversal(traversal) - << " got " << demangle_traversal(internal::assign_traits<Dst,Src>::Traversal) << "\n"; + << " got " << demangle_traversal(traits::Traversal) << "\n"; std::cerr << " Expected Unrolling == " << demangle_unrolling(unrolling) - << " got " << demangle_unrolling(internal::assign_traits<Dst,Src>::Unrolling) << "\n"; + << " got " << demangle_unrolling(traits::Unrolling) << "\n"; } return res; } @@ -63,10 +99,21 @@ bool test_assign(int traversal, int unrolling) template<typename Xpr> bool test_redux(const Xpr&, int traversal, int unrolling) { +#ifdef EIGEN_TEST_EVALUATORS + typedef internal::redux_traits<internal::scalar_sum_op<typename Xpr::Scalar>,internal::redux_evaluator<Xpr> > traits; +#else typedef internal::redux_traits<internal::scalar_sum_op<typename Xpr::Scalar>,Xpr> traits; +#endif + bool res = traits::Traversal==traversal && traits::Unrolling==unrolling; if(!res) { + std::cerr << demangle_flags(Xpr::Flags) << std::endl; +#ifdef EIGEN_TEST_EVALUATORS + std::cerr << demangle_flags(internal::evaluator<Xpr>::Flags) << std::endl; +#endif + traits::debug(); + std::cerr << " Expected Traversal == " << demangle_traversal(traversal) << " got " << demangle_traversal(traits::Traversal) << "\n"; std::cerr << " Expected Unrolling == " << demangle_unrolling(unrolling) diff --git a/test/vectorwiseop.cpp b/test/vectorwiseop.cpp index 6cd1acdda..1631d54c4 100644 --- a/test/vectorwiseop.cpp +++ b/test/vectorwiseop.cpp @@ -104,8 +104,8 @@ template<typename ArrayType> void vectorwiseop_array(const ArrayType& m) m2 = m1; // yes, there might be an aliasing issue there but ".rowwise() /=" - // is suppposed to evaluate " m2.colwise().sum()" into to temporary to avoid - // evaluating the reducions multiple times + // is supposed to evaluate " m2.colwise().sum()" into a temporary to avoid + // evaluating the reduction multiple times if(ArrayType::RowsAtCompileTime>2 || ArrayType::RowsAtCompileTime==Dynamic) { m2.rowwise() /= m2.colwise().sum(); |