diff --git a/Eigen/src/Core/NumTraits.h b/Eigen/src/Core/NumTraits.h index 09a70b713..af49abeb8 100644 --- a/Eigen/src/Core/NumTraits.h +++ b/Eigen/src/Core/NumTraits.h @@ -166,7 +166,16 @@ template<> struct NumTraits : GenericNumTraits template<> struct NumTraits : GenericNumTraits { - static inline long double dummy_precision() { return 1e-15l; } + static inline long double dummy_precision() { return static_cast(1e-15l); } + +#if defined(EIGEN_ARCH_PPC) && (__LDBL_MANT_DIG__ == 106) + // PowerPC double double causes issues with some values + static inline long double epsilon() + { + // 2^(-(__LDBL_MANT_DIG__)+1) + return static_cast(2.4651903288156618919116517665087e-32l); + } +#endif }; template struct NumTraits > diff --git a/unsupported/Eigen/src/MatrixFunctions/MatrixPower.h b/unsupported/Eigen/src/MatrixFunctions/MatrixPower.h index a3273da4e..dc8e6322f 100644 --- a/unsupported/Eigen/src/MatrixFunctions/MatrixPower.h +++ b/unsupported/Eigen/src/MatrixFunctions/MatrixPower.h @@ -282,7 +282,7 @@ inline int MatrixPowerAtomic::getPadeDegree(long double normIminusT) #endif int degree = 3; for (; degree <= maxPadeDegree; ++degree) - if (normIminusT <= maxNormForPade[degree - 3]) + if (normIminusT <= static_cast(maxNormForPade[degree - 3])) break; return degree; } diff --git a/unsupported/test/cxx11_tensor_reduction.cpp b/unsupported/test/cxx11_tensor_reduction.cpp index 1490ec3da..4030e31cf 100644 --- a/unsupported/test/cxx11_tensor_reduction.cpp +++ b/unsupported/test/cxx11_tensor_reduction.cpp @@ -484,7 +484,39 @@ static void test_reduce_middle_dims() { } } +<<<<<<< HEAD void test_cxx11_tensor_reduction() { +======= +template +void test_sum_accuracy() { + Tensor double_tensor(num_elements); + Tensor tensor(num_elements); + for (double prescribed_mean = 0; prescribed_mean <= max_mean; prescribed_mean = numext::maxi(1.0, prescribed_mean*3.99)) { + // FIXME: NormalRandomGenerator doesn't work in bfloat and half. + double_tensor.setRandom>(); + double_tensor += double_tensor.constant(prescribed_mean); + tensor = double_tensor.cast(); + + Tensor sum; + sum = tensor.sum(); + + // Compute the reference value in double precsion. + double expected_sum = 0.0; + double abs_sum = 0.0; + for (int i = 0; i < num_elements; ++i) { + expected_sum += static_cast(tensor(i)); + abs_sum += static_cast(numext::abs(tensor(i))); + } + // Test against probabilistic forward error bound. In reality, the error is much smaller + // when we use tree summation. + double err = Eigen::numext::abs(static_cast(sum()) - expected_sum); + double tol = numext::sqrt(static_cast(num_elements)) * NumTraits::epsilon() * static_cast(abs_sum); + VERIFY_LE(err, tol); + } +} + +EIGEN_DECLARE_TEST(cxx11_tensor_reduction) { +>>>>>>> 54459214a (Fix epsilon and dummy_precision values in long double for double doubles. Prevented some algorithms from converging on PPC.) CALL_SUBTEST(test_trivial_reductions()); CALL_SUBTEST(test_trivial_reductions()); CALL_SUBTEST(test_simple_reductions());