utils_math.h
Go to the documentation of this file.
1
12#ifndef CCGL_UTILS_MATH_H
13#define CCGL_UTILS_MATH_H
14
15#include <cmath>
16
17#include "basic.h"
18#include "utils_array.h"
19#ifndef M_E
20#define M_E 2.7182818284590452354 /* e */
21#endif
22#ifndef M_LOG2E
23#define M_LOG2E 1.4426950408889634074 /* log 2e */
24#endif
25#ifndef M_LOG10E
26#define M_LOG10E 0.43429448190325182765 /* log 10e */
27#endif
28#ifndef M_LN2 /* Avoid warning, newlib defines this as _M_LN2 */
29#define M_LN2 0.69314718055994530942 /* log e2 */
30#endif
31#ifndef M_LN10
32#define M_LN10 2.30258509299404568402 /* log e10 */
33#endif
34#ifndef M_PI
35#define M_PI 3.14159265358979323846 /* pi */
36#endif
37#ifndef M_PI_2
38#define M_PI_2 1.57079632679489661923 /* pi/2 */
39#endif
40#ifndef M_PI_4
41#define M_PI_4 0.78539816339744830962 /* pi/4 */
42#endif
43#ifndef M_1_PI
44#define M_1_PI 0.31830988618379067154 /* 1/pi */
45#endif
46#ifndef M_2_PI
47#define M_2_PI 0.63661977236758134308 /* 2/pi */
48#endif
49#ifndef M_2_SQRTPI
50#define M_2_SQRTPI 1.12837916709551257390 /* 2/sqrt(pi) */
51#endif
52#ifndef M_SQRT2
53#define M_SQRT2 1.41421356237309504880 /* sqrt(2) */
54#endif
55#ifndef M_SQRT1_2
56#define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */
57#endif
58#ifndef M_2POW23
59#define M_2POW23 8388608.0f /* pow(2, 23) */
60#endif
61
62#ifndef HUGE
63#define HUGE ((float)3.40282347e+38) /*maximum value of float*/
64#endif
65#ifndef MAXFLOAT
66#define MAXFLOAT ((float)3.40282347e+38) /*maximum value of float*/
67#endif
68#ifndef MINFLOAT
69#define MINFLOAT ((float)1.175494351e-38) /*minimum value of float*/
70#endif
71
72/* This define is in newlib's math.h (but nowhere else) */
73#ifndef M_SQRT3
74#define M_SQRT3 1.732051f /* sqrt(3) */
75#endif
76/*ADDED MATH CONSTANTS*/
77#define M_TC 0.63212055882855767840f /* 1 - 1/e */
78#define M_PI2 6.283185f /* pi*2 */
79#define M_GOLDEN 1.618034f /* golden ratio */
80#define M_1_PI2 0.15915494309189534561f /* 1/(pi*2) */
81
82/*ADDED RECIPROCAL CONSTANTS (AVOID DIVISION AT ALL COST)*/
83/*IDEALLY THIS WOULD BE IN THE COMPILER? A BETTER WAY?*/
84#define M_DIV3 0.3333333333333333333f /* 1/3 */
85#define M_DIV4 0.25f /* 1/4 */
86#define M_DIV5 0.2f /* 1/5 */
87#define M_DIV6 0.1666666666666666666f /* 1/6 */
88#define M_DIV7 0.142857143f /* 1/7 */
89#define M_DIV8 0.125f /* 1/8 */
90#define M_DIV9 0.1111111111111111111f /* 1/9 */
91#define M_DIV10 0.1f /* 1/10 */
92#define M_DIV11 0.090909091f /* 1/11 */
93#define M_DIV12 0.0833333333333333333f /* 1/12 */
94#define M_DIV13 0.076923077f /* 1/13 */
95#define M_DIV14 0.071428571f /* 1/14 */
96#define M_DIV15 0.0666666666666666666f /* 1/15 */
97#define M_DIV16 0.0625f /* 1/16 */
98#define M_DIV_LN10 0.43429448190325182765f /* 1 / ln(10) */
99
100/*ADDED PHYSICAL CONSTANTS (ADD YOUR FAVORITES:-)*/
101#define PH_C ((float)299792458) /*speed of light (m/s)*/
102#define PH_M0 ((float)1.2566370614359172950) /*mag permeability (mH/m)*/
103#define PH_H ((float)6.62606957e-34) /*planck constant (J/Hz)*/
104#define PH_HBAR ((float)1.05457172e-34) /*diract constant* (J.s/rad)*/
105#define PH_K ((float)1.3806488e-23) /*boltzmann constant (J/K)*/
106#define PH_ME ((float)9.10938291e-31) /*mass of electron (kg)*/
107#define PH_MP ((float)1.672614e-27) /*mass of proton (kg)*/
108#define PH_MN ((float)1.674920e-27) /*mass of neutron (kg)*/
109#define PH_EC ((float)1.6021917e-19) /*charge of electron (C)*/
110#define PH_F ((float)9.648670e4) /*faraday constant (C/mol)*/
111#define PH_G ((float)6.6732e-11) /*gravitational constant (N*m^2/kg^2)*/
112#define PH_AVO ((float)6.022169e23) /*avogadro constant*/
113
114
115namespace ccgl {
120namespace utils_math {
122#ifndef Max
123#define Max(a, b) ((a) >= (b) ? (a) : (b))
124#endif
126#ifndef Min
127#define Min(a, b) ((a) >= (b) ? (b) : (a))
128#endif
130#ifndef Abs
131#define Abs(x) ((x) >= 0 ? (x) : -(x))
132#endif
133
140template <typename T1, typename T2>
141bool FloatEqual(T1 v1, T2 v2) {
142 return Abs(CVT_DBL(v1) - CVT_DBL(v2)) < 1.e-32;
143}
144
148float Expo(float xx, float upper = 20.f, float lower = -20.f);
149
153float Power(float a, float n);
154
160template <typename T>
161T MaxInArray(const T* a, int n);
162
168template <typename T>
169T MinInArray(const T* a, int n);
170
178template <typename T>
179T Sum(int row, const T* data);
180
189template <typename T>
190T Sum(int row, int*& idx, const T* data);
191
199template <typename T>
200void BasicStatistics(const T* values, int num, double** derivedvalues,
201 T exclude = static_cast<T>(NODATA_VALUE));
202
211template <typename T>
212void BasicStatistics(const T*const * values, int num, int lyrs,
213 double*** derivedvalues, T exclude = static_cast<T>(NODATA_VALUE));
214
228float ApprSqrt(float z);
229double ApprSqrt(double z);
230
231template<typename T>
232T CalSqrt(T val) {
233#if defined(USE_APPR_PAL_MATH)
234 return ApprSqrt(val);
235#else
236 return sqrt(val);
237#endif
238}
239
247template <typename T>
248static inline T __p_exp_ln2(const T x) {
249 const T a1 = static_cast<T>(-0.9998684);
250 const T a2 = static_cast<T>(0.4982926);
251 const T a3 = static_cast<T>(-0.1595332);
252 const T a4 = static_cast<T>(0.0293641);
253 T exp_x = static_cast<T>(1.0) +
254 a1 * x +
255 a2 * x * x +
256 a3 * x * x * x +
257 a4 * x * x * x * x;
258 return static_cast<T>(1.0) / exp_x;
259}
260
266template <typename T>
267static inline T __p_exp_pos(const T x) {
268 long int k, twok;
269 static const T ln2 = static_cast<T>(M_LN2);
270 T x_;
271 k = x / ln2;
272 twok = 1ULL << k;
273 x_ = x - static_cast<T>(k) * ln2;
274 return static_cast<T>(twok) * __p_exp_ln2(x_);
275}
276
277template <typename T>
278static inline T ApprExp(const T x) {
279 if (x >= static_cast<T>(0.0))
280 return __p_exp_pos(x);
281 else
282 return static_cast<T>(1.0) / __p_exp_pos(-x);
283}
284
285template<typename T>
286T CalExp(T val) {
287#if defined(USE_APPR_PAL_MATH)
288 return ApprExp(val);
289#else
290 return exp(val);
291#endif
292}
293
298float ApprLn(float z);
299double ApprLn(double z);
300
301template<typename T>
302T CalLn(T val) {
303#if defined(USE_APPR_PAL_MATH)
304 return ApprLn(val);
305#else
306 return log(val);
307#endif
308}
309
315float pow_lookup(const float exp, const float log_base);
316
323float inline ApprPow(float a, float b) {
324 // pow(base, exponent) = pow_lookup(exponent, ln(base))
325 return pow_lookup(b, ApprLn(a));
326};
327
328template<typename T1, typename T2>
329double CalPow(T1 a, T2 b) {
330#if defined(USE_APPR_PAL_MATH)
331 return CVT_DBL(ApprPow(CVT_FLT(a), CVT_FLT(b)));
332#else
333 return pow(CVT_DBL(a),CVT_DBL(b));
334#endif
335}
336
337/************ Implementation of template functions ******************/
338template <typename T>
339T MaxInArray(const T* a, const int n) {
340 T m = a[0];
341 for (int i = 1; i < n; i++) {
342 if (a[i] > m) {
343 m = a[i];
344 }
345 }
346 return m;
347}
348
349template <typename T>
350T MinInArray(const T* a, const int n) {
351 T m = a[0];
352 for (int i = 1; i < n; i++) {
353 if (a[i] < m) {
354 m = a[i];
355 }
356 }
357 return m;
358}
359
360template <typename T>
361T Sum(const int row, const T* data) {
362 T tmp = 0;
363#pragma omp parallel for reduction(+:tmp)
364 for (int i = 0; i < row; i++) {
365 tmp += data[i];
366 }
367 return tmp;
368}
369
370template <typename T>
371T Sum(const int row, int*& idx, const T* data) {
372 T tmp = 0;
373#pragma omp parallel for reduction(+:tmp)
374 for (int i = 0; i < row; i++) {
375 int j = idx[i];
376 tmp += data[j];
377 }
378 return tmp;
379}
380
381template <typename T>
382void BasicStatistics(const T* values, const int num, double** derivedvalues,
383 T exclude /* = CVT_TYP(NODATA_VALUE) */) {
384 double* tmpstats = new double[6];
385 double maxv = MISSINGFLOAT;
386 double minv = MAXIMUMFLOAT;
387 int validnum = 0;
388 double sumv = 0.;
389 double std = 0.;
390 for (int i = 0; i < num; i++) {
391 if (FloatEqual(values[i], exclude)) continue;
392 if (maxv < values[i]) maxv = values[i];
393 if (minv > values[i]) minv = values[i];
394 validnum += 1;
395 sumv += values[i];
396 }
397 tmpstats[0] = CVT_DBL(validnum);
398 double mean = sumv / tmpstats[0];
399#pragma omp parallel for reduction(+:std)
400 for (int i = 0; i < num; i++) {
401 if (!FloatEqual(values[i], exclude)) {
402 std += (values[i] - mean) * (values[i] - mean);
403 }
404 }
405 std = sqrt(std / tmpstats[0]);
406 tmpstats[1] = mean;
407 tmpstats[2] = maxv;
408 tmpstats[3] = minv;
409 tmpstats[4] = std;
410 tmpstats[5] = maxv - minv;
411 *derivedvalues = tmpstats;
412}
413
414template <typename T>
415void BasicStatistics(const T*const * values, const int num, const int lyrs,
416 double*** derivedvalues, T exclude /* = CVT_TYP(NODATA_VALUE) */) {
417 double** tmpstats = new double *[6];
418 for (int i = 0; i < 6; i++) {
419 tmpstats[i] = new double[lyrs];
420 }
421 for (int j = 0; j < lyrs; j++) {
422 tmpstats[0][j] = 0.;
423 tmpstats[1][j] = 0.;
424 tmpstats[2][j] = CVT_DBL(MISSINGFLOAT);
425 tmpstats[3][j] = CVT_DBL(MAXIMUMFLOAT);
426 tmpstats[4][j] = 0.;
427 tmpstats[5][j] = 0.;
428 }
429 double* sumv = nullptr;
430 utils_array::Initialize1DArray(lyrs, sumv, 0.);
431 for (int i = 0; i < num; i++) {
432 for (int j = 0; j < lyrs; j++) {
433 if (FloatEqual(values[i][j], exclude)) continue;
434 if (tmpstats[2][j] < values[i][j]) tmpstats[2][j] = values[i][j];
435 if (tmpstats[3][j] > values[i][j]) tmpstats[3][j] = values[i][j];
436 tmpstats[0][j] += 1;
437 sumv[j] += values[i][j];
438 }
439 }
440
441 for (int j = 0; j < lyrs; j++) {
442 tmpstats[5][j] = tmpstats[2][j] - tmpstats[3][j];
443 tmpstats[1][j] = sumv[j] / tmpstats[0][j];
444 }
445 for (int j = 0; j < lyrs; j++) {
446 double tmpstd = 0;
447#pragma omp parallel for reduction(+:tmpstd)
448 for (int i = 0; i < num; i++) {
449 if (!FloatEqual(values[i][j], exclude)) {
450 tmpstd += (values[i][j] - tmpstats[1][j]) * (values[i][j] - tmpstats[1][j]);
451 }
452 }
453 tmpstats[4][j] = tmpstd;
454 }
455 for (int j = 0; j < lyrs; j++) {
456 tmpstats[4][j] = sqrt(tmpstats[4][j] / tmpstats[0][j]);
457 }
459 *derivedvalues = tmpstats;
460}
461
462} /* namespace: utils_math */
463} /* namespace: ccgl */
464
465#endif /* CCGL_UTILS_MATH_H */
Basic definitions.
#define MAXIMUMFLOAT
Maximum float value.
Definition: basic.h:255
#define MISSINGFLOAT
Missing float value.
Definition: basic.h:250
#define CVT_DBL(param)
Convert to double double
Definition: basic.h:331
#define NODATA_VALUE
Global utility definitions.
Definition: basic.h:245
#define CVT_FLT(param)
Convert to float float
Definition: basic.h:329
void Release1DArray(T *&data)
Release DT_Array1D data.
Definition: utils_array.h:460
bool Initialize1DArray(int row, T *&data, INI_T init_value)
Initialize DT_Array1D data.
Definition: utils_array.h:331
T MaxInArray(const T *a, int n)
Get maximum value in a numeric array with size n.
Definition: utils_math.h:339
float ApprPow(float a, float b)
Approximates pow(a, b) based on the work of Harrison Ainsworth.
Definition: utils_math.h:323
float Expo(float xx, float upper, float lower)
Check the argument against upper and lower boundary values prior to doing Exponential function.
Definition: utils_math.cpp:5
float pow_lookup(const float exp, const float log_base)
lookup for pow(a, b) function
Definition: utils_math.cpp:356
T MinInArray(const T *a, int n)
Get minimum value in a numeric array with size n.
Definition: utils_math.h:350
T Sum(int row, const T *data)
Sum of a numeric array Get sum value of a double array with size row.
Definition: utils_math.h:361
float ApprSqrt(const float z)
approximate sqrt
Definition: utils_math.cpp:18
float Power(const float a, const float n)
deal with positive and negative float numbers
Definition: utils_math.cpp:11
float ApprLn(const float z)
Approximates the natural logarithm, (where the base is 'e'=2.71828)
Definition: utils_math.cpp:59
void BasicStatistics(const T *values, int num, double **derivedvalues, T exclude=static_cast< T >(NODATA_VALUE))
calculate basic statistics at one time_funcs
Definition: utils_math.h:382
bool FloatEqual(T1 v1, T2 v2)
Whether v1 is equal to v2.
Definition: utils_math.h:141
Common Cross-platform Geographic Library (CCGL)
Definition: basic.cpp:17
Template functions to initialize and release arrays.
#define Abs(x)
Return absolute value.
Definition: utils_math.h:131