scran_test_utils
Test utilities for libscran projects
Loading...
Searching...
No Matches
scran_tests
compare_almost_equal.hpp
Go to the documentation of this file.
1
#ifndef SCRAN_TESTS_COMPARE_ALMOST_EQUAL_HPP
2
#define SCRAN_TESTS_COMPARE_ALMOST_EQUAL_HPP
3
4
#include <gtest/gtest.h>
5
#include <cmath>
6
12
namespace
scran_tests
{
13
27
inline
bool
compare_almost_equal
(
double
left,
double
right,
double
tol = 1e-8,
bool
report =
true
) {
28
if
(left != right) {
29
// Use relative tolerance to check that we get a similar float.
30
// EXPECT_DOUBLE_EQ and EXPECT_FLOAT_EQ tend to be a bit too stringent
31
// when numerical imprecision is expected. We define the relative difference
32
// as |difference| / |mean| of the two values, and check that this is
33
// below some acceptable error, in this case 1e-8.
34
//
35
// It's worth nothing that I spent a long time using EXPECT_FLOAT_EQ
36
// when I really should have been using EXPECT_DOUBLE_EQ; this would have
37
// implicitly used a relative threshold at the 8th significant figure,
38
// which is why it never failed from differences in numerical precision.
39
double
denom = std::abs(left + right) / 2;
40
double
threshold = denom * tol;
41
42
// This is effectively refactored to |difference| < threshold. However,
43
// if threshold falls below the machine epsilon - usually because
44
// |mean| is very small - we're effectively back to an exact equality
45
// test, so we need to ensure that the threshold doesn't get too small.
46
//
47
// This compromises the stringency of the test at very-near-zero values,
48
// but this could also be viewed as a feature, because we DON'T want to
49
// fail the test if one value is zero and another is slightly non-zero
50
// (e.g., when something should, in theory, perfectly cancel out).
51
if
(threshold < 1e-15) {
52
threshold = 1e-15;
53
}
54
if
(std::abs(left - right) > threshold) {
55
if
(report) {
56
EXPECT_TRUE(
false
) <<
"mismatch in almost-equal floats (expected "
<< left <<
", got "
<< right <<
")"
;
57
}
58
return
false
;
59
}
60
}
61
62
return
true
;
63
}
64
76
template
<
class
Vector_>
77
void
compare_almost_equal
(
const
Vector_& left,
const
Vector_& right,
double
tol = 1e-8) {
78
auto
n = left.size();
79
ASSERT_EQ(n, right.size());
80
for
(
decltype
(n) i = 0; i < n; ++i) {
81
if
(!
compare_almost_equal
(left[i], right[i], tol,
false
)) {
82
EXPECT_TRUE(
false
) <<
"mismatch in almost-equal floats at element "
<< i <<
" (expected "
<< left[i] <<
", got "
<< right[i] <<
")"
;
83
return
;
84
}
85
}
86
}
87
88
}
89
90
#endif
scran_tests
Test utilites for libscran.
Definition
compare_almost_equal.hpp:12
scran_tests::compare_almost_equal
bool compare_almost_equal(double left, double right, double tol=1e-8, bool report=true)
Definition
compare_almost_equal.hpp:27
Generated by
1.12.0