ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
ErrorFunction.cpp
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 #include "ErrorFunction.h"
9 
10 // local
11 #include "CVConst.h"
12 
13 using namespace cloudViewer;
14 
15 /**************************
16  * erf.cpp
17  * author: Steve Strand
18  * written: 29-Jan-04
19  * modified: Jan-06 (DGM)
20  ***************************/
21 
22 double ErrorFunction::erf(double x)
23 // erf(x) = 2/sqrt(pi)*integral(exp(-t^2),t,0,x)
24 // = 2/sqrt(pi)*[x - x^3/3 + x^5/5*2! - x^7/7*3! + ...]
25 // = 1-erfc(x)
26 {
27  static const double two_sqrtpi = 1.128379167095512574; // 2/sqrt(pi)
28 
29  if (std::abs(x) > 2.2)
30  return 1.0 - erfc(x); // use continued fraction when std::abs(x) > 2.2
31 
32  double sum = x, term = x, xsqr = x * x;
33  int j = 1;
34 
35  do {
36  term *= xsqr / j;
37  sum -= term / (2 * j + 1);
38  ++j;
39  term *= xsqr / j;
40  sum += term / (2 * j + 1);
41  ++j;
42  } while (std::abs(term / sum) > c_erfRelativeError);
43 
44  return two_sqrtpi * sum;
45 }
46 
47 static const double one_sqrtpi = 1.0 / sqrt(M_PI);
48 
49 double ErrorFunction::erfc(double x)
50 // erfc(x) = 2/sqrt(pi)*integral(exp(-t^2),t,x,inf)
51 // = exp(-x^2)/sqrt(pi) * [1/x+ (1/2)/x+ (2/2)/x+ (3/2)/x+ (4/2)/x+ ...]
52 // = 1-erf(x)
53 // expression inside [] is a continued fraction so '+' means add to denominator
54 // only
55 {
56  if (std::abs(x) < 2.2) return erfc(x); // use series when std::abs(x) < 2.2
57 
58  if (x < 1.0e-12) // continued fraction only valid for x>0
59  return 2.0 - erfc(-x);
60 
61  double a = 1, b = x; // last two convergent numerators
62  double c = x, d = x * x + 0.5; // last two convergent denominators
63  double q1, q2 = b / d; // last two convergents (a/c and b/d)
64  double n = 1.0;
65 
66  do {
67  double t = a * n + b * x;
68  a = b;
69  b = t;
70  t = c * n + d * x;
71  c = d;
72  d = t;
73  n += 0.5;
74  q1 = q2;
75  q2 = b / d;
76  } while (std::abs(q1 - q2) / q2 > c_erfRelativeError);
77 
78  return one_sqrtpi * exp(-x * x) * q2;
79 }
constexpr double M_PI
Pi.
Definition: CVConst.h:19
static double erf(double x)
Computes erf(x)
static double erfc(double x)
Computes erfc(x)
static const double one_sqrtpi
__host__ __device__ int2 abs(int2 v)
Definition: cutil_math.h:1267
Generic file read and write utility for python interface.
static const double c_erfRelativeError
Relative error for Error Function computation.
Definition: ErrorFunction.h:21