13namespace autopas::utils::Math {
29template <
class Int_t, std::enable_if_t<std::is_
integral_v<Int_t>,
bool> = true>
30Int_t
safeAdd(
const Int_t &a,
const Int_t &b,
const Int_t &valUnderflow = std::numeric_limits<Int_t>::min(),
31 const Int_t &valOverflow = std::numeric_limits<Int_t>::max()) {
33 bool overflow = __builtin_add_overflow(a, b, &result);
36 if (a < 0 and b < 0) {
37 result = valUnderflow;
58template <
class Float_t, std::enable_if_t<std::is_
floating_po
int_v<Float_t>,
bool> = true>
59Float_t
safeAdd(
const Float_t &a,
const Float_t &b,
const Float_t &valUnderflow = -std::numeric_limits<Float_t>::max(),
60 const Float_t &valOverflow = std::numeric_limits<Float_t>::max()) {
61 Float_t result = a + b;
62 if (std::isinf(result)) {
66 result = valUnderflow;
82template <
class Int_t, std::enable_if_t<std::is_
integral_v<Int_t>,
bool> = true>
83Int_t
safeSub(
const Int_t &a,
const Int_t &b,
const Int_t &valUnderflow = std::numeric_limits<Int_t>::min(),
84 const Int_t &valOverflow = std::numeric_limits<Int_t>::max()) {
86 bool overflow = __builtin_sub_overflow(a, b, &result);
90 result = valUnderflow;
111template <
class Float_t, std::enable_if_t<std::is_
floating_po
int_v<Float_t>,
bool> = true>
112Float_t
safeSub(
const Float_t &a,
const Float_t &b,
const Float_t &valUnderflow = -std::numeric_limits<Float_t>::max(),
113 const Float_t &valOverflow = std::numeric_limits<Float_t>::max()) {
114 Float_t result = a - b;
115 if (std::isinf(result)) {
117 result = valOverflow;
119 result = valUnderflow;
135template <
class Int_t, std::enable_if_t<std::is_
integral_v<Int_t>,
bool> = true>
136Int_t
safeMul(
const Int_t &a,
const Int_t &b,
const Int_t &valUnderflow = std::numeric_limits<Int_t>::min(),
137 const Int_t &valOverflow = std::numeric_limits<Int_t>::max()) {
139 bool overflow = __builtin_mul_overflow(a, b, &result);
142 if ((a < 0) xor (b < 0)) {
143 result = valUnderflow;
145 result = valOverflow;
164template <
class Float_t, std::enable_if_t<std::is_
floating_po
int_v<Float_t>,
bool> = true>
165Float_t
safeMul(
const Float_t &a,
const Float_t &b,
const Float_t &valUnderflow = -std::numeric_limits<Float_t>::max(),
166 const Float_t &valOverflow = std::numeric_limits<Float_t>::max()) {
167 Float_t result = a * b;
168 if (std::isinf(result)) {
170 result = valOverflow;
172 result = valUnderflow;
185template <
size_t exponent,
class T>
193 for (
size_t i = 0; i < exponent - 1; ++i) {
204double normalPDF(
double x);
211double normalCDF(
double x);
218double sigmoid(
double x);
248template <std::
floating_po
int FloatType>
250 static_assert(bit_size_v<FloatType> == 32 || bit_size_v<FloatType> == 64,
251 "int_t only supports 32-bit and 64-bit floating-point types yet. Please extend to 128-bit types");
253 using type = std::conditional_t<bit_size_v<FloatType> == 32, std::int32_t, std::int64_t>;
260template <std::
floating_po
int FloatType>
278template <std::
floating_po
int FloatType>
279bool isInUlp(FloatType lhs, FloatType rhs,
unsigned int ulpDistance = MAX_ULP_DISTANCE) {
286 if (lhs <
static_cast<FloatType
>(0.0) && rhs >
static_cast<FloatType
>(0.0) ||
287 lhs >
static_cast<FloatType
>(0.0) && rhs <
static_cast<FloatType
>(0.0)) {
303template <std::
floating_po
int FloatType>
304bool isNearRel(FloatType a, FloatType b,
double maxRelativeDifference = EPSILON_RELATIVE_EQUALITY) {
305 const auto greaterNumber = std::max(std::abs(a), std::abs(b));
306 const auto absoluteDifference = maxRelativeDifference * greaterNumber;
307 const auto diff = std::abs(a - b);
308 return diff <= absoluteDifference;
318template <std::
floating_po
int FloatType>
319bool isNearAbs(FloatType a, FloatType b,
double maxAbsoluteDifference) {
320 return std::abs(a - b) <= maxAbsoluteDifference;
329double roundFixed(
double d,
int fixedPrecision);
337double roundFloating(
double d,
int floatingPrecision);
344Eigen::VectorXd makeVectorXd(
const std::vector<double> &elements);
351Eigen::VectorXi makeVectorXi(
const std::vector<int> &elements);
Int_t safeAdd(const Int_t &a, const Int_t &b, const Int_t &valUnderflow=std::numeric_limits< Int_t >::min(), const Int_t &valOverflow=std::numeric_limits< Int_t >::max())
Addition function for integer types that is safe against over and underflow.
Definition: Math.h:30
bool isNearAbs(FloatType a, FloatType b, double maxAbsoluteDifference)
Determines if two doubles are near each other.
Definition: Math.h:319
Int_t safeSub(const Int_t &a, const Int_t &b, const Int_t &valUnderflow=std::numeric_limits< Int_t >::min(), const Int_t &valOverflow=std::numeric_limits< Int_t >::max())
Subtraction function for integer types that is safe against over and underflow.
Definition: Math.h:83
constexpr double EPSILON_RELATIVE_EQUALITY
This default relative EPSILON used for the isNearRel function.
Definition: Math.h:223
constexpr unsigned int MAX_ULP_DISTANCE
The default maximal allowed ULP (Units in the Last Place) distance utilized for FloatingPoint compari...
Definition: Math.h:232
constexpr size_t bit_size_v
Helper to find out the bit size of a given type.
Definition: Math.h:240
Int_t safeMul(const Int_t &a, const Int_t &b, const Int_t &valUnderflow=std::numeric_limits< Int_t >::min(), const Int_t &valOverflow=std::numeric_limits< Int_t >::max())
Multiplication function for integer types that is safe against over and underflow.
Definition: Math.h:136
T pow(const T &base)
No-overhead power function with exponent known at compile time.
Definition: Math.h:186
const double normalScale
Factor of PDF of standard normal distribution.
Definition: Math.h:17
typename internal::int_t_impl< FloatType >::type int_t
Returns the correspondingly sized integer type for a given float.
Definition: Math.h:261
Helper struct to get the correspondingly sized integer for a given floating type.
Definition: Math.h:249
std::conditional_t< bit_size_v< FloatType >==32, std::int32_t, std::int64_t > type
access the int data type
Definition: Math.h:253