openGPMP
Open Source Mathematics Package
cdfs.cpp
Go to the documentation of this file.
1 /*************************************************************************
2  *
3  * Project
4  * _____ _____ __ __ _____
5  * / ____| __ \| \/ | __ \
6  * ___ _ __ ___ _ __ | | __| |__) | \ / | |__) |
7  * / _ \| '_ \ / _ \ '_ \| | |_ | ___/| |\/| | ___/
8  *| (_) | |_) | __/ | | | |__| | | | | | | |
9  * \___/| .__/ \___|_| |_|\_____|_| |_| |_|_|
10  * | |
11  * |_|
12  *
13  * Copyright (C) Akiel Aries, <akiel@akiel.org>, et al.
14  *
15  * This software is licensed as described in the file LICENSE, which
16  * you should have received as part of this distribution. The terms
17  * among other details are referenced in the official documentation
18  * seen here : https://akielaries.github.io/openGPMP/ along with
19  * important files seen in this project.
20  *
21  * You may opt to use, copy, modify, merge, publish, distribute
22  * and/or sell copies of the Software, and permit persons to whom
23  * the Software is furnished to do so, under the terms of the
24  * LICENSE file. As this is an Open Source effort, all implementations
25  * must be of the same methodology.
26  *
27  *
28  *
29  * This software is distributed on an AS IS basis, WITHOUT
30  * WARRANTY OF ANY KIND, either express or implied.
31  *
32  ************************************************************************/
33 #include <algorithm>
34 #include <cmath>
35 #include <limits>
36 #include <numeric>
37 #include <openGPMP/stats/cdfs.hpp>
38 #include <random>
39 #include <stdexcept>
40 #include <vector>
41 
42 // Bernoulli CDF
43 double gpmp::stats::CDF::bernoulli(double x, double p) {
44  if (x < 0)
45  return 0.0;
46  else if (x < 1)
47  return 1 - (1 - p);
48  else
49  return 1.0;
50 }
51 
52 // Beta CDF using the incomplete beta function
53 double gpmp::stats::CDF::beta(double x, double alpha, double beta) {
54  if (x <= 0)
55  return 0.0;
56  else if (x >= 1)
57  return 1.0;
58  else
59  return incomplete_beta(alpha, beta, x);
60 }
61 
62 // Binomial CDF
63 double gpmp::stats::CDF::binomial(int k, int n, double p) {
64  if (k < 0)
65  return 0.0;
66  else if (k >= n)
67  return 1.0;
68  else
69  return incomplete_beta(1.0 - p, n - k, k + 1);
70 }
71 
72 // Cauchy CDF
73 double gpmp::stats::CDF::cauchy(double x, double x0, double gamma) {
74  return 0.5 + atan((x - x0) / gamma) / M_PI;
75 }
76 
77 // Chi-squared CDF
78 double gpmp::stats::CDF::chi_squared(double x, double k) {
79  if (x < 0)
80  return 0.0;
81  else
82  return incomplete_gamma(k / 2.0, x / 2.0);
83 }
84 
85 // Exponential CDF
86 double gpmp::stats::CDF::exponential(double x, double lambda) {
87  if (x < 0)
88  return 0.0;
89  else
90  return 1.0 - exp(-lambda * x);
91 }
92 
93 // F CDF
94 double gpmp::stats::CDF::f(double x, double df1, double df2) {
95  if (x <= 0)
96  return 0.0;
97  else
98  return incomplete_beta(df1 / 2.0, df2 / 2.0, df1 / (df1 + df2 * x));
99 }
100 
101 // Gamma CDF
102 double gpmp::stats::CDF::gamma(double x, double shape, double scale) {
103  if (x < 0)
104  return 0.0;
105  else
106  return incomplete_gamma(shape, x / scale);
107 }
108 
109 // Inverse-Gamma CDF
110 double gpmp::stats::CDF::inverse_gamma(double x, double shape, double scale) {
111  if (x <= 0)
112  return 0.0;
113  else
114  return 1.0 - incomplete_gamma(shape, scale / x);
115 }
116 
117 // Inverse-Gaussian CDF
118 double gpmp::stats::CDF::inverse_gaussian(double x, double mu, double lambda) {
119  if (x <= 0)
120  return 0.0;
121  else
122  return normal_cdf(sqrt(lambda / x) * (x / mu - 1.0));
123 }
124 
125 // Laplace CDF
126 double gpmp::stats::CDF::laplace(double x, double mu, double b) {
127  if (x < mu)
128  return 0.5 * exp((x - mu) / b);
129  else
130  return 1.0 - 0.5 * exp(-(x - mu) / b);
131 }
132 
133 // Logistic CDF
134 double gpmp::stats::CDF::logistic(double x, double mu, double s) {
135  return 1.0 / (1.0 + exp(-(x - mu) / s));
136 }
137 
138 // Log-Normal CDF
139 double gpmp::stats::CDF::log_normal(double x, double mu, double sigma) {
140  if (x <= 0)
141  return 0.0;
142  else
143  return 0.5 + 0.5 * erf((log(x) - mu) / (sqrt(2.0) * sigma));
144 }
145 
146 // Normal (Gaussian) CDF
147 double gpmp::stats::CDF::gaussian(double x, double mu, double sigma) {
148  return 0.5 * (1 + erf((x - mu) / (sigma * sqrt(2))));
149 }
150 
151 // Poisson CDF
152 double gpmp::stats::CDF::poisson(int k, double lambda) {
153  if (k < 0)
154  return 0.0;
155  else
156  return incomplete_gamma(k + 1, lambda);
157 }
158 
159 // Rademacher CDF
161  if (x < 0)
162  return 0.0;
163  else if (x < 0.5)
164  return 0.0;
165  else
166  return 1.0;
167 }
168 
169 // Student's t CDF
170 double gpmp::stats::CDF::student_t(double x, double df) {
171  if (df <= 0)
172  return NAN;
173  return 0.5 + 0.5 * std::tgamma((df + 1) / 2) * std::hypot(1, x / sqrt(df)) /
174  (sqrt(df) * std::tgamma(df / 2));
175 }
176 
177 // Uniform CDF
178 double gpmp::stats::CDF::uniform(double x, double a, double b) {
179  if (x < a)
180  return 0.0;
181  else if (x < b)
182  return (x - a) / (b - a);
183  else
184  return 1.0;
185 }
186 
187 // Weibull CDF
188 double gpmp::stats::CDF::weibull(double x, double shape, double scale) {
189  if (x < 0)
190  return 0.0;
191  else
192  return 1.0 - exp(-pow(x / scale, shape));
193 }
194 
195 // Normal cumulative distribution function
197  return 0.5 * (1 + erf(x / sqrt(2.0)));
198 }
199 
200 // Incomplete beta function for beta and binomial CDF
201 double gpmp::stats::CDF::incomplete_beta(double a, double b, double x) {
202  const int maxIterations = 1000;
203  const double epsilon = 1e-12;
204  double result = 0.0;
205  double term = 1.0;
206  for (int k = 0; k < maxIterations; ++k) {
207  term *=
208  (k == 0 ? 1.0
209  : (a + k - 1) * (b - k) / (a + b + k - 1) * x / (k + 1));
210  result += term;
211  if (std::abs(term) < epsilon * std::abs(result))
212  break;
213  }
214  return result * std::pow(x, a) * std::pow(1 - x, b) / (a * std::beta(a, b));
215 }
216 
217 // Incomplete gamma function for chi-squared and gamma CDFs
218 double gpmp::stats::CDF::incomplete_gamma(double a, double x) {
219  const int maxIterations = 1000;
220  const double epsilon = 1e-12;
221  double result = 0.0;
222  double term = 1.0;
223  for (int k = 0; k < maxIterations; ++k) {
224  term *= x / (a + k);
225  result += term;
226  if (std::abs(term) < epsilon * std::abs(result))
227  break;
228  }
229  return exp(-x) * std::pow(x, a) * result / std::tgamma(a);
230 }
static double gaussian(double x, double mu, double sigma)
Compute the cumulative distribution function (CDF) of the normal (Gaussian) distribution.
Definition: cdfs.cpp:147
static double bernoulli(double x, double p)
Compute the cumulative distribution function (CDF) of the Bernoulli distribution.
Definition: cdfs.cpp:43
static double normal_cdf(double x)
Compute the cumulative distribution function (CDF) of the standard normal distribution.
Definition: cdfs.cpp:196
static double inverse_gamma(double x, double shape, double scale)
Compute the cumulative distribution function (CDF) of the inverse-gamma distribution.
Definition: cdfs.cpp:110
static double laplace(double x, double mu, double b)
Compute the cumulative distribution function (CDF) of the Laplace distribution.
Definition: cdfs.cpp:126
static double inverse_gaussian(double x, double mu, double lambda)
Compute the cumulative distribution function (CDF) of the inverse-Gaussian distribution.
Definition: cdfs.cpp:118
static double beta(double x, double alpha, double beta)
Compute the cumulative distribution function (CDF) of the beta distribution.
Definition: cdfs.cpp:53
static double exponential(double x, double lambda)
Compute the cumulative distribution function (CDF) of the exponential distribution.
Definition: cdfs.cpp:86
static double gamma(double x, double shape, double scale)
Compute the cumulative distribution function (CDF) of the gamma distribution.
Definition: cdfs.cpp:102
static double poisson(int k, double lambda)
Compute the cumulative distribution function (CDF) of the Poisson distribution.
Definition: cdfs.cpp:152
static double f(double x, double df1, double df2)
Compute the cumulative distribution function (CDF) of the F distribution.
Definition: cdfs.cpp:94
static double chi_squared(double x, double k)
Compute the cumulative distribution function (CDF) of the chi-squared distribution.
Definition: cdfs.cpp:78
static double rademacher(double x)
Compute the cumulative distribution function (CDF) of the Rademacher distribution.
Definition: cdfs.cpp:160
static double weibull(double x, double shape, double scale)
Compute the cumulative distribution function (CDF) of the Weibull distribution.
Definition: cdfs.cpp:188
static double binomial(int k, int n, double p)
Compute the cumulative distribution function (CDF) of the binomial distribution.
Definition: cdfs.cpp:63
static double student_t(double x, double df)
Compute the cumulative distribution function (CDF) of Student's t distribution.
Definition: cdfs.cpp:170
static double incomplete_gamma(double a, double x)
Compute the incomplete gamma function.
Definition: cdfs.cpp:218
static double incomplete_beta(double a, double b, double x)
Compute the incomplete beta function.
Definition: cdfs.cpp:201
static double logistic(double x, double mu, double s)
Compute the cumulative distribution function (CDF) of the logistic distribution.
Definition: cdfs.cpp:134
static double log_normal(double x, double mu, double sigma)
Compute the cumulative distribution function (CDF) of the log-normal distribution.
Definition: cdfs.cpp:139
static double cauchy(double x, double x0, double gamma)
Compute the cumulative distribution function (CDF) of the Cauchy distribution.
Definition: cdfs.cpp:73
static double uniform(double x, double a, double b)
Compute the cumulative distribution function (CDF) of the uniform distribution.
Definition: cdfs.cpp:178