11#include "MantidKernel/DllConfig.h"
18typedef std::true_type MADE_FOR_INTEGERS;
19typedef std::false_type MADE_FOR_FLOATS;
34template <
typename T>
bool equals(T
const x, T
const y) {
return equals(
x,
y, std::is_integral<T>()); }
42template <
typename T>
inline bool equals(T
const x, T
const y, MADE_FOR_INTEGERS) {
return x ==
y; }
55template <
typename T>
inline bool equals(T
const x, T
const y, MADE_FOR_FLOATS) {
57 if (std::isinf(
x) && std::isinf(
y)) {
59 return std::isnan(
x -
y);
64 int const exp = y < std::numeric_limits<T>::min() ? std::numeric_limits<T>::min_exponent - 1 : std::ilogb(
y);
66 return std::abs(
x -
y) <= std::ldexp(std::numeric_limits<T>::epsilon(), exp);
78template <
typename T> MANTID_KERNEL_DLL
bool ltEquals(T
const x, T
const y) {
return (
equals(
x,
y) ||
x <
y); }
88template <
typename T> MANTID_KERNEL_DLL
bool gtEquals(T
const x, T
const y) {
return (
equals(
x,
y) ||
x >
y); }
93#pragma clang diagnostic push
94#pragma clang diagnostic ignored "-Wabsolute-value"
104#pragma clang diagnostic pop
117 T
const num = absoluteDifference<T>(
x,
y);
118 if (num <= std::numeric_limits<T>::epsilon()) {
120 return static_cast<T
>(0);
123 T
const denom =
static_cast<T
>((std::abs(
x) + std::abs(
y)) /
static_cast<T
>(2));
143#pragma clang diagnostic push
144#pragma clang diagnostic ignored "-Wabsolute-value"
147template <
typename T,
typename S>
152#pragma clang diagnostic pop
164template <
typename T,
typename S>
167 if (std::isinf(
x) && std::isinf(
y))
169 return std::isnan(
static_cast<S
>(
x -
y));
187#pragma clang diagnostic push
188#pragma clang diagnostic ignored "-Wabsolute-value"
190template <
typename T,
typename S>
192 S
const num =
static_cast<S
>(std::llabs(
x -
y));
193 if (num ==
static_cast<S
>(0)) {
196 S
const denom =
static_cast<S
>(std::llabs(
x) + std::llabs(
y));
197 return num <= static_cast<S>(2) * denom *
tolerance;
201#pragma clang diagnostic pop
213template <
typename T,
typename S>
216 if (std::isinf(
x) && std::isinf(
y))
218 return std::isnan(
static_cast<S
>(
x -
y));
219 S
const num =
static_cast<S
>(absoluteDifference<T>(
x,
y));
220 if (num <= std::numeric_limits<S>::epsilon()) {
225 S
const denom =
static_cast<S
>(0.5) *
static_cast<S
>(std::abs(
x) + std::abs(
y));
239template MANTID_KERNEL_DLL
bool equals<double>(
double const,
double const);
240template MANTID_KERNEL_DLL
bool equals<float>(
float const,
float const);
241template MANTID_KERNEL_DLL
bool ltEquals<double>(
double const,
double const);
242template MANTID_KERNEL_DLL
bool ltEquals<float>(
float const,
float const);
243template MANTID_KERNEL_DLL
bool gtEquals<double>(
double const,
double const);
244template MANTID_KERNEL_DLL
bool gtEquals<float>(
float const,
float const);
246template MANTID_KERNEL_DLL
double absoluteDifference<double>(
double const,
double const);
247template MANTID_KERNEL_DLL
float absoluteDifference<float>(
float const,
float const);
248template MANTID_KERNEL_DLL
double relativeDifference<double>(
double const,
double const);
249template MANTID_KERNEL_DLL
float relativeDifference<float>(
float const,
float const);
251template MANTID_KERNEL_DLL
bool withinAbsoluteDifference<double>(
double const,
double const,
double const);
252template MANTID_KERNEL_DLL
bool withinAbsoluteDifference<float>(
float const,
float const,
float const);
253template MANTID_KERNEL_DLL
bool withinAbsoluteDifference<int>(
int const,
int const,
int const);
254template MANTID_KERNEL_DLL
bool withinAbsoluteDifference<unsigned int>(
unsigned int const,
unsigned int const,
256template MANTID_KERNEL_DLL
bool withinAbsoluteDifference<long>(
long const,
long const,
long const);
257template MANTID_KERNEL_DLL
bool withinAbsoluteDifference<long long>(
long long const,
long long const,
long long const);
259template MANTID_KERNEL_DLL
bool withinRelativeDifference<double>(
double const,
double const,
double const);
260template MANTID_KERNEL_DLL
bool withinRelativeDifference<float>(
float const,
float const,
float const);
261template MANTID_KERNEL_DLL
bool withinRelativeDifference<int>(
int const,
int const,
int const);
262template MANTID_KERNEL_DLL
bool withinRelativeDifference<unsigned int>(
unsigned int const,
unsigned int const,
264template MANTID_KERNEL_DLL
bool withinRelativeDifference<long>(
long const,
long const,
long const);
265template MANTID_KERNEL_DLL
bool withinRelativeDifference<long long>(
long long const,
long long const,
long long const);
267template MANTID_KERNEL_DLL
bool withinAbsoluteDifference<float, double>(
float const,
float const,
double const);
268template MANTID_KERNEL_DLL
bool withinAbsoluteDifference<int, double>(
int const,
int const,
double const);
269template MANTID_KERNEL_DLL
bool withinAbsoluteDifference<unsigned int, double>(
unsigned int const,
unsigned int const,
271template MANTID_KERNEL_DLL
bool withinAbsoluteDifference<long, double>(
long const,
long const,
double const);
272template MANTID_KERNEL_DLL
bool withinAbsoluteDifference<unsigned long, double>(
unsigned long const,
273 unsigned long const,
double const);
274template MANTID_KERNEL_DLL
bool withinAbsoluteDifference<long long, double>(
long long const,
long long const,
276template MANTID_KERNEL_DLL
bool
277withinAbsoluteDifference<unsigned long long, double>(
unsigned long long const,
unsigned long long const,
double const);
279template MANTID_KERNEL_DLL
bool withinRelativeDifference<float, double>(
float const,
float const,
double const);
280template MANTID_KERNEL_DLL
bool withinRelativeDifference<int, double>(
int const,
int const,
double const);
281template MANTID_KERNEL_DLL
bool withinRelativeDifference<unsigned int, double>(
unsigned int const,
unsigned int const,
283template MANTID_KERNEL_DLL
bool withinRelativeDifference<long, double>(
long const,
long const,
double const);
284template MANTID_KERNEL_DLL
bool withinRelativeDifference<unsigned long, double>(
unsigned long const,
285 unsigned long const,
double const);
286template MANTID_KERNEL_DLL
bool withinRelativeDifference<long long, double>(
long long const,
long long const,
288template MANTID_KERNEL_DLL
bool
289withinRelativeDifference<unsigned long long, double>(
unsigned long long const,
unsigned long long const,
double const);
328 double diff2 = (V1 - V2).norm2(), denom4;
329 if (diff2 < 1 && diff2 <= std::numeric_limits<double>::epsilon()) {
331 double const scale = std::max({V1.
X(), V1.
Y(), V1.
Z()});
332 if (scale < 1 && scale * scale < std::numeric_limits<double>::epsilon()) {
333 V3D const v1 = V1 / scale, v2 = V2 / scale;
334 diff2 = (v1 - v2).norm();
335 denom4 = std::sqrt(v1.
norm()) * sqrt(v2.norm());
342 denom4 =
static_cast<double>(V1.
norm2() * V2.
norm2());
345 if (std::isinf(denom4)) {
346 double const scale = 1.0 / std::max({V1.
X(), V1.
Y(), V1.
Z(), V2.
X(), V2.
Y(), V2.
Z()});
347 V3D const v1 = V1 * scale, v2 = V2 * scale;
348 diff2 = (v1 - v2).norm();
349 denom4 = std::sqrt(v1.norm()) * sqrt(v2.norm());
354 if (denom4 <= 1. && !
ltEquals(diff2, tol2)) {
360 return ltEquals(diff2 * diff2, denom4 * tol2 * tol2);
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.
MANTID_KERNEL_DLL T relativeDifference(T const x, T const y)
Calculate relative difference between x, y.
MANTID_KERNEL_DLL 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.
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.
MANTID_KERNEL_DLL bool withinAbsoluteDifference< V3D, double >(V3D const V1, V3D const V2, double const tolerance)
Template specialization for V3D.