SPH
MathUtils.h
Go to the documentation of this file.
1 #pragma once
2 
7 
8 #include "common/Assert.h"
9 #include "math/MathBasic.h"
10 #include <cmath>
11 #include <cstring>
12 #include <limits>
13 #include <utility>
14 
16 
18 template <typename T>
19 struct Eps;
20 
21 template <>
22 struct Eps<float> {
23  constexpr static float value = 1.e-6f;
24 };
25 template <>
26 struct Eps<double> {
27  constexpr static double value = 1.e-12f;
28 };
29 
31 
34 constexpr Float LARGE = 1.e20f;
35 
39 
40 
43 template <typename T>
44 INLINE T sqrtInv(const T& f) {
45  int i;
46  // cast to float
47  float x2 = float(f) * 0.5f;
48  float y = float(f);
49  memcpy(&i, &y, sizeof(float));
50  i = 0x5f3759df - (i >> 1);
51  memcpy(&y, &i, sizeof(float));
52  return y * (1.5f - (x2 * y * y));
53 }
54 
56 template <typename T>
57 INLINE T sqrtApprox(const T f) {
58  if (f == T(0)) {
59  return T(0);
60  }
61  return T(1.f) / sqrtInv(f);
62 }
63 
64 
66 template <typename T>
67 INLINE constexpr T sqr(const T& f) noexcept {
68  return f * f;
69 }
70 
72 INLINE constexpr bool isPower2(const Size n) noexcept {
73  return n >= 1 && (n & (n - 1)) == 0;
74 }
75 
77 template <typename T>
78 INLINE T sqrt(const T f) {
79  SPH_ASSERT(f >= T(0), f);
80  return std::sqrt(f);
81 }
82 
84 INLINE Float cbrt(const Float f) {
85  return std::cbrt(f);
86 }
87 
89 INLINE int positiveMod(const int i, const int n) {
90  return (i % n + n) % n;
91 }
92 
93 
94 template <int N>
96 template <>
98  return f;
99 }
100 template <>
102  return sqrt(f);
103 }
104 template <>
106  return cbrt(f);
107 }
108 template <>
111  return sqrt(sqrt(f));
112 }
113 
114 
116 template <int N>
117 INLINE constexpr Float pow(const Float v);
118 
119 template <>
120 INLINE constexpr Float pow<0>(const Float) {
121  return 1._f;
122 }
123 template <>
124 INLINE constexpr Float pow<1>(const Float v) {
125  return v;
126 }
127 template <>
128 INLINE constexpr Float pow<2>(const Float v) {
129  return v * v;
130 }
131 template <>
132 INLINE constexpr Float pow<3>(const Float v) {
133  return v * v * v;
134 }
135 template <>
136 INLINE constexpr Float pow<4>(const Float v) {
137  return pow<2>(pow<2>(v));
138 }
139 template <>
140 INLINE constexpr Float pow<5>(const Float v) {
141  return pow<2>(pow<2>(v)) * v;
142 }
143 template <>
144 INLINE constexpr Float pow<6>(const Float v) {
145  return pow<3>(pow<2>(v));
146 }
147 template <>
148 INLINE constexpr Float pow<7>(const Float v) {
149  return pow<6>(v) * v;
150 }
151 template <>
152 INLINE constexpr Float pow<8>(const Float v) {
153  return pow<4>(pow<2>(v));
154 }
155 template <>
156 INLINE constexpr Float pow<-1>(const Float v) {
157  return 1._f / v;
158 }
159 template <>
160 INLINE constexpr Float pow<-2>(const Float v) {
161  return 1._f / (v * v);
162 }
163 template <>
164 INLINE constexpr Float pow<-3>(const Float v) {
165  return 1._f / (v * v * v);
166 }
167 template <>
168 INLINE constexpr Float pow<-4>(const Float v) {
169  return 1._f / (pow<2>(pow<2>(v)));
170 }
171 template <>
172 INLINE constexpr Float pow<-5>(const Float v) {
173  return 1._f / (v * pow<2>(pow<2>(v)));
174 }
175 template <>
176 INLINE constexpr Float pow<-8>(const Float v) {
177  return 1._f / (pow<2>(pow<4>(v)));
178 }
179 template <>
180 INLINE constexpr Float pow<-16>(const Float v) {
181  return 1._f / (pow<2>(pow<8>(v)));
182 }
183 
184 
186 template <int N>
187 INLINE constexpr Size pow(const Size v);
188 
189 template <>
190 INLINE constexpr Size pow<0>(const Size) {
191  return 1;
192 }
193 template <>
194 INLINE constexpr Size pow<1>(const Size v) {
195  return v;
196 }
197 template <>
198 INLINE constexpr Size pow<2>(const Size v) {
199  return v * v;
200 }
201 template <>
202 INLINE constexpr Size pow<3>(const Size v) {
203  return v * v * v;
204 }
205 template <>
206 INLINE constexpr Size pow<4>(const Size v) {
207  return pow<2>(pow<2>(v));
208 }
209 template <>
210 INLINE constexpr Size pow<5>(const Size v) {
211  return pow<2>(pow<2>(v)) * v;
212 }
213 template <>
214 INLINE constexpr Size pow<6>(const Size v) {
215  return pow<3>(pow<2>(v));
216 }
217 
218 
220 
221 template <typename T>
222 INLINE T pow(const T value, const T power) {
223  return std::pow(value, power);
224 }
225 
229 INLINE Float powFastest(const Float value, const Float power) {
230  SPH_ASSERT(value > 0._f && power > 0._f, value, power);
231  // https://martin.ankerl.com/2012/01/25/optimized-approximative-pow-in-c-and-cpp/
232  // this type-punning through union is undefined behavior according to C++ standard, but most compilers
233  // behave expectably ...
234  union {
235  double d;
236  int x[2];
237  } u = { value };
238  u.x[1] = (int)(power * (u.x[1] - 1072632447) + 1072632447);
239  u.x[0] = 0;
240  return u.d;
241 }
242 
246 INLINE Float powFast(Float value, const Float power) {
247  SPH_ASSERT(value > 0._f && power > 0._f, value, power);
248  // https://martin.ankerl.com/2012/01/25/optimized-approximative-pow-in-c-and-cpp/
249  int e = (int)power;
250  union {
251  double d;
252  int x[2];
253  } u = { value };
254  u.x[1] = (int)((power - e) * (u.x[1] - 1072632447) + 1072632447);
255  u.x[0] = 0;
256 
257  double r = 1.0;
258  while (e) {
259  if (e & 1) {
260  r *= value;
261  }
262  value *= value;
263  e >>= 1;
264  }
265  return r * u.d;
266 }
267 
268 template <typename T>
269 INLINE T exp(const T f) {
270  return ::exp(f);
271 }
272 
275 template <typename T>
276 INLINE auto abs(const T& f) {
277  return ::fabs(f);
278 }
279 
280 template <>
281 INLINE auto abs(const int& f) {
282  return int(::abs(f));
283 }
284 
285 template <>
286 INLINE auto abs(const Size& f) {
287  return Size(f);
288 }
289 
290 template <typename T>
291 INLINE T cos(const T f) {
292  return std::cos(f);
293 }
294 
295 template <typename T>
296 INLINE T sin(const T f) {
297  return std::sin(f);
298 }
299 
300 template <typename T>
301 INLINE T tan(const T f) {
302  return std::tan(f);
303 }
304 
305 template <typename T>
306 INLINE T acos(const T f) {
307  return std::acos(f);
308 }
309 
310 template <typename T>
311 INLINE T asin(const T f) {
312  return std::asin(f);
313 }
314 
315 template <typename T>
316 INLINE T atan(const T f) {
317  return std::atan(f);
318 }
319 
320 template <typename T>
321 INLINE T atan2(const T y, const T x) {
322  return std::atan2(y, x);
323 }
324 
325 template <typename T>
326 INLINE T exp10(const T f) {
327  return std::pow(10._f, f);
328 }
329 
330 template <typename T>
331 INLINE T log10(const T f) {
332  return std::log10(f);
333 }
334 
335 template <typename T>
336 INLINE int sgn(const T val) {
337  return (T(0) < val) - (val < T(0));
338 }
339 
340 template <typename T, typename TAmount>
341 INLINE T lerp(const T v1, const T v2, const TAmount amount) {
342  return v1 * (TAmount(1) - amount) + v2 * amount;
343 }
344 
345 template <typename T>
346 INLINE auto floor(const T& f) {
347  return std::floor(f);
348 }
349 
350 template <typename T>
351 INLINE auto ceil(const T& f) {
352  return std::ceil(f);
353 }
354 
355 template <typename T>
356 INLINE auto round(const T& f) {
357  return std::round(f);
358 }
359 
361 constexpr Float PI = 3.14159265358979323846264338327950288419716939937510582097_f;
362 
363 constexpr Float PI_INV = 1._f / PI;
364 
365 constexpr Float E = 2.718281828459045235360287471352662497757247093699959574967_f;
366 
367 constexpr Float SQRT_3 = 1.732050807568877293527446341505872366942805253810380628055_f;
368 
369 constexpr Float DEG_TO_RAD = PI / 180._f;
370 
371 constexpr Float RAD_TO_DEG = 180._f / PI;
372 
373 
376  return 1.3333333333333333333333_f * PI * pow<3>(radius);
377 }
378 
381  return 4._f * PI * pow<2>(radius);
382 }
383 
386 INLINE bool almostEqual(const Float& f1, const Float& f2, const Float& eps = EPS) {
387  return abs(f1 - f2) <= eps * (1._f + max(abs(f1), abs(f2)));
388 }
389 
Custom assertions.
#define SPH_ASSERT(x,...)
Definition: Assert.h:94
NAMESPACE_SPH_BEGIN
Definition: BarnesHut.cpp:13
const float radius
Definition: CurveDialog.cpp:18
uint32_t Size
Integral type used to index arrays (by default).
Definition: Globals.h:16
double Float
Precision used withing the code. Use Float instead of float or double where precision is important.
Definition: Globals.h:13
Basic math routines.
constexpr INLINE T max(const T &f1, const T &f2)
Definition: MathBasic.h:20
constexpr Float PI_INV
Definition: MathUtils.h:363
INLINE Float root(const Float f)
constexpr INLINE Float pow< 5 >(const Float v)
Definition: MathUtils.h:140
INLINE T sqrtApprox(const T f)
Returns an approximative value of square root.
Definition: MathUtils.h:57
INLINE int positiveMod(const int i, const int n)
Returns a positive modulo value.
Definition: MathUtils.h:89
INLINE T lerp(const T v1, const T v2, const TAmount amount)
Definition: MathUtils.h:341
constexpr Float EPS
Definition: MathUtils.h:30
INLINE Float root< 1 >(const Float f)
Definition: MathUtils.h:97
INLINE Float root< 4 >(const Float f)
Definition: MathUtils.h:109
constexpr INLINE T sqr(const T &f) noexcept
Return a squared value.
Definition: MathUtils.h:67
INLINE Float powFastest(const Float value, const Float power)
Definition: MathUtils.h:229
INLINE Float cbrt(const Float f)
Returns a cubed root of a value.
Definition: MathUtils.h:84
INLINE T sin(const T f)
Definition: MathUtils.h:296
INLINE auto floor(const T &f)
Definition: MathUtils.h:346
INLINE T cos(const T f)
Definition: MathUtils.h:291
INLINE T sqrt(const T f)
Return a squared root of a value.
Definition: MathUtils.h:78
constexpr INLINE Float pow< 3 >(const Float v)
Definition: MathUtils.h:132
constexpr INLINE bool isPower2(const Size n) noexcept
Returns true if given n is a power of 2. N must at least 1.
Definition: MathUtils.h:72
constexpr INLINE Float pow< 4 >(const Float v)
Definition: MathUtils.h:136
constexpr INLINE Float pow(const Float v)
Power for floats.
INLINE T atan(const T f)
Definition: MathUtils.h:316
INLINE int sgn(const T val)
Definition: MathUtils.h:336
constexpr INLINE Float sphereVolume(const Float radius)
Computes a volume of a sphere given its radius.
Definition: MathUtils.h:375
constexpr Float DEG_TO_RAD
Definition: MathUtils.h:369
INLINE T tan(const T f)
Definition: MathUtils.h:301
INLINE bool almostEqual(const Float &f1, const Float &f2, const Float &eps=EPS)
Definition: MathUtils.h:386
INLINE T log10(const T f)
Definition: MathUtils.h:331
INLINE Float root< 2 >(const Float f)
Definition: MathUtils.h:101
constexpr Float INFTY
Definition: MathUtils.h:38
INLINE auto round(const T &f)
Definition: MathUtils.h:356
constexpr INLINE Float pow< 6 >(const Float v)
Definition: MathUtils.h:144
INLINE T exp(const T f)
Definition: MathUtils.h:269
INLINE Float root< 3 >(const Float f)
Definition: MathUtils.h:105
constexpr INLINE Float pow< 2 >(const Float v)
Definition: MathUtils.h:128
INLINE T acos(const T f)
Definition: MathUtils.h:306
INLINE T sqrtInv(const T &f)
Definition: MathUtils.h:44
constexpr INLINE Float pow< 0 >(const Float)
Definition: MathUtils.h:120
constexpr INLINE Float sphereSurfaceArea(const Float radius)
Computes a surface area of a sphere given its radius.
Definition: MathUtils.h:380
constexpr INLINE Float pow< 7 >(const Float v)
Definition: MathUtils.h:148
INLINE T atan2(const T y, const T x)
Definition: MathUtils.h:321
INLINE T exp10(const T f)
Definition: MathUtils.h:326
INLINE Float powFast(Float value, const Float power)
Definition: MathUtils.h:246
INLINE auto ceil(const T &f)
Definition: MathUtils.h:351
constexpr INLINE Float pow< 8 >(const Float v)
Definition: MathUtils.h:152
constexpr Float E
Definition: MathUtils.h:365
constexpr Float SQRT_3
Definition: MathUtils.h:367
INLINE auto abs(const T &f)
Definition: MathUtils.h:276
constexpr INLINE Float pow< 1 >(const Float v)
Definition: MathUtils.h:124
constexpr Float RAD_TO_DEG
Definition: MathUtils.h:371
INLINE T asin(const T f)
Definition: MathUtils.h:311
constexpr Float PI
Mathematical constants.
Definition: MathUtils.h:361
constexpr Float LARGE
Definition: MathUtils.h:34
#define INLINE
Macros for conditional compilation based on selected compiler.
Definition: Object.h:31
#define NAMESPACE_SPH_END
Definition: Object.h:12
Small value (compared with 1) for given precision.
Definition: MathUtils.h:19