17typedef std::true_type MADE_FOR_INTEGERS;
18typedef std::false_type MADE_FOR_FLOATS;
33template <
typename T>
bool equals(T
const x, T
const y) {
return equals(
x,
y, std::is_integral<T>()); }
41template <
typename T>
inline bool equals(T
const x, T
const y, MADE_FOR_INTEGERS) {
return x ==
y; }
54template <
typename T>
inline bool equals(T
const x, T
const y, MADE_FOR_FLOATS) {
56 if (std::isinf(
x) && std::isinf(
y)) {
58 return std::isnan(
x -
y);
63 int const exp = y < std::numeric_limits<T>::min() ? std::numeric_limits<T>::min_exponent - 1 : std::ilogb(
y);
65 return std::abs(
x -
y) <= std::ldexp(std::numeric_limits<T>::epsilon(), exp);
77template <
typename T> MANTID_KERNEL_DLL
bool ltEquals(T
const x, T
const y) {
return (
equals(
x,
y) ||
x <
y); }
87template <
typename T> MANTID_KERNEL_DLL
bool gtEquals(T
const x, T
const y) {
return (
equals(
x,
y) ||
x >
y); }
92#pragma clang diagnostic push
93#pragma clang diagnostic ignored "-Wabsolute-value"
103#pragma clang diagnostic pop
116 T
const num = absoluteDifference<T>(
x,
y);
117 if (num <= std::numeric_limits<T>::epsilon()) {
119 return static_cast<T
>(0);
122 T
const denom =
static_cast<T
>((std::abs(
x) + std::abs(
y)) /
static_cast<T
>(2));
142#pragma clang diagnostic push
143#pragma clang diagnostic ignored "-Wabsolute-value"
146template <
typename T,
typename S>
151#pragma clang diagnostic pop
163template <
typename T,
typename S>
166 if (std::isinf(
x) && std::isinf(
y))
168 return std::isnan(
static_cast<S
>(
x -
y));
186#pragma clang diagnostic push
187#pragma clang diagnostic ignored "-Wabsolute-value"
189template <
typename T,
typename S>
191 S
const num =
static_cast<S
>(std::llabs(
x -
y));
192 if (num ==
static_cast<S
>(0)) {
195 S
const denom =
static_cast<S
>(std::llabs(
x) + std::llabs(
y));
196 return num <= static_cast<S>(2) * denom *
tolerance;
200#pragma clang diagnostic pop
212template <
typename T,
typename S>
215 if (std::isinf(
x) && std::isinf(
y))
217 return std::isnan(
static_cast<S
>(
x -
y));
218 S
const num =
static_cast<S
>(absoluteDifference<T>(
x,
y));
219 if (num <= std::numeric_limits<S>::epsilon()) {
224 S
const denom =
static_cast<S
>(0.5) *
static_cast<S
>(std::abs(
x) + std::abs(
y));
238template DLLExport bool equals<double>(
double const,
double const);
239template DLLExport bool equals<float>(
float const,
float const);
240template DLLExport bool ltEquals<double>(
double const,
double const);
241template DLLExport bool ltEquals<float>(
float const,
float const);
242template DLLExport bool gtEquals<double>(
double const,
double const);
243template DLLExport bool gtEquals<float>(
float const,
float const);
245template DLLExport double absoluteDifference<double>(
double const,
double const);
246template DLLExport float absoluteDifference<float>(
float const,
float const);
247template DLLExport double relativeDifference<double>(
double const,
double const);
248template DLLExport float relativeDifference<float>(
float const,
float const);
250template DLLExport bool withinAbsoluteDifference<double>(
double const,
double const,
double const);
251template DLLExport bool withinAbsoluteDifference<float>(
float const,
float const,
float const);
252template DLLExport bool withinAbsoluteDifference<int>(
int const,
int const,
int const);
253template DLLExport bool withinAbsoluteDifference<unsigned int>(
unsigned int const,
unsigned int const,
255template DLLExport bool withinAbsoluteDifference<long>(
long const,
long const,
long const);
256template DLLExport bool withinAbsoluteDifference<long long>(
long long const,
long long const,
long long const);
258template DLLExport bool withinRelativeDifference<double>(
double const,
double const,
double const);
259template DLLExport bool withinRelativeDifference<float>(
float const,
float const,
float const);
260template DLLExport bool withinRelativeDifference<int>(
int const,
int const,
int const);
261template DLLExport bool withinRelativeDifference<unsigned int>(
unsigned int const,
unsigned int const,
263template DLLExport bool withinRelativeDifference<long>(
long const,
long const,
long const);
264template DLLExport bool withinRelativeDifference<long long>(
long long const,
long long const,
long long const);
266template DLLExport bool withinAbsoluteDifference<float, double>(
float const,
float const,
double const);
267template DLLExport bool withinAbsoluteDifference<int, double>(
int const,
int const,
double const);
268template DLLExport bool withinAbsoluteDifference<unsigned int, double>(
unsigned int const,
unsigned int const,
270template DLLExport bool withinAbsoluteDifference<long, double>(
long const,
long const,
double const);
271template DLLExport bool withinAbsoluteDifference<unsigned long, double>(
unsigned long const,
unsigned long const,
273template DLLExport bool withinAbsoluteDifference<long long, double>(
long long const,
long long const,
double const);
274template DLLExport bool withinAbsoluteDifference<unsigned long long, double>(
unsigned long long const,
275 unsigned long long const,
double const);
277template DLLExport bool withinRelativeDifference<float, double>(
float const,
float const,
double const);
278template DLLExport bool withinRelativeDifference<int, double>(
int const,
int const,
double const);
279template DLLExport bool withinRelativeDifference<unsigned int, double>(
unsigned int const,
unsigned int const,
281template DLLExport bool withinRelativeDifference<long, double>(
long const,
long const,
double const);
282template DLLExport bool withinRelativeDifference<unsigned long, double>(
unsigned long const,
unsigned long const,
284template DLLExport bool withinRelativeDifference<long long, double>(
long long const,
long long const,
double const);
285template DLLExport bool withinRelativeDifference<unsigned long long, double>(
unsigned long long const,
286 unsigned long long const,
double const);
323 double diff2 = (V1 - V2).norm2(), denom4;
324 if (diff2 < 1 && diff2 <= std::numeric_limits<double>::epsilon()) {
326 double const scale = std::max({V1.
X(), V1.
Y(), V1.
Z()});
327 if (scale < 1 && scale * scale < std::numeric_limits<double>::epsilon()) {
328 V3D const v1 = V1 / scale, v2 = V2 / scale;
329 diff2 = (v1 - v2).norm();
330 denom4 = std::sqrt(v1.
norm()) * sqrt(v2.norm());
337 denom4 =
static_cast<double>(V1.
norm2() * V2.
norm2());
340 if (std::isinf(denom4)) {
341 double const scale = 1.0 / std::max({V1.
X(), V1.
Y(), V1.
Z(), V2.
X(), V2.
Y(), V2.
Z()});
342 V3D const v1 = V1 * scale, v2 = V2 * scale;
343 diff2 = (v1 - v2).norm();
344 denom4 = std::sqrt(v1.norm()) * sqrt(v2.norm());
349 if (denom4 <= 1. && !
ltEquals(diff2, tol2)) {
355 return ltEquals(diff2 * diff2, denom4 * tol2 * tol2);
#define DLLExport
Definitions of the DLLImport compiler directives for MSVC.
constexpr double X() const noexcept
Get x.
constexpr double Y() const noexcept
Get y.
double norm() const noexcept
constexpr double norm2() const noexcept
Vector length squared.
constexpr double Z() const noexcept
Get z.
MANTID_KERNEL_DLL bool withinRelativeDifference(T const x, T const y, S const tolerance)
Test whether x, y are within relative tolerance tol.
MANTID_KERNEL_DLL bool equals(T const x, T const y)
Test for equality of doubles using compiler-defined precision.
MANTID_KERNEL_DLL bool gtEquals(T const x, T const y)
Test whether x>=y within machine precision.
MANTID_KERNEL_DLL T absoluteDifference(T const x, T const y)
Calculate absolute difference between x, y.
DLLExport bool withinAbsoluteDifference< V3D, double >(V3D const V1, V3D const V2, double const tolerance)
Template specialization for V3D.
MANTID_KERNEL_DLL T relativeDifference(T const x, T const y)
Calculate relative difference between x, y.
MANTID_KERNEL_DLL bool ltEquals(T const x, T const y)
Test whether x<=y within machine precision.
MANTID_KERNEL_DLL bool withinAbsoluteDifference(T const x, T const y, S const tolerance)
Test whether x, y are within absolute tolerance tol.
DLLExport bool withinRelativeDifference< V3D, double >(V3D const V1, V3D const V2, double const tolerance)
Compare 3D vectors (class V3D) for relative difference to within the given tolerance.