Skip to content

Commit 048485b

Browse files
committed
fix templating, skip bad tests
1 parent e32f5dc commit 048485b

File tree

6 files changed

+153
-161
lines changed

6 files changed

+153
-161
lines changed

Framework/DataObjects/inc/MantidDataObjects/TableColumn.h

Lines changed: 0 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -244,32 +244,6 @@ template <class Type> class TableColumn : public API::Column {
244244
}
245245
};
246246

247-
/// Template specialisation for long64
248-
template <>
249-
inline bool TableColumn<int64_t>::compareVectors(const std::vector<int64_t> &newVector, double tolerance,
250-
bool const) const {
251-
int64_t roundedTol = llround(tolerance);
252-
for (size_t i = 0; i < m_data.size(); i++) {
253-
if (std::llabs(m_data[i] - newVector[i]) > roundedTol) {
254-
return false;
255-
}
256-
}
257-
return true;
258-
}
259-
260-
/// Template specialisation for unsigned long int
261-
template <>
262-
inline bool TableColumn<unsigned long>::compareVectors(const std::vector<unsigned long> &newVector, double tolerance,
263-
bool const) const {
264-
long long roundedTol = llround(tolerance);
265-
for (size_t i = 0; i < m_data.size(); i++) {
266-
if (std::llabs((long long)m_data[i] - (long long)newVector[i]) > roundedTol) {
267-
return false;
268-
}
269-
}
270-
return true;
271-
}
272-
273247
/// Template specialisation for strings for comparison
274248
template <>
275249
inline bool TableColumn<std::string>::compareVectors(const std::vector<std::string> &newVector, double tolerance,
@@ -311,40 +285,6 @@ inline bool TableColumn<Kernel::V3D>::compareVectors(const std::vector<Kernel::V
311285
return true;
312286
}
313287

314-
/// Template specialisation for long64 with relative error
315-
template <>
316-
inline bool TableColumn<int64_t>::compareVectorsRelError(const std::vector<int64_t> &newVector, double tolerance,
317-
bool const) const {
318-
int64_t roundedTol = llround(tolerance);
319-
for (size_t i = 0; i < m_data.size(); i++) {
320-
int64_t num = llabs(m_data[i] - newVector[i]);
321-
int64_t den = (llabs(m_data[i]) + llabs(newVector[i])) / 2;
322-
if (den < roundedTol && num > roundedTol) {
323-
return false;
324-
} else if (num / den > roundedTol) {
325-
return false;
326-
}
327-
}
328-
return true;
329-
}
330-
331-
/// Template specialisation for unsigned long int
332-
template <>
333-
inline bool TableColumn<unsigned long>::compareVectorsRelError(const std::vector<unsigned long> &newVector,
334-
double tolerance, bool const) const {
335-
long long roundedTol = lround(tolerance);
336-
for (size_t i = 0; i < m_data.size(); i++) {
337-
long long num = labs((long long)m_data[i] - (long long)newVector[i]);
338-
long long den = (m_data[i] + newVector[i]) / 2;
339-
if (den < roundedTol && num > roundedTol) {
340-
return false;
341-
} else if (num / den > roundedTol) {
342-
return false;
343-
}
344-
}
345-
return true;
346-
}
347-
348288
/// Template specialisation for strings for comparison
349289
template <>
350290
inline bool TableColumn<std::string>::compareVectorsRelError(const std::vector<std::string> &newVector,

Framework/Kernel/inc/MantidKernel/FloatingPointComparison.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ namespace Mantid {
1616
namespace Kernel {
1717
/// Test for equality of doubles using compiler-defined precision
1818
template <typename T> MANTID_KERNEL_DLL bool equals(T const x, T const y);
19+
template <typename T> MANTID_KERNEL_DLL inline bool equals(T const x, T const y, std::true_type);
20+
template <typename T> MANTID_KERNEL_DLL inline bool equals(T const x, T const y, std::false_type);
1921
/// Test whether x<=y within machine precision
2022
template <typename T> MANTID_KERNEL_DLL bool ltEquals(T const x, T const y);
2123
/// Test whether x>=y within machine precision
@@ -27,8 +29,16 @@ template <typename T> MANTID_KERNEL_DLL T relativeDifference(T const x, T const
2729
/// Test whether x, y are within absolute tolerance tol
2830
template <typename T, typename S = T>
2931
MANTID_KERNEL_DLL bool withinAbsoluteDifference(T const x, T const y, S const tolerance);
32+
template <typename T, typename S = T>
33+
MANTID_KERNEL_DLL bool withinAbsoluteDifference(T const x, T const y, S const tolerance, std::false_type);
34+
template <typename T, typename S = T>
35+
MANTID_KERNEL_DLL bool withinAbsoluteDifference(T const x, T const y, S const tolerance, std::true_type);
3036
/// Test whether x, y are within relative tolerance tol
3137
template <typename T, typename S = T>
3238
MANTID_KERNEL_DLL bool withinRelativeDifference(T const x, T const y, S const tolerance);
39+
template <typename T, typename S = T>
40+
MANTID_KERNEL_DLL inline bool withinRelativeDifference(T const x, T const y, S const tolerance, std::false_type);
41+
template <typename T, typename S = T>
42+
MANTID_KERNEL_DLL inline bool withinRelativeDifference(T const x, T const y, S const tolerance, std::true_type);
3343
} // namespace Kernel
3444
} // namespace Mantid

Framework/Kernel/src/FloatingPointComparison.cpp

Lines changed: 91 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,26 @@
1616

1717
namespace Mantid::Kernel {
1818

19+
/**
20+
* Compare numbers for equality to within machine epsilon.
21+
* @param x :: LHS comparator
22+
* @param y :: RHS comparator
23+
* @returns True if the numbers are considered equal within machine precision.
24+
* Machine precision is a 1 at the least significant bit scaled to the same power as the numbers compared.
25+
* E.g. for 1, it is usually 1x2^{-52}
26+
* E.g. for 1x2^100, it is usually 1x2^{-52} x 1x2^100 = 1x2^{48}
27+
* False if any value is NaN. False if comparing opposite infinities.
28+
*/
29+
template <typename T> bool equals(T const x, T const y) { return equals(x, y, std::is_integral<T>()); }
30+
31+
/**
32+
* Compare integer numbers
33+
* @param x :: LHS comparator
34+
* @param y :: RHS comparator
35+
* @returns True if the numbers are considered equal
36+
*/
37+
template <typename T> inline bool equals(T const x, T const y, std::true_type) { return x == y; }
38+
1939
/**
2040
* Compare floating point numbers for equality to within
2141
* std::numeric_limits<TYPE>::epsilon precision
@@ -27,7 +47,7 @@ namespace Mantid::Kernel {
2747
* E.g. for 1x2^100, it is usually 1x2^{-52} x 1x2^100 = 1x2^{48}
2848
* False if any value is NaN. False if comparing opposite infinities.
2949
*/
30-
template <typename T> bool equals(T const x, T const y) {
50+
template <typename T> inline bool equals(T const x, T const y, std::false_type) {
3151
// handle infinities
3252
if (std::isinf(x) && std::isinf(y)) {
3353
// if x,y both +inf, x-y=NaN; if x,y both -inf, x-y=NaN; else not an NaN
@@ -104,6 +124,26 @@ template <typename T> T relativeDifference(T const x, T const y) {
104124
* false otherwise. False if either value is NaN.
105125
*/
106126
template <typename T, typename S> bool withinAbsoluteDifference(T const x, T const y, S const tolerance) {
127+
return withinAbsoluteDifference(x, y, tolerance, std::is_integral<T>());
128+
}
129+
130+
// specialization for integer types
131+
template <typename T, typename S>
132+
inline bool withinAbsoluteDifference(T const x, T const y, S const tolerance, std::true_type) {
133+
return ltEquals(static_cast<S>(std::llabs(x - y)), tolerance);
134+
}
135+
136+
/**
137+
* Compare floating point numbers for absolute difference to
138+
* within the given tolerance
139+
* @param x :: first value
140+
* @param y :: second value
141+
* @param tolerance :: the tolerance
142+
* @returns True if the numbers are considered equal within the given tolerance,
143+
* false otherwise. False if either value is NaN.
144+
*/
145+
template <typename T, typename S>
146+
inline bool withinAbsoluteDifference(T const x, T const y, S const tolerance, std::false_type) {
107147
// handle the case of infinities
108148
if (std::isinf(x) && std::isinf(y))
109149
// if both are +inf, return true; if both -inf, return true; else false
@@ -121,6 +161,31 @@ template <typename T, typename S> bool withinAbsoluteDifference(T const x, T con
121161
* false otherwise. False if either value is NaN.
122162
*/
123163
template <typename T, typename S> bool withinRelativeDifference(T const x, T const y, S const tolerance) {
164+
return withinRelativeDifference(x, y, tolerance, std::is_integral<T>());
165+
}
166+
167+
template <typename T, typename S>
168+
inline bool withinRelativeDifference(T const x, T const y, S const tolerance, std::true_type) {
169+
S const num = static_cast<S>(std::llabs(x - y));
170+
if (num == static_cast<S>(0)) {
171+
return true;
172+
} else {
173+
S const denom = static_cast<S>(std::llabs(x) + std::llabs(y));
174+
return num <= static_cast<S>(2) * denom * tolerance;
175+
}
176+
}
177+
178+
/**
179+
* Compare floating point numbers for relative difference to
180+
* within the given tolerance
181+
* @param x :: first value
182+
* @param y :: second value
183+
* @param tolerance :: the tolerance
184+
* @returns True if the numbers are considered equal within the given tolerance,
185+
* false otherwise. False if either value is NaN.
186+
*/
187+
template <typename T, typename S>
188+
inline bool withinRelativeDifference(T const x, T const y, S const tolerance, std::false_type) {
124189
// handles the case of infinities
125190
if (std::isinf(x) && std::isinf(y))
126191
// if both are +inf, return true; if both -inf, return true; else false
@@ -131,7 +196,7 @@ template <typename T, typename S> bool withinRelativeDifference(T const x, T con
131196
return true;
132197
} else {
133198
// otherwise we have to calculate the denominator
134-
S const denom = static_cast<S>(std::abs(x) + std::abs(y)) / static_cast<S>(2);
199+
S const denom = static_cast<S>(0.5) * static_cast<S>(std::abs(x) + std::abs(y));
135200
// if denom <= 1, then |x-y| > tol implies |x-y|/denom > tol, can return early
136201
// NOTE can only return early if BOTH denom > tol AND |x-y| > tol.
137202
if (denom <= static_cast<S>(1) && !ltEquals(num, tolerance)) {
@@ -156,73 +221,40 @@ template DLLExport double absoluteDifference<double>(double const, double const)
156221
template DLLExport float absoluteDifference<float>(float const, float const);
157222
template DLLExport double relativeDifference<double>(double const, double const);
158223
template DLLExport float relativeDifference<float>(float const, float const);
159-
// within difference methods
224+
// within difference methods -- object and tolerance same
160225
template DLLExport bool withinAbsoluteDifference<double>(double const, double const, double const);
161226
template DLLExport bool withinAbsoluteDifference<float>(float const, float const, float const);
227+
template DLLExport bool withinAbsoluteDifference<int>(int const, int const, int const);
228+
template DLLExport bool withinAbsoluteDifference<unsigned int>(unsigned int const, unsigned int const,
229+
unsigned int const);
230+
template DLLExport bool withinAbsoluteDifference<long>(long const, long const, long const);
231+
template DLLExport bool withinAbsoluteDifference<long long>(long long const, long long const, long long const);
232+
//
162233
template DLLExport bool withinRelativeDifference<double>(double const, double const, double const);
163234
template DLLExport bool withinRelativeDifference<float>(float const, float const, float const);
164-
// instantiations where the objects are anything and tolerance is a double
235+
template DLLExport bool withinRelativeDifference<int>(int const, int const, int const);
236+
template DLLExport bool withinRelativeDifference<unsigned int>(unsigned int const, unsigned int const,
237+
unsigned int const);
238+
template DLLExport bool withinRelativeDifference<long>(long const, long const, long const);
239+
template DLLExport bool withinRelativeDifference<long long>(long long const, long long const, long long const);
240+
// within difference methods -- tolerance is double
165241
template DLLExport bool withinAbsoluteDifference<float, double>(float const, float const, double const);
166242
template DLLExport bool withinAbsoluteDifference<int, double>(int const, int const, double const);
243+
template DLLExport bool withinAbsoluteDifference<unsigned int, double>(unsigned int const, unsigned int const,
244+
double const);
167245
template DLLExport bool withinAbsoluteDifference<long, double>(long const, long const, double const);
246+
template DLLExport bool withinAbsoluteDifference<unsigned long, double>(unsigned long const, unsigned long const,
247+
double const);
248+
template DLLExport bool withinAbsoluteDifference<long long, double>(long long const, long long const, double const);
249+
//
168250
template DLLExport bool withinRelativeDifference<float, double>(float const, float const, double const);
169251
template DLLExport bool withinRelativeDifference<int, double>(int const, int const, double const);
252+
template DLLExport bool withinRelativeDifference<unsigned int, double>(unsigned int const, unsigned int const,
253+
double const);
170254
template DLLExport bool withinRelativeDifference<long, double>(long const, long const, double const);
255+
template DLLExport bool withinRelativeDifference<unsigned long, double>(unsigned long const, unsigned long const,
256+
double const);
257+
template DLLExport bool withinRelativeDifference<long long, double>(long long const, long long const, double const);
171258
///@endcond
172259

173-
/// Template specialization for long int
174-
/// these prevent compiler warnings about using isinf and isnan on longs
175-
176-
template <> DLLExport bool equals<long>(long const x, long const y) { return x == y; }
177-
178-
template <> DLLExport bool withinAbsoluteDifference<long>(long const x, long const y, long const tolerance) {
179-
return ltEquals(std::labs(x - y), tolerance);
180-
}
181-
182-
template <> DLLExport bool withinRelativeDifference<long>(long const x, long const y, long const tolerance) {
183-
long const num = std::labs(x - y);
184-
if (num == 0) {
185-
return true;
186-
} else {
187-
long const denom = (std::labs(x) + std::labs(y)) / 2;
188-
return num <= static_cast<long>(denom * tolerance);
189-
}
190-
}
191-
192-
/// Template specialization for long long int
193-
/// these prevent compiler warnings about using isinf and isnan on longs
194-
195-
template <> DLLExport bool equals<long long>(long long const x, long long const y) { return x == y; }
196-
197-
template <>
198-
DLLExport bool withinAbsoluteDifference<long long>(long long const x, long long const y, long long const tolerance) {
199-
return ltEquals(std::llabs(x - y), tolerance);
200-
}
201-
202-
template <>
203-
DLLExport bool withinRelativeDifference<long long>(long long const x, long long const y, long long const tolerance) {
204-
long long const num = std::llabs(x - y);
205-
if (num == 0) {
206-
return true;
207-
} else {
208-
long long const denom = (std::llabs(x) + std::llabs(y)) / 2;
209-
return num <= static_cast<long long>(denom * tolerance);
210-
}
211-
}
212-
213-
/// Template specialization for unsigned int
214-
215-
template <>
216-
DLLExport bool withinAbsoluteDifference<unsigned int, double>(unsigned int const x, unsigned int const y,
217-
double const tol) {
218-
unsigned int roundedTol = static_cast<unsigned int>(llround(tol));
219-
return std::llabs(x - y) <= roundedTol;
220-
}
221-
template <>
222-
DLLExport bool withinRelativeDifference<unsigned int, double>(unsigned int const x, unsigned int const y,
223-
double const tol) {
224-
unsigned int roundedTol = static_cast<unsigned int>(llround(tol));
225-
return std::llabs(x - y) <= roundedTol;
226-
}
227-
228260
} // namespace Mantid::Kernel

Testing/SystemTests/tests/framework/ARCSReductionTest.py

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,14 @@ class ARCSReductionTest(systemtesting.MantidSystemTest):
1919
vanFile0 = ""
2020
nxspeFile = ""
2121

22+
def skipTests(self):
23+
"""
24+
This test relies on prior, errant behavior, where NaN evaluates
25+
as equal to any finite floating-point value.
26+
This might be recoverable if the reference file is updated.
27+
"""
28+
return True
29+
2230
def requiredFiles(self):
2331
return ["ARCS_23961_event.nxs", "WBARCS.nxs"]
2432

@@ -69,25 +77,21 @@ def runTest(self):
6977
SaveNXSPE(InputWorkspace="reduced", Filename=self.nxspeFile, Efixed=Ei, psi=0, KiOverKfScaling=True)
7078

7179
def validate(self):
72-
"""
73-
This test relies on prior, errant behavior, where NaN evaluates
74-
as equal to any finite floating-point value.
75-
"""
76-
# # test vanadium file
77-
# self.assertTrue(os.path.exists(self.vanFile0))
78-
# self.assertTrue(os.path.exists(self.vanFile1))
79-
# van0 = Load(self.vanFile0)
80-
# van1 = Load(self.vanFile1)
81-
# m0 = ExtractMask(van0)
82-
# m1 = ExtractMask(van1)
83-
# self.assertGreaterThan(len(m0[1]), len(m1[1])) # levelsUp=1 should have less pixels masked
84-
# DeleteWorkspace("m0")
85-
# DeleteWorkspace("m1")
86-
# DeleteWorkspace(van0)
87-
# DeleteWorkspace(van1)
88-
# self.assertTrue(os.path.exists(self.nxspeFile))
89-
# LoadNXSPE(self.nxspeFile, OutputWorkspace="nxspe")
90-
# self.disableChecking.append("Instrument")
80+
# test vanadium file
81+
self.assertTrue(os.path.exists(self.vanFile0))
82+
self.assertTrue(os.path.exists(self.vanFile1))
83+
van0 = Load(self.vanFile0)
84+
van1 = Load(self.vanFile1)
85+
m0 = ExtractMask(van0)
86+
m1 = ExtractMask(van1)
87+
self.assertGreaterThan(len(m0[1]), len(m1[1])) # levelsUp=1 should have less pixels masked
88+
DeleteWorkspace("m0")
89+
DeleteWorkspace("m1")
90+
DeleteWorkspace(van0)
91+
DeleteWorkspace(van1)
92+
self.assertTrue(os.path.exists(self.nxspeFile))
93+
LoadNXSPE(self.nxspeFile, OutputWorkspace="nxspe")
94+
self.disableChecking.append("Instrument")
9195

92-
# return "nxspe", "ARCSsystemtest.nxs"
96+
return "nxspe", "ARCSsystemtest.nxs"
9397
pass

0 commit comments

Comments
 (0)