Theoretica
A C++ numerical and automatic mathematical library
distributions.h
Go to the documentation of this file.
1 
5 
6 #ifndef THEORETICA_DISTRIBUTIONS
7 #define THEORETICA_DISTRIBUTIONS
8 
9 #include "../core/real_analysis.h"
10 #include "../algebra/vec.h"
11 #include "./statistics.h"
12 #include "../core/function.h"
13 #include "../core/special.h"
14 
15 
16 namespace theoretica {
17 
18 
19  namespace stats {
20 
27  inline real likelihood(const vec<real>& X, const vec<real>& theta, stat_function f) {
28 
29  real res = 1;
30 
31  for (unsigned int i = 0; i < X.size(); ++i)
32  res *= f(X[i], theta);
33 
34  return res;
35  }
36 
37 
44  inline real log_likelihood(const vec<real>& X, const vec<real>& theta, stat_function f) {
45 
46  real res = 0;
47 
48  for (unsigned int i = 0; i < X.size(); ++i)
49  res += ln(f(X[i], theta));
50 
51  return res;
52  }
53  }
54 
55 
57  namespace distribution {
58 
59 
61  inline real gaussian(real x, real X, real sigma) {
62 
63  return (1.0 / (sigma * SQRT2 * SQRTPI))
64  * exp(-square(x - X) / (2 * square(sigma)));
65  }
66 
67 
69  inline real gaussian(real x, const vec<real>& theta) {
70 
71  if(theta.size() != 2) {
72  TH_MATH_ERROR("distribution::gaussian", theta.size(), INVALID_ARGUMENT);
73  return nan();
74  }
75 
76  return gaussian(x, theta[0], theta[1]);
77  }
78 
79 
81  inline real bernoulli(unsigned int k, real p) {
82 
83  return pow(p, k) * pow(1 - p, 1 - k);
84  }
85 
86 
88  inline real bernoulli(real k, const vec<real>& theta) {
89 
90  if(theta.size() != 1) {
91  TH_MATH_ERROR("distribution::bernoulli", theta.size(), INVALID_ARGUMENT);
92  return nan();
93  }
94 
95  return bernoulli(static_cast<unsigned int>(k), theta[0]);
96 
97  }
98 
99 
101  inline real poisson(unsigned int k, real lambda) {
102 
103  return exp(-lambda) * pow(lambda, k) / (real) fact(k);
104  }
105 
106 
108  inline real poisson(real k, const vec<real>& theta) {
109 
110  if(theta.size() != 1) {
111  TH_MATH_ERROR("distribution::poisson", theta.size(), INVALID_ARGUMENT);
112  return nan();
113  }
114 
115  return poisson(static_cast<unsigned int>(k), theta[0]);
116  }
117 
118 
120  inline real binomial(unsigned int nu, unsigned int n, real p) {
121 
122  return binomial_coeff(n, nu) *
123  pow(p, nu) * pow(1 - p, n - nu);
124  }
125 
126 
128  inline real binomial(real nu, const vec<real>& theta) {
129 
130  if(theta.size() != 2) {
131  TH_MATH_ERROR("distribution::binomial", theta.size(), INVALID_ARGUMENT);
132  return nan();
133  }
134 
135  return binomial(static_cast<unsigned int>(nu),
136  static_cast<unsigned int>(theta[0]), theta[1]);
137  }
138 
139 
142  std::vector<unsigned int> x,
143  unsigned int n,
144  unsigned int k,
145  std::vector<real> p) {
146 
147  if(x.size() != p.size() || x.size() != k) {
148  TH_MATH_ERROR("distribution::multinomial", x.size(), INVALID_ARGUMENT);
149  return nan();
150  }
151 
152  real res = fact(n);
153 
154  for (unsigned int i = 0; i < k; ++i)
155  res *= pow(p[i], x[i]) / fact(x[i]);
156 
157  return res;
158  }
159 
160 
162  inline real chi_squared(real x, unsigned int k) {
163 
164  if(x < 0)
165  return 0;
166 
167  const real coeff = special::half_gamma(k);
168 
169  if(k % 2 == 0)
170  return pow(x, int(k / 2) - 1) * exp(-x / 2.0)
171  / (pow(SQRT2, k) * coeff);
172  else
173  return pow(sqrt(x), k - 2) * exp(-x / 2.0)
174  / (pow(SQRT2, k) * coeff);
175  }
176 
177 
179  inline real chi_squared(real x, const vec<real>& theta) {
180 
181  if(theta.size() != 1) {
182  TH_MATH_ERROR("distribution::chi_squared", theta.size(), INVALID_ARGUMENT);
183  return nan();
184  }
185 
186  return chi_squared(x, static_cast<unsigned int>(theta[0]));
187  }
188 
189 
192  inline real gamma(real x, real alpha, real beta) {
193 
194  return powf(beta, alpha) * powf(x, alpha - 1)
195  * exp(-beta * x) / special::gamma(alpha);
196  }
197 
198 
200  inline real gamma(real x, const vec<real>& theta) {
201 
202  if(theta.size() != 2) {
203  TH_MATH_ERROR("distribution::gamma", theta.size(), INVALID_ARGUMENT);
204  return nan();
205  }
206 
207  return gamma(x, theta[0], theta[1]);
208  }
209 
210 
213  inline real beta(real x, real alpha, real beta) {
214 
215  return powf(x, alpha - 1) * powf(1 - x, beta - 1)
216  / special::beta(alpha, beta);
217  }
218 
219 
221  inline real beta(real x, const vec<real>& theta) {
222 
223  if(theta.size() != 2) {
224  TH_MATH_ERROR("distribution::beta", theta.size(), INVALID_ARGUMENT);
225  return nan();
226  }
227 
228  return beta(x, theta[0], theta[1]);
229  }
230 
231 
233  inline real student(real x, unsigned int nu) {
234 
235  const real a = 1 + (x * x / nu);
236 
237  return (special::half_gamma(nu + 1) / special::half_gamma(nu))
238  * pow(sqrt(a), -nu - 1) / (sqrt(nu) * SQRTPI);
239  }
240 
241 
243  inline real student(real x, const vec<real>& theta) {
244 
245  if(theta.size() != 1) {
246  TH_MATH_ERROR("distribution::student", theta.size(), INVALID_ARGUMENT);
247  return nan();
248  }
249 
250  return student(x, static_cast<unsigned int>(theta[0]));
251  }
252 
253 
255  inline real log_normal(real x, real mu, real sigma) {
256 
257  return 1.0 / (2.50662827463 * sigma * x) *
258  exp(-square(ln(x) - mu) / (2 * square(sigma)));
259  }
260 
261 
263  inline real log_normal(real x, const vec<real>& theta) {
264 
265  if(theta.size() != 2) {
266  TH_MATH_ERROR("distribution::log_normal", theta.size(), INVALID_ARGUMENT);
267  return nan();
268  }
269 
270  return log_normal(x, theta[0], theta[1]);
271  }
272 
273 
275  inline real exponential(real x, real lambda) {
276 
277  if(x < 0)
278  return 0;
279 
280  return lambda * exp(-lambda * x);
281  }
282 
283 
285  inline real exponential(real x, const vec<real>& theta) {
286 
287  if(theta.size() != 1) {
288  TH_MATH_ERROR("distribution::exponential", theta.size(), INVALID_ARGUMENT);
289  return nan();
290  }
291 
292  return exponential(x, theta[0]);
293  }
294 
295 
297  inline real rayleigh(real x, real sigma) {
298 
299  if(x < 0)
300  return 0;
301 
302  if(sigma < MACH_EPSILON) {
303  TH_MATH_ERROR("distribution::rayleigh", sigma, DIV_BY_ZERO);
304  return nan();
305  }
306 
307  return x * exp(-square(x / sigma) / 2) / square(sigma);
308  }
309 
310 
312  inline real rayleigh(real x, const vec<real>& theta) {
313 
314  if(theta.size() != 1) {
315  TH_MATH_ERROR("distribution::rayleigh", theta.size(), INVALID_ARGUMENT);
316  return nan();
317  }
318 
319  return rayleigh(x, theta[0]);
320  }
321 
322 
324  inline real cauchy(real x, real mu, real alpha) {
325 
326  return 1.0 / (PI * alpha * (1 + (square(x - mu) / square(alpha))));
327  }
328 
329 
331  inline real cauchy(real x, const vec<real>& theta) {
332 
333  if(theta.size() != 2) {
334  TH_MATH_ERROR("distribution::cauchy", theta.size(), INVALID_ARGUMENT);
335  return nan();
336  }
337 
338  return cauchy(x, theta[0], theta[1]);
339  }
340 
341 
343  inline real breit_wigner(real x, real M, real Gamma) {
344 
345  return Gamma / (2 * PI * (square(x - M) + square(Gamma / 2.0)));
346  }
347 
348 
350  inline real breit_wigner(real x, const vec<real>& theta) {
351 
352  if(theta.size() != 2) {
353  TH_MATH_ERROR("distribution::breit_wigner", theta.size(), INVALID_ARGUMENT);
354  return nan();
355  }
356 
357  return breit_wigner(x, theta[0], theta[1]);
358  }
359 
360 
362  inline real maxwell(real x, real a) {
363 
364  return (SQRT2 / SQRTPI) * square(x) * exp(-square(x / a) / 2.0) / cube(a);
365  }
366 
367 
369  inline real maxwell(real x, const vec<real>& theta) {
370 
371  if(theta.size() != 1) {
372  TH_MATH_ERROR("distribution::maxwell", theta.size(), INVALID_ARGUMENT);
373  return nan();
374  }
375 
376  return maxwell(x, theta[0]);
377  }
378 
379 
381  inline real laplace(real x, real mu, real b) {
382 
383  return (1.0 / (2.0 * b)) * exp(-abs(x - mu) / b);
384  }
385 
386 
388  inline real laplace(real x, const vec<real>& theta) {
389 
390  if(theta.size() != 2) {
391  TH_MATH_ERROR("distribution::laplace", theta.size(), INVALID_ARGUMENT);
392  return nan();
393  }
394 
395  return (1.0 / (2.0 * theta[1])) * exp(-abs(x - theta[0]) / theta[1]);
396  }
397 
398 
400  inline real pareto(real x, real x_m, real alpha) {
401 
402  if(alpha <= 0) {
403  TH_MATH_ERROR("distribution::pareto", alpha, OUT_OF_DOMAIN);
404  return nan();
405  }
406 
407  if(x < x_m)
408  return 0;
409 
410  return alpha * powf(x_m, alpha) / powf(x, alpha + 1);
411  }
412 
413 
415  inline real pareto(real x, const vec<real>& theta) {
416 
417  if(theta.size() != 2) {
418  TH_MATH_ERROR("distribution::pareto", theta.size(), INVALID_ARGUMENT);
419  return nan();
420  }
421 
422  return pareto(x, theta[0], theta[1]);
423  }
424 
425 
427  inline real erlang(real x, unsigned int k, real lambda) {
428 
429  if(!k) {
430  TH_MATH_ERROR("distribution::erlang", k, INVALID_ARGUMENT);
431  return nan();
432  }
433 
434  return pow(lambda, k) * pow(x, k - 1)
435  * exp(-lambda * x) / fact(k - 1);
436  }
437 
438 
440  inline real erlang(real x, const vec<real>& theta) {
441 
442  if(theta.size() != 2) {
443  TH_MATH_ERROR("distribution::erlang", theta.size(), INVALID_ARGUMENT);
444  return nan();
445  }
446 
447  return erlang(x, static_cast<unsigned int>(theta[0]), theta[1]);
448  }
449 
450  }
451 }
452 
453 #endif
TH_CONSTEXPR unsigned int size() const
Returns the size of the vector (N)
Definition: vec.h:402
#define TH_MATH_ERROR(F_NAME, VALUE, EXCEPTION)
TH_MATH_ERROR is a macro which throws exceptions or modifies errno (depending on which compiling opti...
Definition: error.h:219
real maxwell(real x, real a)
Maxwell-Boltzmann distribution.
Definition: distributions.h:362
real binomial(unsigned int nu, unsigned int n, real p)
Binomial distribution function.
Definition: distributions.h:120
real exponential(real x, real lambda)
Exponential distribution.
Definition: distributions.h:275
real poisson(unsigned int k, real lambda)
Poisson distribution.
Definition: distributions.h:101
real pareto(real x, real x_m, real alpha)
Pareto distribution.
Definition: distributions.h:400
real bernoulli(unsigned int k, real p)
Bernoulli distribution.
Definition: distributions.h:81
real beta(real x, real alpha, real beta)
Beta distribution density function with parameters alpha (shape) and beta (shape)
Definition: distributions.h:213
real breit_wigner(real x, real M, real Gamma)
Breit Wigner distribution.
Definition: distributions.h:343
real chi_squared(real x, unsigned int k)
Chi-squared distribution.
Definition: distributions.h:162
real erlang(real x, unsigned int k, real lambda)
Erlang distribution.
Definition: distributions.h:427
real laplace(real x, real mu, real b)
Laplace distribution.
Definition: distributions.h:381
real student(real x, unsigned int nu)
Student's t distribution.
Definition: distributions.h:233
real log_normal(real x, real mu, real sigma)
Log-normal distribution.
Definition: distributions.h:255
real multinomial(std::vector< unsigned int > x, unsigned int n, unsigned int k, std::vector< real > p)
Multinomial distribution.
Definition: distributions.h:141
real gamma(real x, real alpha, real beta)
Gamma distribution density function with parameters alpha (shape) and beta (rate)
Definition: distributions.h:192
real cauchy(real x, real mu, real alpha)
Cauchy distribution.
Definition: distributions.h:324
real gaussian(real x, real X, real sigma)
Gaussian distribution function.
Definition: distributions.h:61
real rayleigh(real x, real sigma)
Rayleigh distribution.
Definition: distributions.h:297
real beta(real x1, real x2)
Beta special function of real argument.
Definition: special.h:141
real half_gamma(unsigned int k)
Half Gamma special function, defined as HG(n) = Gamma(n / 2) for any positive integer n.
Definition: special.h:41
real gamma(unsigned int k)
Gamma special function of positive integer argument.
Definition: special.h:23
real likelihood(const vec< real > &X, const vec< real > &theta, stat_function f)
Compute the likelihood of a distribution <f> with the given parameters <theta> and measures <X>
Definition: distributions.h:27
real log_likelihood(const vec< real > &X, const vec< real > &theta, stat_function f)
Compute the log likelihood of a distribution <f> with the given parameters <theta> and measures <X>
Definition: distributions.h:44
Main namespace of the library which contains all functions and objects.
Definition: algebra.h:27
double real
A real number, defined as a floating point type.
Definition: constants.h:188
TH_CONSTEXPR IntType binomial_coeff(unsigned int n, unsigned int m)
Compute the binomial coefficient.
Definition: real_analysis.h:1230
dual2 sqrt(dual2 x)
Compute the square root of a second order dual number.
Definition: dual2_functions.h:54
dual2 ln(dual2 x)
Compute the natural logarithm of a second order dual number.
Definition: dual2_functions.h:139
dual2 abs(dual2 x)
Compute the absolute value of a second order dual number.
Definition: dual2_functions.h:183
constexpr real SQRTPI
The square root of Pi.
Definition: constants.h:224
dual2 exp(dual2 x)
Compute the exponential of a second order dual number.
Definition: dual2_functions.h:130
real powf(real x, real a)
Approximate x elevated to a real exponent.
Definition: real_analysis.h:796
TH_CONSTEXPR IntType fact(unsigned int n)
Compute the factorial of n.
Definition: real_analysis.h:671
constexpr real MACH_EPSILON
Machine epsilon for the real type.
Definition: constants.h:197
std::function< real(real, const vec< real > &)> stat_function
Function pointer to a probability distribution function where the first argument is the variable and ...
Definition: function.h:30
constexpr real SQRT2
The square root of 2.
Definition: constants.h:251
dual2 square(dual2 x)
Return the square of a second order dual number.
Definition: dual2_functions.h:23
constexpr real PI
The Pi mathematical constant.
Definition: constants.h:206
real nan()
Return a quiet NaN number in floating point representation.
Definition: error.h:54
dual2 pow(dual2 x, int n)
Compute the n-th power of a second order dual number.
Definition: dual2_functions.h:41
dual2 cube(dual2 x)
Return the cube of a second order dual number.
Definition: dual2_functions.h:29
Statistical functions.