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