diff --git a/test/array_cwise.cpp b/test/array_cwise.cpp index 379ce4af1..6e894a2ad 100644 --- a/test/array_cwise.cpp +++ b/test/array_cwise.cpp @@ -232,9 +232,24 @@ struct ref_pow { } }; +template +Base ref_pow_integer_base(Base base, Exponent exponent) { + // std::pow uses floating-point arithmetic and can round one ulp below the exact integer result before casting. + Base result(1); + while (exponent > Exponent(0)) { + if (exponent & Exponent(1)) result *= base; + exponent >>= 1; + if (exponent > Exponent(0)) base *= base; + } + return result; +} + template struct ref_pow { static Base run(Base base, Exponent exponent) { + if (NumTraits::IsInteger && (exponent > Exponent(0) || exponent == Exponent(0))) { + return ref_pow_integer_base(base, exponent); + } EIGEN_USING_STD(pow); return static_cast(pow(base, exponent)); } @@ -293,6 +308,10 @@ void float_pow_test_impl() { bool ref_is_neg = !(numext::isnan)(e) && (bool)numext::signbit(e); bool flip_sign = result_is_neg != ref_is_neg; if (flip_sign) e = -e; + } else if (e == Base(0)) { + // Implementations may disagree on the sign of pow(-0, positive non-integer). The specified result is + // +0, so do not inherit a negative zero from the scalar reference. + e = numext::abs(e); } Base a = eigenPow(j); diff --git a/test/jacobi.cpp b/test/jacobi.cpp index eab2d4500..b33e4e3d0 100644 --- a/test/jacobi.cpp +++ b/test/jacobi.cpp @@ -70,7 +70,10 @@ void verify_makeGivens(const Scalar& p, const Scalar& q) { Scalar rotated0 = rot.c() * p - rot.s() * q; Scalar rotated1 = rot.s() * p + rot.c() * q; - Scalar tol = NumTraits::epsilon() * (abs(r) + (std::numeric_limits::min)()) * Scalar(8); + // The check itself performs two rounded products and an addition/subtraction, sometimes at the safe-scaling + // overflow threshold. Keep the tolerance relative to r, but leave enough room for compiler-specific contraction and + // reassociation in the verification expression. + Scalar tol = NumTraits::epsilon() * (abs(r) + (std::numeric_limits::min)()) * Scalar(64); VERIFY(abs(rotated0 - r) <= tol); VERIFY(abs(rotated1) <= tol); VERIFY(r >= Scalar(0)); diff --git a/test/visitor.cpp b/test/visitor.cpp index 6765ed311..fb9d823bf 100644 --- a/test/visitor.cpp +++ b/test/visitor.cpp @@ -253,7 +253,9 @@ void checkOptimalTraversal_impl(const DenseBase& mat) { static constexpr bool RowMajor = Derived::IsRowMajor; Derived X(mat.rows(), mat.cols()); X.setRandom(); - TrackedVisitor visitor; + using Visitor = TrackedVisitor; + using VisitImpl = Eigen::internal::visit_impl; + Visitor visitor; visitor.visited.reserve(X.size()); X.visit(visitor); Index count = 0; @@ -266,7 +268,7 @@ void checkOptimalTraversal_impl(const DenseBase& mat) { ++count; } } - Index vectorOps = Vectorized ? ((X.innerSize() / PacketSize) * X.outerSize()) : 0; + Index vectorOps = VisitImpl::Vectorize ? ((X.innerSize() / PacketSize) * X.outerSize()) : 0; Index scalarOps = X.size() - (vectorOps * PacketSize); VERIFY_IS_EQUAL(vectorOps, visitor.vectorOps); VERIFY_IS_EQUAL(scalarOps, visitor.scalarOps); diff --git a/unsupported/test/polynomialsolver.cpp b/unsupported/test/polynomialsolver.cpp index c534b9af5..6918c3211 100644 --- a/unsupported/test/polynomialsolver.cpp +++ b/unsupported/test/polynomialsolver.cpp @@ -106,12 +106,12 @@ void evalSolverSugarFunction(const POLYNOMIAL& pols, const ROOTS& roots, const R // 2) the roots have distinct moduli // Test realRoots - std::vector calc_realRoots; - psolve.realRoots(calc_realRoots, test_precision()); - VERIFY_IS_EQUAL(calc_realRoots.size(), (size_t)real_roots.size()); - const RealScalar psPrec = sqrt(test_precision()); + std::vector calc_realRoots; + psolve.realRoots(calc_realRoots, psPrec); + VERIFY_IS_EQUAL(calc_realRoots.size(), (size_t)real_roots.size()); + for (size_t i = 0; i < calc_realRoots.size(); ++i) { bool found = false; for (Index j = 0; j < real_roots.size() && !found; ++j) { @@ -130,28 +130,28 @@ void evalSolverSugarFunction(const POLYNOMIAL& pols, const ROOTS& roots, const R bool hasRealRoot; // Test absGreatestRealRoot - RealScalar r = psolve.absGreatestRealRoot(hasRealRoot, test_precision()); + RealScalar r = psolve.absGreatestRealRoot(hasRealRoot, psPrec); VERIFY(hasRealRoot == (real_roots.size() > 0)); if (hasRealRoot) { VERIFY(internal::isApprox(real_roots.array().abs().maxCoeff(), abs(r), psPrec)); } // Test absSmallestRealRoot - r = psolve.absSmallestRealRoot(hasRealRoot, test_precision()); + r = psolve.absSmallestRealRoot(hasRealRoot, psPrec); VERIFY(hasRealRoot == (real_roots.size() > 0)); if (hasRealRoot) { VERIFY(internal::isApprox(real_roots.array().abs().minCoeff(), abs(r), psPrec)); } // Test greatestRealRoot - r = psolve.greatestRealRoot(hasRealRoot, test_precision()); + r = psolve.greatestRealRoot(hasRealRoot, psPrec); VERIFY(hasRealRoot == (real_roots.size() > 0)); if (hasRealRoot) { VERIFY(internal::isApprox(real_roots.array().maxCoeff(), r, psPrec)); } // Test smallestRealRoot - r = psolve.smallestRealRoot(hasRealRoot, test_precision()); + r = psolve.smallestRealRoot(hasRealRoot, psPrec); VERIFY(hasRealRoot == (real_roots.size() > 0)); if (hasRealRoot) { VERIFY(internal::isApprox(real_roots.array().minCoeff(), r, psPrec));