1 #ifndef INCLUDE_AL_MATH_FUNCTIONS_HPP
2 #define INCLUDE_AL_MATH_FUNCTIONS_HPP
49 #include "al/math/al_Constants.hpp"
63 bool aeq(
float a,
float b,
int maxULP = 10);
64 bool aeq(
double a,
double b,
int maxULP = 10);
71 return 20 * std::log(amp);
78 T
atLeast(
const T& v,
const T& eps);
101 T
ceil(
const T& val,
const T& step);
103 T
ceil(
const T& val,
const T& step,
const T& recStep);
106 inline uint32_t
ceilEven(uint32_t v) {
return v += v & 1UL; }
121 T
clip(
const T& value,
const T& hi = T(1),
const T& lo = T(0));
131 T
clip(
const T& v,
int& clipFlag,
const T& hi,
const T& lo);
137 T
clipS(
const T& value,
const T& hi = T(1));
144 return ::pow(10, db / 20.);
151 bool even(
const T& v);
174 T
floor(
const T& val,
const T& step);
176 T
floor(
const T& val,
const T& step,
const T& recStep);
195 T
fold(
const T& value,
const T& hi = T(1),
const T& lo = T(0));
201 T
foldOnce(
const T& value,
const T& hi = T(1),
const T& lo = T(0));
213 T
gcd(
const T& x,
const T& y);
215 template <
typename T,
typename... Ts>
216 T
gcd(
const T& x,
const Ts&... rest) {
217 return gcd(x,
gcd(rest...));
241 T
lcm(
const T& x,
const T& y);
264 bool lessAbs(
const T& v,
const T& eps = T(0.000001));
269 template <
typename T>
270 T
max(
const T& v1,
const T& v2,
const T& v3);
276 T
mean(
const T& v1,
const T& v2);
282 T
min(
const T& v1,
const T& v2,
const T& v3);
289 return to /
round(to / of);
315 bool odd(
const T& v);
321 T
poly(
const T& x,
const T& a0,
const T& a1,
const T& a2);
327 T
poly(
const T& x,
const T& a0,
const T& a1,
const T& a2,
const T& a3);
357 T
powN(T base,
unsigned power);
362 unsigned char prime(uint32_t n);
368 T
round(
const T& v,
const T& step);
375 T
round(
const T& v,
const T& step,
const T& recStep);
394 T
sgn(
const T& v,
const T& norm = T(1));
400 T
sinc(
const T& radians,
const T& eps = T(0.0001));
406 T
slope(
const T& x1,
const T& y1,
const T& x2,
const T& y2);
412 void sort(T& value1, T& value2);
433 T
trunc(
const T& v,
const T& step);
440 T
trunc(
const T& v,
const T& step,
const T& recStep);
446 bool within(
const T& v,
const T& lo,
const T& hi);
452 bool within3(
const T& v1,
const T& v2,
const T& v3,
const T& lo,
const T& hi);
458 bool withinIE(
const T& v,
const T& lo,
const T& hi);
464 T
wrap(
const T& value,
const T& hi = T(1),
const T& lo = T(0));
473 T
wrap(
const T& value,
long& numWraps,
const T& hi = T(1),
const T& lo = T(0));
481 return v ==
max ? 0 : v;
488 T
wrapOnce(
const T& value,
const T& hi = T(1));
491 T
wrapOnce(
const T& value,
const T& hi,
const T& lo);
508 #define TEM template <class T>
514 inline const float roundEps<float>() {
518 inline const double roundEps<double>() {
522 inline uint32_t deBruijn(uint32_t v) {
523 static const uint32_t deBruijnBitPosition[32] = {
524 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
525 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9};
526 return deBruijnBitPosition[(uint32_t(v * 0x077CB531UL)) >> 27];
529 const uint32_t mFactorial12u[13] = {1, 1, 2, 6, 24,
530 120, 720, 5040, 40320, 362880,
531 3628800, 39916800, 479001600};
533 const uint8_t mPrimes54[54] = {
535 2, 3, 5, 7, 11, 13, 17, 19, 23, 29,
536 31, 37, 41, 43, 47, 53, 59, 61, 67, 71,
537 73, 79, 83, 89, 97, 101, 103, 107, 109, 113,
538 127, 131, 137, 139, 149, 151, 157, 163, 167, 173,
539 179, 181, 191, 193, 197, 199, 211, 223, 227, 229,
544 inline bool aeq(
float a,
float b,
int maxULP) {
557 if (ai < 0) ai = 0x80000000 - ai;
558 if (bi < 0) bi = 0x80000000 - bi;
559 return std::abs((
float)(ai - bi)) <= maxULP;
562 inline bool aeq(
double a,
double b,
int maxULP) {
575 if (ai < 0) ai = 0x8000000000000000ULL - ai;
576 if (bi < 0) bi = 0x8000000000000000ULL - bi;
577 return std::abs((
double)(ai - bi)) <= maxULP;
580 TEM
inline T
atLeast(
const T& v,
const T& e) {
586 T ay = std::abs(y) + T(1e-10);
589 r = (x + ay) / (ay - x);
592 r = (x - ay) / (x + ay);
596 angle += (T(0.1963) * r * r - T(0.9817)) * r;
601 v = v - ((v >> 1) & 0x55555555);
602 v = (v & 0x33333333) + ((v >> 2) & 0x33333333);
603 return ((v + ((v >> 4) & 0xF0F0F0F)) * 0x1010101) >> 24;
607 TEM
inline T
ceil(
const T& v,
const T& s,
const T& r) {
621 TEM
inline T
clip(
const T& v,
const T& hi,
const T& lo) {
629 TEM
inline T
clip(
const T& v,
int& clipFlag,
const T& hi,
const T& lo) {
641 TEM
inline T
clipS(
const T& v,
const T& hi) {
return al::clip(v, hi, -hi); }
646 TEM
inline T
erf(
const T& x) {
649 const T ax2 = a * x2;
651 std::sqrt(T(1) - std::exp(-x2 * (T(4. / M_PI) + ax2) / (T(1) + ax2)));
654 inline uint32_t
factorial(uint32_t v) {
return mFactorial12u[v]; }
657 if (v <= 1)
return 1;
659 for (
int i = 2; i <= v; ++i) r *= std::sqrt(i);
664 TEM
inline T
floor(
const T& v,
const T& s,
const T& r) {
677 TEM
inline T
fold(
const T& v,
const T& hi,
const T& lo) {
679 T R =
al::wrap(v, numWraps, hi, lo);
680 if (numWraps & 1) R = hi + lo - R;
684 TEM
inline T
foldOnce(
const T& v,
const T& hi,
const T& lo) {
685 if (v > hi)
return hi + (hi - v);
686 if (v < lo)
return lo + (lo - v);
690 TEM
inline T
gaussian(
const T& v) {
return std::exp(-v * v); }
692 TEM T
gcd(
const T& x,
const T& y) {
693 if (y == T(0))
return std::abs(x);
694 return al::gcd(y,
static_cast<T
>(std::remainder(x, y)));
698 TEM T
gudermannian(
const T& x) {
return T(2) * std::atan(exp(x)) - T(M_PI_2); }
709 if (n < 0)
return T(0);
712 for (
int i = 1; i <= n; ++i) {
715 R = ((2 * i + k - 1 - x) * L1 - (i + k - 1) * L0) / i;
720 TEM
inline T
lcm(
const T& x,
const T& y) {
return (x * y) /
al::gcd(x, y); }
722 TEM T
legendreP(
int l,
int m, T ct, T st) {
740 return -0.5 + 1.5 * ct * ct;
742 return -3.0 * ct * st;
744 return 3.0 * st * st;
752 return ct * (-1.5 + 2.5 * ct * ct);
754 return (1.5 - 7.5 * ct * ct) * st;
756 return 15. * ct * st * st;
758 return -15. * st * st * st;
767 return 0.375 + ct * (-3.75 + 4.375 * ct);
769 return ct * (7.5 - 17.5 * ct * ct) * st;
771 return (-7.5 + 52.5 * ct * ct) * st * st;
773 return -105. * ct * st * st * st;
776 return 105. * st * st;
797 int M = std::abs((
double)m);
800 for (
int i = 1; i <= M; ++i) y1 *= -((i << 1) - 1) * st;
806 T y = ((M << 1) + 1) * ct * y1;
812 for (
int k = M + 2; k <= l; ++k) {
816 y = (2. + d) * ct * y1 - (1. + d) * y2;
838 TEM
inline bool lessAbs(
const T& v,
const T& eps) {
return std::abs(v) < eps; }
840 TEM
inline T
max(
const T& v1,
const T& v2,
const T& v3) {
843 TEM
inline T
mean(
const T& v1,
const T& v2) {
return (v1 + v2) * T(0.5); }
844 TEM
inline T
min(
const T& v1,
const T& v2,
const T& v3) {
851 inline T
nextAfter(
const T& x,
const T& y) {
852 return x < y ? x + 1 : x - 1;
855 inline float nextAfter(
const float& x,
const float& y) {
856 return nextafterf(x, y);
859 inline double nextAfter(
const double& x,
const double& y) {
860 return nextafter(x, y);
863 TEM
inline T
nextAfter(
const T& x,
const T& y) {
return std::nextafter(x, y); }
867 uint32_t div = (uint32_t)(v / m);
868 return T(div + 1) * m;
873 TEM
inline bool odd(
const T& v) {
return v & T(1); }
875 TEM
inline T
poly(
const T& v,
const T& a0,
const T& a1,
const T& a2) {
876 return a0 + v * (a1 + v * a2);
878 TEM
inline T
poly(
const T& v,
const T& a0,
const T& a1,
const T& a2, T a3) {
879 return a0 + v * (a1 + v * (a2 + v * a3));
882 TEM
inline T
pow2(
const T& v) {
return v * v; }
883 TEM
inline T
pow2S(
const T& v) {
return v * std::abs(v); }
884 TEM
inline T
pow3(
const T& v) {
return v * v * v; }
887 TEM
inline T
pow5(
const T& v) {
return v *
pow4(v); }
893 TEM
inline T
powN(T base,
unsigned power) {
910 return pow6(base) * base;
914 return pow8(base) * base;
917 for (
unsigned i = 10; i < power; ++i) r *= base;
923 inline uint8_t
prime(uint32_t n) {
return mPrimes54[n]; }
926 TEM
inline T
round(
const T& v,
const T& s,
const T& r) {
936 TEM
inline T
sgn(
const T& v,
const T& norm) {
937 return v == T(0) ? T(0) : v < T(0) ? -norm : norm;
940 TEM
inline T
sinc(
const T& r,
const T& eps) {
941 return (std::abs(r) > eps) ? std::sin(r) / r : std::cos(r);
944 TEM
inline T
slope(
const T& x1,
const T& y1,
const T& x2,
const T& y2) {
945 return (y2 - y1) / (x2 - x1);
948 TEM
inline void sort(T& v1, T& v2) {
957 static const T c1_6 = 1 / T(6);
958 static const T c2_6 = c1_6 * T(2);
959 return n * (n + 1) * (c2_6 * n + c1_6);
965 TEM
inline T
trunc(
const T& v,
const T& s,
const T& r) {
969 TEM
inline bool within(
const T& v,
const T& lo,
const T& hi) {
970 return !((v < lo) || (v > hi));
972 TEM
inline bool withinIE(
const T& v,
const T& lo,
const T& hi) {
973 return (!(v < lo)) && (v < hi);
976 TEM
inline bool within3(
const T& v1,
const T& v2,
const T& v3,
const T& lo,
983 TEM
inline T
wrap(
const T& v,
const T& hi,
const T& lo) {
984 if (lo == hi)
return lo;
991 if (R >= hi) R -= diff * uint32_t((R - lo) / diff);
999 if (R < lo) R += diff * uint32_t(((lo - R) / diff) + 1);
1000 if (R == diff)
return lo;
1005 TEM
inline T
wrap(
const T& v,
long& numWraps,
const T& hi,
const T& lo) {
1007 numWraps = 0xFFFFFFFF;
1018 numWraps = long((R - lo) / diff);
1019 R -= diff * numWraps;
1022 }
else if (R < lo) {
1025 numWraps = long((R - lo) / diff) - 1;
1026 R -= diff * numWraps;
1041 TEM
inline T
wrapOnce(
const T& v,
const T& hi,
const T& lo) {
1055 if (r < T(M_PI))
return r;
1056 return r - T(
long((r + M_PI) * M_1_2PI)) * M_2PI;
1057 }
else if (r < T(-M_PI)) {
1059 if (r >= T(-M_PI))
return r;
1060 return r - T(
long((r + M_PI) * M_1_2PI) - 1) * M_2PI;
1067 return r - T(M_2PI);
1068 else if (r < T(-M_PI))
1069 return r + T(M_2PI);
1073 TEM
inline T mapRange(T value, T inlow, T inhigh, T outlow, T outhigh) {
1074 float tmp = (value - inlow) / (inhigh - inlow);
1075 return tmp * (outhigh - outlow) + outlow;
1078 TEM
inline T lerp(T src, T dest, T amt) {
1079 return src * (T(1) - amt) + dest * amt;
T wrapAdd1(const T &v, const T &max)
T nextAfter(const T &x, const T &y)
T clip(const T &value, const T &hi=T(1), const T &lo=T(0))
T min(const T &v1, const T &v2, const T &v3)
uint32_t bitsSet(uint32_t v)
Returns number of bits set to 1.
void sort(T &value1, T &value2)
T round(const T &v, const T &step)
uint32_t factorial(uint32_t n0to12)
bool withinIE(const T &v, const T &lo, const T &hi)
T gcd(const T &x, const T &y)
T wrapPhase(const T &radians)
T mean(const T &v1, const T &v2)
T sgn(const T &v, const T &norm=T(1))
uint32_t trailingZeroes(uint32_t v)
Returns number of trailing zeros in 32-bit int.
T ceil(const T &val, const T &step)
T floor(const T &val, const T &step)
uint32_t ceilPow2(uint32_t value)
Returns power of two ceiling of value.
T wrapOnce(const T &value, const T &hi=T(1))
unsigned char prime(uint32_t n)
T max(const T &v1, const T &v2, const T &v3)
bool lessAbs(const T &v, const T &eps=T(0.000001))
T laguerreL(int n, int k, T x)
Generalized Laguerre polynomial L{n,k}.
T wrapPhaseOnce(const T &radians)
bool within3(const T &v1, const T &v2, const T &v3, const T &lo, const T &hi)
T powN(T base, unsigned power)
Returns value to a positive integer power.
T slope(const T &x1, const T &y1, const T &x2, const T &y2)
T legendreP(int l, int m, T t)
T sinc(const T &radians, const T &eps=T(0.0001))
T trunc(const T &v, const T &step)
T foldOnce(const T &value, const T &hi=T(1), const T &lo=T(0))
double factorialSqrt(int v)
T wrap(const T &value, const T &hi=T(1), const T &lo=T(0))
T fold(const T &value, const T &hi=T(1), const T &lo=T(0))
Returns value folded into [lo, hi].
T nextMultiple(T val, T multiple)
T round(const T &v, const T &step, const T &recStep)
T gudermannian(const T &x)
uint32_t floorPow2(uint32_t value)
Returns power of two floor of value.
T trunc(const T &v, const T &step, const T &recStep)
bool within(const T &v, const T &lo, const T &hi)
T clipS(const T &value, const T &hi=T(1))
bool aeq(float a, float b, int maxULP=10)
Return whether two floats are almost equal.
T atLeast(const T &v, const T &eps)
T atan2Fast(const T &y, const T &x)
T poly(const T &x, const T &a0, const T &a1, const T &a2)
uint32_t ceilEven(uint32_t v)
Returns even number ceiling.
T pow8(const T &v)
Returns value to the 8th power.
T pow6(const T &v)
Returns value to the 6th power.
T pow2S(const T &v)
Returns value to the 2nd power preserving sign.
T pow16(const T &v)
Returns value to the 16th power.
T angle(const Vec< N, T > &a, const Vec< N, T > &b)
Returns angle, in interval [0, pi], between two vectors.
T pow5(const T &v)
Returns value to the 5th power.
T pow2(const T &v)
Returns value to the 2nd power.
T pow3Abs(const T &v)
Returns absolute value to the 3rd power.
T lcm(const T &x, const T &y)
Returns least common multiple.
T pow4(const T &v)
Returns value to the 4th power.
T pow3(const T &v)
Returns value to the 3rd power.
T pow64(const T &v)
Returns value to the 64th power.