29 using namespace boost::math::constants;
33 using namespace boost::math::constants;
36 using neolib::math::operators::operator~;
37 using neolib::math::operators::operator+;
38 using neolib::math::operators::operator-;
39 using neolib::math::operators::operator*;
40 using neolib::math::operators::operator/;
41 using neolib::math::operators::operator<;
42 using neolib::math::operators::operator>;
43 using neolib::math::operators::operator<=;
44 using neolib::math::operators::operator>=;
45 using neolib::math::operators::operator==;
46 using neolib::math::operators::operator!=;
54 if (lhs != std::abs(std::numeric_limits<T>::infinity()) && rhs != std::abs(std::numeric_limits<T>::infinity()))
56 else if (lhs == std::numeric_limits<T>::infinity() && rhs == std::numeric_limits<T>::infinity())
57 return std::numeric_limits<T>::infinity();
58 else if (lhs == -std::numeric_limits<T>::infinity() && rhs == -std::numeric_limits<T>::infinity())
59 return -std::numeric_limits<T>::infinity();
60 else if (lhs == -std::numeric_limits<T>::infinity() && rhs == std::numeric_limits<T>::infinity())
62 else if (lhs == std::numeric_limits<T>::infinity() && rhs == -std::numeric_limits<T>::infinity())
64 else if (lhs == std::numeric_limits<T>::infinity() || rhs == std::numeric_limits<T>::infinity())
65 return std::numeric_limits<T>::infinity();
67 return -std::numeric_limits<T>::infinity();
74 if (lhs == 0.0 || rhs == 0.0)
76 else if (lhs != std::numeric_limits<T>::infinity() && rhs != std::numeric_limits<T>::infinity())
78 else if ((lhs > 0.0 && rhs > 0.0) || (lhs < 0.0 && rhs < 0.0))
79 return std::numeric_limits<T>::infinity();
81 return -std::numeric_limits<T>::infinity();
85 template <
typename T, u
int32_t D>
92 for (uint32_t index = 0; index <
D; ++index)
98 template <
typename T, u
int32_t D>
104 for (uint32_t column = 0; column <
D; ++column)
105 for (uint32_t index = 0; index <
D; ++index)
110 template <
typename T>
111 inline T
mix(
const T& aLhs,
const T& aRhs,
double aMixValue)
113 if constexpr (std::is_scalar_v<T>)
114 return static_cast<T
>(
static_cast<double>(aLhs) * (1.0 - aMixValue) +
static_cast<double>(aRhs) * aMixValue);
119 template <
typename T1,
typename T2>
120 inline T1
mix(
const T1& aLhs,
const T2&,
double)
125 template <
typename T>
126 inline T
mix(
const std::optional<T>& aLhs,
const std::optional<T>& aRhs,
double aMixValue)
128 if (!aLhs.has_value() && !aRhs.has_value())
130 else if (aLhs.has_value() && !aRhs.has_value())
132 else if (!aLhs.has_value() && aRhs.has_value())
135 return mix(*aLhs, *aRhs, aMixValue);
T inf_multiply(T lhs, T rhs)
point mix(const point &aLhs, const point &aRhs, double aMixValue)
bool nearly_equal(T lhs, T rhs, scalar epsilon=0.00001, std::enable_if_t< std::is_floating_point_v< T >, sfinae >={})