@@ -30,6 +30,25 @@ class FloatingPointComparisonTest : public CxxTest::TestSuite {
30
30
TS_ASSERT_EQUALS (Mantid::Kernel::equals (0.1 , 1.0001 * tol), false );
31
31
}
32
32
33
+ void test_with_NaN () {
34
+ // everything compares false with an NaN
35
+ constexpr double anan = std::numeric_limits<double >::quiet_NaN ();
36
+ constexpr double bnan = std::numeric_limits<double >::quiet_NaN ();
37
+ constexpr double real = 3.0 ;
38
+ // equals
39
+ TS_ASSERT_EQUALS (Mantid::Kernel::equals (anan, real), false );
40
+ TS_ASSERT_EQUALS (Mantid::Kernel::equals (real, anan), false );
41
+ TS_ASSERT_EQUALS (Mantid::Kernel::equals (anan, bnan), false );
42
+ // ltEquals
43
+ TS_ASSERT_EQUALS (Mantid::Kernel::ltEquals (anan, real), false );
44
+ TS_ASSERT_EQUALS (Mantid::Kernel::ltEquals (real, anan), false );
45
+ TS_ASSERT_EQUALS (Mantid::Kernel::ltEquals (anan, bnan), false );
46
+ // gtEquals
47
+ TS_ASSERT_EQUALS (Mantid::Kernel::gtEquals (anan, real), false );
48
+ TS_ASSERT_EQUALS (Mantid::Kernel::gtEquals (real, anan), false );
49
+ TS_ASSERT_EQUALS (Mantid::Kernel::gtEquals (anan, bnan), false );
50
+ }
51
+
33
52
void test_LtEquals_With_X_Equal_To_Y_Produces_True () {
34
53
TS_ASSERT_EQUALS (Mantid::Kernel::ltEquals (0.1 , 0.1 ), true );
35
54
TS_ASSERT_EQUALS (Mantid::Kernel::ltEquals (-0.1 , -0.1 ), true );
@@ -63,4 +82,99 @@ class FloatingPointComparisonTest : public CxxTest::TestSuite {
63
82
TS_ASSERT_EQUALS (Mantid::Kernel::gtEquals (-5.56 , 0.23 ), false );
64
83
TS_ASSERT_EQUALS (Mantid::Kernel::gtEquals (-0.00002 , -0.00001 ), false );
65
84
}
85
+
86
+ void test_absoluteDifference () {
87
+ constexpr double left = 1.1 , right = 1.0 ;
88
+ // test value
89
+ TS_ASSERT_EQUALS (Mantid::Kernel::absoluteDifference (left, right), std::abs (left - right));
90
+ // test positive-definiteness
91
+ TS_ASSERT_LESS_THAN (0.0 , Mantid::Kernel::absoluteDifference (left, -right));
92
+ TS_ASSERT_LESS_THAN (0.0 , Mantid::Kernel::absoluteDifference (-left, right));
93
+ TS_ASSERT_LESS_THAN (0.0 , Mantid::Kernel::absoluteDifference (-left, -right));
94
+ // test symmetry
95
+ TS_ASSERT_EQUALS (Mantid::Kernel::absoluteDifference (left, right), Mantid::Kernel::absoluteDifference (right, left));
96
+ // absolute difference with NaN is NaN
97
+ constexpr double anan = std::numeric_limits<double >::quiet_NaN ();
98
+ constexpr double bnan = std::numeric_limits<double >::quiet_NaN ();
99
+ TS_ASSERT (std::isnan (Mantid::Kernel::absoluteDifference (left, anan)));
100
+ TS_ASSERT (std::isnan (Mantid::Kernel::absoluteDifference (bnan, anan)));
101
+ }
102
+
103
+ void test_relativeDifference () {
104
+ constexpr double point3 = 0.3 , notquitepoint3 = 0.2 + 0.1 ;
105
+ TS_ASSERT_EQUALS (Mantid::Kernel::relativeDifference (point3, notquitepoint3), 0.0 );
106
+ TS_ASSERT_EQUALS (Mantid::Kernel::relativeDifference (2.3 , 2.3 ), 0.0 );
107
+ TS_ASSERT_EQUALS (Mantid::Kernel::relativeDifference (2.3e208 , 2.3e208 ), 0.0 );
108
+ // check no errors using zero
109
+ TS_ASSERT_THROWS_NOTHING (Mantid::Kernel::relativeDifference (0.0 , 0.0 ))
110
+ TS_ASSERT (!std::isnan (Mantid::Kernel::relativeDifference (0.0 , 0.0 )));
111
+ TS_ASSERT_EQUALS (Mantid::Kernel::relativeDifference (0.0 , 0.0 ), 0.0 );
112
+ // check no errors using machine epsilon
113
+ constexpr double realsmall = std::numeric_limits<double >::epsilon ();
114
+ TS_ASSERT_THROWS_NOTHING (Mantid::Kernel::relativeDifference (0.0 , realsmall))
115
+ TS_ASSERT (!std::isnan (Mantid::Kernel::relativeDifference (0.0 , realsmall)));
116
+ TS_ASSERT_EQUALS (Mantid::Kernel::relativeDifference (0.0 , realsmall), 0.0 );
117
+ // check we get correct values for normal situations
118
+ const double left = 2.6 , right = 2.7 ;
119
+ const double reldiff = 2.0 * std::abs (left - right) / (left + right);
120
+ TS_ASSERT_EQUALS (Mantid::Kernel::relativeDifference (left, right), reldiff);
121
+ TS_ASSERT_EQUALS (Mantid::Kernel::relativeDifference (right, left), reldiff);
122
+ // relative difference with NaN is NaN
123
+ constexpr double anan = std::numeric_limits<double >::quiet_NaN ();
124
+ constexpr double bnan = std::numeric_limits<double >::quiet_NaN ();
125
+ TS_ASSERT (std::isnan (Mantid::Kernel::relativeDifference (left, anan)));
126
+ TS_ASSERT (std::isnan (Mantid::Kernel::absoluteDifference (bnan, anan)));
127
+ }
128
+
129
+ void test_withinAbsoluteDifference () {
130
+ TS_ASSERT_EQUALS (Mantid::Kernel::withinAbsoluteDifference (0.3 , 0.2 , 0.1 ), true );
131
+ TS_ASSERT_EQUALS (Mantid::Kernel::withinAbsoluteDifference (0.3 , 0.1 , 0.1 ), false );
132
+ TS_ASSERT_EQUALS (Mantid::Kernel::withinAbsoluteDifference (0.01 , 0.011 , 0.01 ), true );
133
+ TS_ASSERT_EQUALS (Mantid::Kernel::withinAbsoluteDifference (0.01 , -0.011 , 0.01 ), false );
134
+ TS_ASSERT_EQUALS (Mantid::Kernel::withinAbsoluteDifference (100.1 , 100.15 , 0.1 ), true );
135
+ TS_ASSERT_EQUALS (Mantid::Kernel::withinAbsoluteDifference (12345678923456.789 , 12345679023456.788 , 0.0001 ), false );
136
+ // case of NaNs -- nothing is close to an NaN
137
+ constexpr double anan = std::numeric_limits<double >::quiet_NaN ();
138
+ constexpr double bnan = std::numeric_limits<double >::quiet_NaN ();
139
+ TS_ASSERT_EQUALS (Mantid::Kernel::withinAbsoluteDifference (anan, 0.3 , 0.1 ), false );
140
+ TS_ASSERT_EQUALS (Mantid::Kernel::withinAbsoluteDifference (anan, bnan, 0.1 ), false );
141
+ }
142
+
143
+ void test_withinRelativeDifference () {
144
+ // things difference at machine epsilon are equal
145
+ const double point3 = 0.3 , notquitepoint3 = 0.2 + 0.1 ;
146
+ TS_ASSERT_EQUALS (Mantid::Kernel::withinRelativeDifference (point3, notquitepoint3, 1 .e -307 ), true );
147
+ // some cases with zero difference
148
+ TS_ASSERT_EQUALS (Mantid::Kernel::withinRelativeDifference (2.3 , 2.3 , 1 .e -307 ), true );
149
+ TS_ASSERT_EQUALS (Mantid::Kernel::withinRelativeDifference (2.3e208 , 2.3e208 , 1 .e -307 ), true );
150
+ TS_ASSERT_EQUALS (Mantid::Kernel::withinRelativeDifference (2.3e-208 , 2.3e-208 , 0.0 ), true );
151
+ // case of large magnitude values -- even though abs diff would always fail, rel diff can still pass
152
+ // - passing
153
+ TS_ASSERT_EQUALS (Mantid::Kernel::withinAbsoluteDifference (2.31e208 , 2.32e208 , 0.01 ), false );
154
+ TS_ASSERT_EQUALS (Mantid::Kernel::withinRelativeDifference (2.31e208 , 2.32e208 , 0.01 ), true );
155
+ // - failing
156
+ TS_ASSERT_EQUALS (Mantid::Kernel::withinRelativeDifference (2.3e208 , 2.4e208 , 0.01 ), false );
157
+ // case of small magnitude values -- even though abs diff would always pass, rel diff still can fail
158
+ // - passing
159
+ TS_ASSERT_EQUALS (Mantid::Kernel::withinAbsoluteDifference (2.31e-10 , 2.32e-10 , 0.01 ), true );
160
+ TS_ASSERT_EQUALS (Mantid::Kernel::withinRelativeDifference (2.31e-10 , 2.32e-10 , 0.01 ), true );
161
+ // - failing
162
+ TS_ASSERT_EQUALS (Mantid::Kernel::withinAbsoluteDifference (2.3e-10 , 2.4e-10 , 0.01 ), true );
163
+ TS_ASSERT_EQUALS (Mantid::Kernel::withinRelativeDifference (2.3e-10 , 2.4e-10 , 0.01 ), false );
164
+ // case of normal-sized values
165
+ const double left = 2.6 , right = 2.7 , far = 3.0 ;
166
+ const double reldiff = 2.0 * std::abs (left - right) / (left + right);
167
+ const double tolerance = 1.01 * reldiff;
168
+ // - passing
169
+ TS_ASSERT_EQUALS (Mantid::Kernel::withinRelativeDifference (left, right, tolerance), true );
170
+ TS_ASSERT_EQUALS (Mantid::Kernel::withinRelativeDifference (right, left, tolerance), true );
171
+ // - failing
172
+ TS_ASSERT_EQUALS (Mantid::Kernel::withinRelativeDifference (left, far, tolerance), false );
173
+ TS_ASSERT_EQUALS (Mantid::Kernel::withinRelativeDifference (far, left, tolerance), false );
174
+ // case of NaNs -- nothing is close to an NaN
175
+ constexpr double anan = std::numeric_limits<double >::quiet_NaN ();
176
+ constexpr double bnan = std::numeric_limits<double >::quiet_NaN ();
177
+ TS_ASSERT_EQUALS (Mantid::Kernel::withinRelativeDifference (anan, 0.3 , 0.1 ), false );
178
+ TS_ASSERT_EQUALS (Mantid::Kernel::withinRelativeDifference (anan, bnan, 0.1 ), false );
179
+ }
66
180
};
0 commit comments