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
134# ifndef NonNeg
135# define NonNeg(x) ((x) >= 0 ? (x) : 0)
136# endif
137
144template <typename T1, typename T2>
145bool FloatEqual(T1 v1, T2 v2) {
146 return Abs(CVT_DBL(v1) - CVT_DBL(v2)) < 1.e-32;
147}
148
152float Expo(float xx, float upper = 20.f, float lower = -20.f);
153
157float Power(float a, float n);
158
164template <typename T>
165T MaxInArray(const T* a, int n);
166
172template <typename T>
173T MinInArray(const T* a, int n);
174
175
176template <typename T>
177bool IsVectorAllSame(const vector<T>* a, T value);
178
179template <typename T>
180bool IsValueInVector(const vector<T>* a, T value);
181
189template <typename T>
190T Sum(int row, const T* data);
191
200template <typename T>
201T Sum(int row, int*& idx, const T* data);
202
210template <typename T>
211void BasicStatistics(const T* values, int num, double** derivedvalues,
212 T exclude = static_cast<T>(NODATA_VALUE));
213
222template <typename T>
223void BasicStatistics(const T*const * values, int num, int lyrs,
224 double*** derivedvalues, T exclude = static_cast<T>(NODATA_VALUE));
225
239float ApprSqrt(float z);
240double ApprSqrt(double z);
241
242template<typename T>
243T CalSqrt(T val) {
244#if defined(USE_APPR_PAL_MATH)
245 return ApprSqrt(val);
246#else
247 return sqrt(val);
248#endif
249}
250
258template <typename T>
259static inline T __p_exp_ln2(const T x) {
260 const T a1 = static_cast<T>(-0.9998684);
261 const T a2 = static_cast<T>(0.4982926);
262 const T a3 = static_cast<T>(-0.1595332);
263 const T a4 = static_cast<T>(0.0293641);
264 T exp_x = static_cast<T>(1.0) +
265 a1 * x +
266 a2 * x * x +
267 a3 * x * x * x +
268 a4 * x * x * x * x;
269 return static_cast<T>(1.0) / exp_x;
270}
271
277template <typename T>
278static inline T __p_exp_pos(const T x) {
279 long int k, twok;
280 static const T ln2 = static_cast<T>(M_LN2);
281 T x_;
282 k = x / ln2;
283 twok = 1ULL << k;
284 x_ = x - static_cast<T>(k) * ln2;
285 return static_cast<T>(twok) * __p_exp_ln2(x_);
286}
287
288template <typename T>
289static inline T ApprExp(const T x) {
290 if (x >= static_cast<T>(0.0))
291 return __p_exp_pos(x);
292 else
293 return static_cast<T>(1.0) / __p_exp_pos(-x);
294}
295
296template<typename T>
297T CalExp(T val) {
298#if defined(USE_APPR_PAL_MATH)
299 return ApprExp(val);
300#else
301 return exp(val);
302#endif
303}
304
309float ApprLn(float z);
310double ApprLn(double z);
311
312template<typename T>
313T CalLn(T val) {
314#if defined(USE_APPR_PAL_MATH)
315 return ApprLn(val);
316#else
317 return log(val);
318#endif
319}
320
326float pow_lookup(const float exp, const float log_base);
327
334float inline ApprPow(float a, float b) {
335 // pow(base, exponent) = pow_lookup(exponent, ln(base))
336 return pow_lookup(b, ApprLn(a));
337};
338
339template<typename T1, typename T2>
340double CalPow(T1 a, T2 b) {
341#if defined(USE_APPR_PAL_MATH)
342 return CVT_DBL(ApprPow(CVT_FLT(a), CVT_FLT(b)));
343#else
344 return pow(CVT_DBL(a),CVT_DBL(b));
345#endif
346}
347
348/************ Implementation of template functions ******************/
349template <typename T>
350T MaxInArray(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 MinInArray(const T* a, const int n) {
362 T m = a[0];
363 for (int i = 1; i < n; i++) {
364 if (a[i] < m) {
365 m = a[i];
366 }
367 }
368 return m;
369}
370
371template <typename T>
372bool IsVectorAllSame(const vector<T>* a, T value){
373 for (int i = 0; i < a->size(); i++) {
374 if (a->at(i) != value) {
375 return false;
376 }
377 }
378 return true;
379}
380
381template <typename T>
382bool IsValueInVector(const vector<T>* a, T value){
383 return std::find(a->begin(), a->end(), value) != a->end();
384}
385template <typename T>
386bool IsValueInVectorVector(const vector< vector<T>>* a, T value) {
387 for (int i = 0; i < a->size(); i++) {
388 if (std::find(a->at(i).begin(), a->at(i).end(), value) != a->at(i).end()) {
389 return true;
390 }
391 }
392 return false;
393}
394template <typename T>
395T Sum(const int row, const T* data) {
396 T tmp = 0;
397#pragma omp parallel for reduction(+:tmp)
398 for (int i = 0; i < row; i++) {
399 tmp += data[i];
400 }
401 return tmp;
402}
403
404template <typename T>
405T Sum(const int row, int*& idx, const T* data) {
406 T tmp = 0;
407#pragma omp parallel for reduction(+:tmp)
408 for (int i = 0; i < row; i++) {
409 int j = idx[i];
410 tmp += data[j];
411 }
412 return tmp;
413}
414
415template <typename T>
416void BasicStatistics(const T* values, const int num, double** derivedvalues,
417 T exclude /* = CVT_TYP(NODATA_VALUE) */) {
418 double* tmpstats = new double[6];
419 double maxv = MISSINGFLOAT;
420 double minv = MAXIMUMFLOAT;
421 int validnum = 0;
422 double sumv = 0.;
423 double std = 0.;
424 for (int i = 0; i < num; i++) {
425 if (FloatEqual(values[i], exclude)) continue;
426 if (maxv < values[i]) maxv = values[i];
427 if (minv > values[i]) minv = values[i];
428 validnum += 1;
429 sumv += values[i];
430 }
431 tmpstats[0] = CVT_DBL(validnum);
432 double mean = sumv / tmpstats[0];
433#pragma omp parallel for reduction(+:std)
434 for (int i = 0; i < num; i++) {
435 if (!FloatEqual(values[i], exclude)) {
436 std += (values[i] - mean) * (values[i] - mean);
437 }
438 }
439 std = sqrt(std / tmpstats[0]);
440 tmpstats[1] = mean;
441 tmpstats[2] = maxv;
442 tmpstats[3] = minv;
443 tmpstats[4] = std;
444 tmpstats[5] = maxv - minv;
445 *derivedvalues = tmpstats;
446}
447
448template <typename T>
449void BasicStatistics(const T*const * values, const int num, const int lyrs,
450 double*** derivedvalues, T exclude /* = CVT_TYP(NODATA_VALUE) */) {
451 double** tmpstats = new double *[6];
452 for (int i = 0; i < 6; i++) {
453 tmpstats[i] = new double[lyrs];
454 }
455 for (int j = 0; j < lyrs; j++) {
456 tmpstats[0][j] = 0.;
457 tmpstats[1][j] = 0.;
458 tmpstats[2][j] = CVT_DBL(MISSINGFLOAT);
459 tmpstats[3][j] = CVT_DBL(MAXIMUMFLOAT);
460 tmpstats[4][j] = 0.;
461 tmpstats[5][j] = 0.;
462 }
463 double* sumv = nullptr;
464 utils_array::Initialize1DArray(lyrs, sumv, 0.);
465 for (int i = 0; i < num; i++) {
466 for (int j = 0; j < lyrs; j++) {
467 if (FloatEqual(values[i][j], exclude)) continue;
468 if (tmpstats[2][j] < values[i][j]) tmpstats[2][j] = values[i][j];
469 if (tmpstats[3][j] > values[i][j]) tmpstats[3][j] = values[i][j];
470 tmpstats[0][j] += 1;
471 sumv[j] += values[i][j];
472 }
473 }
474
475 for (int j = 0; j < lyrs; j++) {
476 tmpstats[5][j] = tmpstats[2][j] - tmpstats[3][j];
477 tmpstats[1][j] = sumv[j] / tmpstats[0][j];
478 }
479 for (int j = 0; j < lyrs; j++) {
480 double tmpstd = 0;
481#pragma omp parallel for reduction(+:tmpstd)
482 for (int i = 0; i < num; i++) {
483 if (!FloatEqual(values[i][j], exclude)) {
484 tmpstd += (values[i][j] - tmpstats[1][j]) * (values[i][j] - tmpstats[1][j]);
485 }
486 }
487 tmpstats[4][j] = tmpstd;
488 }
489 for (int j = 0; j < lyrs; j++) {
490 tmpstats[4][j] = sqrt(tmpstats[4][j] / tmpstats[0][j]);
491 }
493 *derivedvalues = tmpstats;
494}
495
496} /* namespace: utils_math */
497} /* namespace: ccgl */
498
499#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:476
bool Initialize1DArray(int row, T *&data, INI_T init_value)
Initialize DT_Array1D data.
Definition: utils_array.h:344
T MaxInArray(const T *a, int n)
Get maximum value in a numeric array with size n.
Definition: utils_math.h:350
float ApprPow(float a, float b)
Approximates pow(a, b) based on the work of Harrison Ainsworth.
Definition: utils_math.h:334
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:361
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:395
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:416
bool FloatEqual(T1 v1, T2 v2)
Whether v1 is equal to v2.
Definition: utils_math.h:145
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