Several files were removed from this patch due to not applying.

Only Ellipsoid_test.cpp actually failed for me without it.

From 18aeab318cbf2df7450d8c2e5e3634802345454c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-No=C3=ABl=20Grad?= <jgrad@icp.uni-stuttgart.de>
Date: Mon, 17 Apr 2023 11:58:09 +0200
Subject: [PATCH] tests: Decrease sensitivity to rounding errors

Expressions involving multiple multiplications can lead to rounding
errors in the order of 1.5 machine precision, triggering assertions
on architectures that don't support double extended precision, or
when fast-math mode is enabled.
---
 .../tests/ReactionAlgorithm_test.cpp              |  2 +-
 .../tests/SingleReaction_test.cpp                 |  4 ++--
 .../tests/reaction_methods_utils_test.cpp         |  2 +-
 .../unit_tests/EspressoSystemStandAlone_test.cpp  |  2 +-
 src/core/unit_tests/Verlet_list_test.cpp          |  2 +-
 src/core/unit_tests/p3m_test.cpp                  |  2 +-
 src/core/unit_tests/periodic_fold_test.cpp        |  4 ++--
 src/core/unit_tests/specfunc_test.cpp             |  2 +-
 src/core/unit_tests/thermostats_test.cpp          |  2 +-
 src/particle_observables/tests/algorithms.cpp     |  2 +-
 src/shapes/unit_tests/Ellipsoid_test.cpp          |  2 +-
 src/shapes/unit_tests/Sphere_test.cpp             |  2 +-
 src/utils/tests/Vector_test.cpp                   |  5 +++--
 src/utils/tests/interpolation_test.cpp            |  3 ++-
 src/utils/tests/matrix_vector_product.cpp         |  5 +++--
 src/utils/tests/vec_rotate_test.cpp               |  2 +-
 testsuite/python/analyze_chains.py                | 15 ++++++++++-----
 testsuite/python/integrator_npt_stats.py          |  2 +-
 18 files changed, 34 insertions(+), 26 deletions(-)

diff --git a/src/core/reaction_methods/tests/SingleReaction_test.cpp b/src/core/reaction_methods/tests/SingleReaction_test.cpp
index aeae253cec1..41a27b03ae9 100644
--- a/src/core/reaction_methods/tests/SingleReaction_test.cpp
+++ b/src/core/reaction_methods/tests/SingleReaction_test.cpp
@@ -32,7 +32,7 @@
 // and the configurational move probability for a given system state.
 BOOST_AUTO_TEST_CASE(SingleReaction_test) {
   using namespace ReactionMethods;
-  constexpr double tol = 100 * std::numeric_limits<double>::epsilon();
+  auto constexpr tol = 8. * 100. * std::numeric_limits<double>::epsilon();
 
   // create a reaction A -> 3 B + 4 C
   int const type_A = 0;
@@ -64,7 +64,7 @@ BOOST_AUTO_TEST_CASE(SingleReaction_test) {
             std::unordered_map<int, int>{{type_A, i}, {type_B, j}, {type_C, k}};
         auto const val = calculate_factorial_expression(reaction, p_numbers);
         auto const ref = g(i, -1) * g(j, 3) * g(k, 4);
-        BOOST_CHECK_CLOSE(val, ref, 5 * tol);
+        BOOST_CHECK_CLOSE(val, ref, 5. * tol);
       }
     }
   }
diff --git a/src/core/unit_tests/periodic_fold_test.cpp b/src/core/unit_tests/periodic_fold_test.cpp
index 7346b472c0e..49d69777c94 100644
--- a/src/core/unit_tests/periodic_fold_test.cpp
+++ b/src/core/unit_tests/periodic_fold_test.cpp
@@ -106,7 +106,7 @@ BOOST_AUTO_TEST_CASE(with_image_count) {
     BOOST_CHECK(res.first >= 0.);
     BOOST_CHECK(res.first <= box);
     BOOST_CHECK(std::abs(res.first - x + res.second * box) <=
-                std::numeric_limits<double>::epsilon());
+                4. * std::numeric_limits<double>::epsilon());
   }
 
   /* Corner right */
@@ -117,7 +117,7 @@ BOOST_AUTO_TEST_CASE(with_image_count) {
     BOOST_CHECK(res.first >= 0.);
     BOOST_CHECK(res.first < box);
     BOOST_CHECK(std::abs(res.first - x + res.second * box) <=
-                std::numeric_limits<double>::epsilon());
+                4. * std::numeric_limits<double>::epsilon());
   }
 }
 
diff --git a/src/core/unit_tests/thermostats_test.cpp b/src/core/unit_tests/thermostats_test.cpp
index 0edd7f47a44..16d5cbf992c 100644
--- a/src/core/unit_tests/thermostats_test.cpp
+++ b/src/core/unit_tests/thermostats_test.cpp
@@ -42,7 +42,7 @@
 
 // multiply by 100 because BOOST_CHECK_CLOSE takes a percentage tolerance,
 // and by 6 to account for error accumulation in thermostat functions
-constexpr auto tol = 6 * 100 * std::numeric_limits<double>::epsilon();
+auto constexpr tol = 8. * 100. * std::numeric_limits<double>::epsilon();
 
 Particle particle_factory() {
   Particle p{};
diff --git a/src/particle_observables/tests/algorithms.cpp b/src/particle_observables/tests/algorithms.cpp
index 4a1cef824cf..7fabb7c3ef4 100644
--- a/src/particle_observables/tests/algorithms.cpp
+++ b/src/particle_observables/tests/algorithms.cpp
@@ -79,7 +79,7 @@ BOOST_AUTO_TEST_CASE(algorithms_integer) {
 }
 
 BOOST_AUTO_TEST_CASE(algorithms_double) {
-  auto constexpr tol = 100 * std::numeric_limits<double>::epsilon();
+  auto constexpr tol = 8. * 100. * std::numeric_limits<double>::epsilon();
   std::vector<double> const values{1., 2., 3., 4.};
   {
     auto const res = WeightedAverage<Testing::Identity, Testing::One>()(values);
diff --git a/src/shapes/unit_tests/Ellipsoid_test.cpp b/src/shapes/unit_tests/Ellipsoid_test.cpp
index 2f4331a6147..d9d41874bf7 100644
--- a/src/shapes/unit_tests/Ellipsoid_test.cpp
+++ b/src/shapes/unit_tests/Ellipsoid_test.cpp
@@ -34,7 +34,7 @@
 
 BOOST_AUTO_TEST_CASE(dist_function) {
   // multiply by 100 because BOOST_REQUIRE_CLOSE takes a percentage tolerance
-  auto constexpr tol = std::numeric_limits<double>::epsilon() * 100;
+  auto constexpr tol = 8. * 100. * std::numeric_limits<double>::epsilon();
   double const semiaxes[3] = {3.1, 2.2, 1.3};
 
   Shapes::Ellipsoid e;
diff --git a/src/shapes/unit_tests/Sphere_test.cpp b/src/shapes/unit_tests/Sphere_test.cpp
index e6eb19aa2f7..61fb916ce7f 100644
--- a/src/shapes/unit_tests/Sphere_test.cpp
+++ b/src/shapes/unit_tests/Sphere_test.cpp
@@ -34,7 +34,7 @@ void check_distance_function(Shapes::Sphere &s) {
   Utils::Vector3d vec;
   double dist;
   // multiply by 100 because BOOST_REQUIRE_CLOSE takes a percentage tolerance
-  auto const tol = std::numeric_limits<double>::epsilon() * 100;
+  auto constexpr tol = 8. * 100. * std::numeric_limits<double>::epsilon();
 
   s.rad() = 1.0;
   pos = {0., 0., 0.};
diff --git a/src/utils/tests/Vector_test.cpp b/src/utils/tests/Vector_test.cpp
index 88bb0ad0ceb..a29709ecfc6 100644
--- a/src/utils/tests/Vector_test.cpp
+++ b/src/utils/tests/Vector_test.cpp
@@ -119,10 +119,11 @@ BOOST_AUTO_TEST_CASE(test_norm2) {
 }
 
 BOOST_AUTO_TEST_CASE(normalize) {
-  Utils::Vector3d v{1, 2, 3};
+  auto constexpr tol = 8. * 100. * std::numeric_limits<double>::epsilon();
+  Utils::Vector3d v{1., 2., 3.};
   v.normalize();
 
-  BOOST_CHECK((v.norm2() - 1.0) <= std::numeric_limits<double>::epsilon());
+  BOOST_CHECK_CLOSE(v.norm2(), 1.0, tol);
 }
 
 BOOST_AUTO_TEST_CASE(comparison_operators) {
diff --git a/src/utils/tests/interpolation_test.cpp b/src/utils/tests/interpolation_test.cpp
index 701a7456c89..b452ab32e9d 100644
--- a/src/utils/tests/interpolation_test.cpp
+++ b/src/utils/tests/interpolation_test.cpp
@@ -135,6 +135,7 @@ BOOST_AUTO_TEST_CASE(sum_of_weights_odd) {
 }
 
 BOOST_AUTO_TEST_CASE(nearest_point) {
+  auto constexpr tol = 8. * 100. * std::numeric_limits<double>::epsilon();
   std::array<int, 3> nmp;
   double weight;
   auto save_ind = [&nmp, &weight](const std::array<int, 3> &ind, double w) {
@@ -145,7 +146,7 @@ BOOST_AUTO_TEST_CASE(nearest_point) {
   bspline_3d<1>({.1, .2, .3}, save_ind, {0.5, 0.5, 0.5}, {});
 
   BOOST_CHECK((std::array<int, 3>{{0, 0, 1}} == nmp));
-  BOOST_CHECK_CLOSE(weight, 1., 100. * std::numeric_limits<double>::epsilon());
+  BOOST_CHECK_CLOSE(weight, 1., tol);
 }
 
 BOOST_AUTO_TEST_CASE(interpolation_points_3) {
diff --git a/src/utils/tests/matrix_vector_product.cpp b/src/utils/tests/matrix_vector_product.cpp
index 8f7d8f1fdec..f98d0f5bd4f 100644
--- a/src/utils/tests/matrix_vector_product.cpp
+++ b/src/utils/tests/matrix_vector_product.cpp
@@ -32,10 +32,11 @@ static constexpr std::array<std::array<int, 3>, 3> matrix{
     {{{1, 2, 9}}, {{8, 41, 6}}, {{31, 15, 99}}}};
 
 BOOST_AUTO_TEST_CASE(inner_product) {
+  auto constexpr tol = 8. * 100. * std::numeric_limits<double>::epsilon();
   const std::array<double, 3> vector{{0.5, 1.25, 3.1}};
   auto const result = Utils::matrix_vector_product<double, 3, matrix>(vector);
   for (int i = 0; i < 3; ++i) {
-    BOOST_CHECK_CLOSE(result[i], boost::inner_product(matrix[i], vector, 0.0),
-                      100. * std::numeric_limits<double>::epsilon());
+    auto const ref = boost::inner_product(matrix[i], vector, 0.0);
+    BOOST_CHECK_CLOSE(result[i], ref, tol);
   }
 }
diff --git a/src/utils/tests/vec_rotate_test.cpp b/src/utils/tests/vec_rotate_test.cpp
index c1ad10eabb7..88b2af17983 100644
--- a/src/utils/tests/vec_rotate_test.cpp
+++ b/src/utils/tests/vec_rotate_test.cpp
@@ -44,7 +44,7 @@ BOOST_AUTO_TEST_CASE(rotation) {
   auto const is = Utils::vec_rotate(k, t, v);
   auto const rel_diff = (expected - is).norm() / expected.norm();
 
-  BOOST_CHECK(rel_diff < std::numeric_limits<double>::epsilon());
+  BOOST_CHECK(rel_diff < 8. * std::numeric_limits<double>::epsilon());
 }
 
 BOOST_AUTO_TEST_CASE(angle_between) {

