ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
Chi2Helper.h
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // - CloudViewer: www.cloudViewer.org -
3 // ----------------------------------------------------------------------------
4 // Copyright (c) 2018-2024 www.cloudViewer.org
5 // SPDX-License-Identifier: MIT
6 // ----------------------------------------------------------------------------
7 
8 #pragma once
9 
10 // system
11 #include <cmath>
12 
13 #ifndef LOG_SQRT_PI
14 #define LOG_SQRT_PI 0.5723649429247000870717135 /* log(sqrt(pi)) */
15 #endif
16 #ifndef I_SQRT_PI
17 #define I_SQRT_PI 0.5641895835477562869480795 /* 1 / sqrt(pi) */
18 #endif
19 
21 
28 class Chi2Helper {
29 public:
31 
38  static double poz(double z) {
39  double x;
40 
41  if (z == 0.0) {
42  x = 0.0;
43  } else {
44  double y = 0.5 * std::abs(z);
45  if (y >= 3.0) /* Maximum meaningful z value (6) divided by 2 */
46  {
47  x = 1.0;
48  } else if (y < 1.0) {
49  double w = y * y;
50  x = ((((((((0.000124818987 * w - 0.001075204047) * w +
51  0.005198775019) *
52  w -
53  0.019198292004) *
54  w +
55  0.059054035642) *
56  w -
57  0.151968751364) *
58  w +
59  0.319152932694) *
60  w -
61  0.531923007300) *
62  w +
63  0.797884560593) *
64  y * 2.0;
65  } else {
66  y -= 2.0;
67  x = (((((((((((((-0.000045255659 * y + 0.000152529290) * y -
68  0.000019538132) *
69  y -
70  0.000676904986) *
71  y +
72  0.001390604284) *
73  y -
74  0.000794620820) *
75  y -
76  0.002034254874) *
77  y +
78  0.006549791214) *
79  y -
80  0.010557625006) *
81  y +
82  0.011630447319) *
83  y -
84  0.009279453341) *
85  y +
86  0.005353579108) *
87  y -
88  0.002141268741) *
89  y +
90  0.000535310849) *
91  y +
92  0.999936657524;
93  }
94  }
95  return z > 0.0 ? ((x + 1.0) * 0.5) : ((1.0 - x) * 0.5);
96  }
97 
99  static inline double EXP_MAX_A_VALUE() { return 50.0; }
100 
102 
108  static double pochisq(double x, int df) {
109  if (x <= 0.0 || df < 1) return 1.0;
110 
111  double a = 0.5 * x;
112  bool even = !(df & 1); /* True if df is an even number */
113  double y = 0;
114  if (df > 1) {
115  y = std::exp(-a);
116  }
117  double s = (even ? y : (2.0 * poz(-std::sqrt(x))));
118  if (df > 2) {
119  x = 0.5 * (df - 1.0);
120  double z = (even ? 1.0 : 0.5);
121  if (a > EXP_MAX_A_VALUE()) {
122  double e = (even ? 0.0 : LOG_SQRT_PI);
123  double c = std::log(a);
124  while (z <= x) {
125  e = std::log(z) + e;
126  s += std::exp(c * z - a - e);
127  z += 1.0;
128  }
129  return s;
130  } else {
131  double e = (even ? 1.0 : (I_SQRT_PI / std::sqrt(a)));
132  double c = 0.0;
133  while (z <= x) {
134  e = e * (a / z);
135  c = c + e;
136  z += 1.0;
137  }
138  return c * y + s;
139  }
140  } else
141  return s;
142  }
143 
145 
148  static double critchi(double p, int df) {
149  double CHI_EPSILON = 0.000001; /* Accuracy of critchi approximation */
150  double CHI_MAX = 99999.0; /* Maximum chi-square value */
151  double minchisq = 0.0;
152  double maxchisq = CHI_MAX;
153  double chisqval;
154 
155  if (p <= 0.0)
156  return maxchisq;
157  else if (p >= 1.0)
158  return 0.0;
159 
160  chisqval = df / std::sqrt(p); /* fair first value */
161  while ((maxchisq - minchisq) > CHI_EPSILON) {
162  if (pochisq(chisqval, df) < p)
163  maxchisq = chisqval;
164  else
165  minchisq = chisqval;
166 
167  chisqval = (maxchisq + minchisq) * 0.5;
168  }
169 
170  return chisqval;
171  }
172 };
#define I_SQRT_PI
Definition: Chi2Helper.h:17
#define LOG_SQRT_PI
Definition: Chi2Helper.h:14
Package of methods to compute Chi2 related stuff.
Definition: Chi2Helper.h:28
static double pochisq(double x, int df)
Probability of chi-square value.
Definition: Chi2Helper.h:108
static double critchi(double p, int df)
Compute critical chi-square value toproduce given p.
Definition: Chi2Helper.h:148
static double poz(double z)
Probability of normal z value.
Definition: Chi2Helper.h:38
static double EXP_MAX_A_VALUE()
Value above which exp(EXP_MAX_A_VALUE) diverges.
Definition: Chi2Helper.h:99
__host__ __device__ int2 abs(int2 v)
Definition: cutil_math.h:1267