Plaquette
 
Loading...
Searching...
No Matches
pq_fastmath.h
1/*
2 * pq_fastmath.h
3 *
4 * Optimized mathematical functions.
5 *
6 * (c) 2022 Sofian Audry :: info(@)sofianaudry(.)com
7 *
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#ifndef PQ_FAST_MATH_H_
23#define PQ_FAST_MATH_H_
24
25#include "pq_globals.h"
26#include "pq_fixed32_trig.h"
27#include "pq_wrap.h"
28
29#include <stdint.h>
30
31namespace pq {
32
34// Source: https://www.gamedev.net/forums/topic/704525-3-quick-ways-to-calculate-the-square-root-in-c/
35inline float fastSqrt(const float& n)
36{
37 static union {int32_t i; float f;} u;
38 u.i = 0x2035AD0C + (*(int32_t*)&n >> 1);
39 return n / u.f + u.f * 0.25f;
40}
41
42inline float fastSin(float x) {
43#if defined(PQ_ARCH_32BITS)
44 x = wrap01(x/TWO_PI) * 4294967295ULL;
45 return sin32( (uint32_t)x ) / 2147483532.0f;
46#else
47 x = wrap01(x/TWO_PI) * 65535;
48 return sin16( (uint16_t)x ) / 32767.0f;
49#endif
50}
51
52inline float fastCos(float x) {
53 return fastSin(HALF_PI - x);
54}
55
56//Source: https://martin.ankerl.com/2007/10/04/optimized-pow-approximation-for-java-and-c-c/
57inline double fastPow(double a, double b) {
58 union {
59 double d;
60 int32_t x[2];
61 } u = { a };
62 u.x[1] = (int32_t)(b * (u.x[1] - 1072632447) + 1072632447);
63 u.x[0] = 0;
64 return u.d;
65}
66
67inline float fastPow(float a, float b) {
68 return (float)fastPow((double)a, (double)b);
69}
70
71// Source: https://gist.github.com/jrade/293a73f89dfef51da6522428c857802d
72// N. Schraudolph, “A Fast, Compact Approximation of the Exponential Function”,
73// Neural Computation 11, 853–862 (1999).
74// (available at https://nic.schraudolph.org/pubs/Schraudolph99.pdf)
75inline float fastExp(float x)
76{
77 constexpr float a = (1 << 23) / 0.69314718f;
78 constexpr float b = (1 << 23) * (127 - 0.043677448f);
79 x = a * x + b;
80
81 // Remove these lines if bounds checking is not needed
82 constexpr float c = (1 << 23);
83 constexpr float d = (1 << 23) * 255;
84 if (x < c || x > d)
85 x = (x < c) ? 0.0f : d;
86
87 // With C++20 one can use std::bit_cast instead
88 uint32_t n = static_cast<uint32_t>(x);
89 memcpy(&x, &n, 4);
90 return x;
91}
92
93// inline double fastExp(double x)
94// {
95// constexpr double a = (1ll << 52) / 0.6931471805599453;
96// constexpr double b = (1ll << 52) * (1023 - 0.04367744890362246);
97// x = a * x + b;
98
99// // Remove these lines if bounds checking is not needed
100// constexpr double c = (1ll << 52);
101// constexpr double d = (1ll << 52) * 2047;
102// if (x < c || x > d)
103// x = (x < c) ? 0.0 : d;
104
105// // With C++20 one can use std::bit_cast instead
106// uint64_t n = static_cast<uint64_t>(x);
107// memcpy(&x, &n, 8);
108// return x;
109// }
110
111} // namespace pq
112
113#endif