Zephyr Scientific Library (zscilib)
probability.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2021 Marti Riba Pons
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <errno.h>
8 #include <stdio.h>
9 #include <stdbool.h>
10 #include <string.h>
11 #include <zsl/zsl.h>
12 #include <zsl/probability.h>
13 
15 {
16 #if CONFIG_ZSL_BOUNDS_CHECKS
17  /* Make sure b is bigger than a. */
18  if (*a >= *b) {
19  return -EINVAL;
20  }
21 #endif
22 
23  if (*x >= *a && *x <= *b) {
24  return 1. / (*b - *a);
25  } else {
26  return 0.0;
27  }
28 }
29 
31 {
32 #if CONFIG_ZSL_BOUNDS_CHECKS
33  /* Make sure b is bigger than a. */
34  if (*a >= *b) {
35  return -EINVAL;
36  }
37 #endif
38 
39  *m = 0.5 * (*a + *b);
40 
41  return 0;
42 }
43 
45 {
46 #if CONFIG_ZSL_BOUNDS_CHECKS
47  /* Make sure b is bigger than a. */
48  if (*a >= *b) {
49  return -EINVAL;
50  }
51 #endif
52 
53  *v = (*b - *a) * (*b - *a) / 12.0;
54 
55  return 0;
56 }
57 
59 {
60 #if CONFIG_ZSL_BOUNDS_CHECKS
61  /* Make sure b is bigger than a. */
62  if (*a >= *b) {
63  return -EINVAL;
64  }
65 #endif
66 
67  if (*x >= *a && *x <= *b) {
68  return (*x - *a) / (*b - *a);
69  } else if (*x < *a) {
70  return 0.0;
71  } else {
72  return 1.0;
73  }
74 }
75 
77 {
78  zsl_real_t y;
79 
80  y = (1. / (*s * ZSL_SQRT(2. * ZSL_PI))) *
81  ZSL_POW(ZSL_E, -0.5 * ((*x - *m) / *s) * ((*x - *m) / *s));
82 
83  return y;
84 }
85 
87 {
88  zsl_real_t y;
89 
90  y = 0.5 * (1 + ZSL_ERF((*x - *m) / (*s * ZSL_SQRT(2.))));
91 
92  return y;
93 }
94 
96 {
97  zsl_real_t p, r, t;
98 
99 #if CONFIG_ZSL_BOUNDS_CHECKS
100  /* Make sure x is between -1 and 1. */
101  if (*x <= -1.0 || *x >= 1.0) {
102  return -EINVAL;
103  }
104 #endif
105 
106  t = ZSL_FMA(*x, 0.0 - *x, 1.0);
107  t = ZSL_LOG(t);
108  if (ZSL_ABS(t) > 6.125) {
109  p = 3.03697567e-10; // 0x1.4deb44p-32
110  p = ZSL_FMA(p, t, 2.93243101e-8); // 0x1.f7c9aep-26
111  p = ZSL_FMA(p, t, 1.22150334e-6); // 0x1.47e512p-20
112  p = ZSL_FMA(p, t, 2.84108955e-5); // 0x1.dca7dep-16
113  p = ZSL_FMA(p, t, 3.93552968e-4); // 0x1.9cab92p-12
114  p = ZSL_FMA(p, t, 3.02698812e-3); // 0x1.8cc0dep-9
115  p = ZSL_FMA(p, t, 4.83185798e-3); // 0x1.3ca920p-8
116  p = ZSL_FMA(p, t, -2.64646143e-1); // -0x1.0eff66p-2
117  p = ZSL_FMA(p, t, 8.40016484e-1); // 0x1.ae16a4p-1
118  } else { // max ulp error = 2.35002
119  p = 5.43877832e-9; // 0x1.75c000p-28
120  p = ZSL_FMA(p, t, 1.43285448e-7); // 0x1.33b402p-23
121  p = ZSL_FMA(p, t, 1.22774793e-6); // 0x1.499232p-20
122  p = ZSL_FMA(p, t, 1.12963626e-7); // 0x1.e52cd2p-24
123  p = ZSL_FMA(p, t, -5.61530760e-5); // -0x1.d70bd0p-15
124  p = ZSL_FMA(p, t, -1.47697632e-4); // -0x1.35be90p-13
125  p = ZSL_FMA(p, t, 2.31468678e-3); // 0x1.2f6400p-9
126  p = ZSL_FMA(p, t, 1.15392581e-2); // 0x1.7a1e50p-7
127  p = ZSL_FMA(p, t, -2.32015476e-1); // -0x1.db2aeep-3
128  p = ZSL_FMA(p, t, 8.86226892e-1);
129  }
130  r = *x * p;
131  return r;
132 }
133 
135 {
136  zsl_real_t x, y;
137 
138 #if CONFIG_ZSL_BOUNDS_CHECKS
139  /* Make sure p is between 0 and 1. */
140  if (*p <= 0.0 || *p >= 1.0) {
141  return -EINVAL;
142  }
143 #endif
144 
145  x = 2.0 * *p - 1.0;
146  y = *m + *s * ZSL_SQRT(2.0) * zsl_prob_erf_inv(&x);
147 
148  return y;
149 }
150 
152 {
153  if (*n == 0 || *n == 1) {
154  return 1;
155  } else if (*n < 0) {
156  return -EINVAL;
157  }
158 
159  int n2 = *n;
160 
161  for (int i = 1; i < *n; i++) {
162  n2 *= (*n - i);
163  }
164 
165  return n2;
166 }
167 
168 int zsl_prob_binomial_coef(int *n, int *k, int *c)
169 {
170 #if CONFIG_ZSL_BOUNDS_CHECKS
171  /* Make sure n is positive or zero. */
172  if (*n < 0) {
173  return -EINVAL;
174  }
175 #endif
176 
177  if (*k > *n || *k < 0) {
178  *c = 0;
179  return 0;
180  }
181 
182  int kn = *n - *k;
183  *c = zsl_prob_factorial(n) /
185 
186  return 0;
187 }
188 
190 {
191 #if CONFIG_ZSL_BOUNDS_CHECKS
192  /* Make sure p is between 0 and 1. */
193  if (*p > 1.0 || *p < 0.0) {
194  return -EINVAL;
195  }
196  /* Make sure n is positive or zero. */
197  if (*n < 0) {
198  return -EINVAL;
199  }
200 #endif
201 
202  int c;
203  zsl_prob_binomial_coef(n, x, &c);
204 
205  return c * ZSL_POW(*p, *x) * ZSL_POW((1. - *p), (*n - *x));
206 }
207 
209 {
210 #if CONFIG_ZSL_BOUNDS_CHECKS
211  /* Make sure p is between 0 and 1. */
212  if (*p > 1.0 || *p < 0.0) {
213  return -EINVAL;
214  }
215  /* Make sure n is positive or zero. */
216  if (*n < 0) {
217  return -EINVAL;
218  }
219 #endif
220 
221  *m = *n * *p;
222 
223  return 0;
224 }
225 
227 {
228 #if CONFIG_ZSL_BOUNDS_CHECKS
229  /* Make sure p is between 0 and 1. */
230  if (*p > 1.0 || *p < 0.0) {
231  return -EINVAL;
232  }
233  /* Make sure n is positive or zero. */
234  if (*n < 0) {
235  return -EINVAL;
236  }
237 #endif
238 
239  *v = *n * *p * (1. - *p);
240 
241  return 0;
242 }
243 
245 {
246 #if CONFIG_ZSL_BOUNDS_CHECKS
247  /* Make sure p is between 0 and 1. */
248  if (*p > 1.0 || *p < 0.0) {
249  return -EINVAL;
250  }
251  /* Make sure n is positive or zero. */
252  if (*n < 0) {
253  return -EINVAL;
254  }
255 #endif
256  if (*x < 0) {
257  return 0;
258  }
259 
260  zsl_real_t y = 0.0;
261  int c;
262 
263  for (int i = 0; i <= *x; i++) {
264  zsl_prob_binomial_coef(n, &i, &c);
265  y += c * ZSL_POW(*p, i) * ZSL_POW((1. - *p), (*n - i));
266  }
267 
268 
269  return y;
270 }
271 
272 
273 
275 {
276 #if CONFIG_ZSL_BOUNDS_CHECKS
277  /* Make sure the sum of all coefficients in v is 1 and that each
278  * probability is greater or equal than 0. */
279  zsl_real_t sum = -1.0;
280  for (size_t i = 0; i < v->sz; i++) {
281  if (v->data[i] < 0.0) {
282  return -EINVAL;
283  }
284  sum += v->data[i];
285  }
286  if (ZSL_ABS(sum) > 1E-6) {
287  return -EINVAL;
288  }
289 #endif
290 
291  *h = 0.0;
292  for (size_t i = 0; i < v->sz; i++) {
293  *h -= v->data[i] * ZSL_LOG(v->data[i]);
294  }
295 
296  *h /= ZSL_LOG(2.);
297 
298  return 0;
299 }
300 
302  zsl_real_t *pab)
303 {
304 
305 #if CONFIG_ZSL_BOUNDS_CHECKS
306  /* Make sure every probability is between 0 and 1, and pb is not zero. */
307  if (*pa < 0.0 || *pa > 1.0) {
308  return -EINVAL;
309  }
310  if (*pb <= 0.0 || *pb > 1.0 || *pb < *pa * *pba) {
311  return -EINVAL;
312  }
313  if (*pba < 0.0 || *pba > 1.0) {
314  return -EINVAL;
315  }
316 #endif
317 
318  *pab = (*pba * *pa) / *pb;
319 
320  return 0;
321 }
zsl_prob_uni_var
int zsl_prob_uni_var(zsl_real_t *a, zsl_real_t *b, zsl_real_t *v)
Computes the variance of a uniform probability distribution function of interval (a,...
Definition: probability.c:44
probability.h
API header file for probability in zscilib.
zsl_vec::data
zsl_real_t * data
Definition: vectors.h:44
ZSL_POW
#define ZSL_POW
Definition: zsl.h:87
ZSL_E
#define ZSL_E
Definition: consts.h:62
ZSL_FMA
#define ZSL_FMA
Definition: zsl.h:103
zsl_vec::sz
size_t sz
Definition: vectors.h:42
zsl_prob_uni_cdf
zsl_real_t zsl_prob_uni_cdf(zsl_real_t *a, zsl_real_t *b, zsl_real_t *x)
Computes the image of a value x of the uniform cumulative distribution function (CDF) with interval (...
Definition: probability.c:58
ZSL_LOG
#define ZSL_LOG
Definition: zsl.h:89
zsl_prob_binomial_mean
int zsl_prob_binomial_mean(int *n, zsl_real_t *p, zsl_real_t *m)
Computes the mean of a binomial probability distribution function.
Definition: probability.c:208
zsl_prob_binomial_pdf
zsl_real_t zsl_prob_binomial_pdf(int *n, zsl_real_t *p, int *x)
Computes the image of a value x of the binomial probability distribution function (PDF).
Definition: probability.c:189
zsl_prob_normal_cdf
zsl_real_t zsl_prob_normal_cdf(zsl_real_t *m, zsl_real_t *s, zsl_real_t *x)
Computes the image of a value x of the normal cumulative distribution function (CDF) of mean 'm' and ...
Definition: probability.c:86
ZSL_ERF
#define ZSL_ERF
Definition: zsl.h:102
ZSL_ABS
#define ZSL_ABS
Definition: zsl.h:84
zsl_prob_bayes
int zsl_prob_bayes(zsl_real_t *pa, zsl_real_t *pb, zsl_real_t *pba, zsl_real_t *pab)
Computes the probability of an event A to occur given the event B, based on the probability of A,...
Definition: probability.c:301
zsl_prob_uni_mean
int zsl_prob_uni_mean(zsl_real_t *a, zsl_real_t *b, zsl_real_t *m)
Computes the mean of a uniform probability distribution function of interval (a, b).
Definition: probability.c:30
zsl_prob_binomial_coef
int zsl_prob_binomial_coef(int *n, int *k, int *c)
Computes binomial coefficient of n and k (commonly writen as 'n over k').
Definition: probability.c:168
zsl_prob_normal_cdf_inv
zsl_real_t zsl_prob_normal_cdf_inv(zsl_real_t *m, zsl_real_t *s, zsl_real_t *p)
Computes the inverse of the normal cumulative distribution function of a value x.
Definition: probability.c:134
zsl.h
API header file for zscilib.
ZSL_PI
#define ZSL_PI
Definition: consts.h:45
zsl_vec
Represents a vector.
Definition: vectors.h:40
zsl_prob_normal_pdf
zsl_real_t zsl_prob_normal_pdf(zsl_real_t *m, zsl_real_t *s, zsl_real_t *x)
Computes the image of a value x of the normal probability distribution function (PDF) of mean 'm' and...
Definition: probability.c:76
zsl_prob_factorial
int zsl_prob_factorial(int *n)
Computes the factorial of a natural number, i. e., the finite product n * (n - 1) * (n - 2) * (n - 3)...
Definition: probability.c:151
zsl_prob_entropy
int zsl_prob_entropy(struct zsl_vec *v, zsl_real_t *h)
Computes the Shannon entropy of a set of events with given probabilities.
Definition: probability.c:274
zsl_real_t
double zsl_real_t
Definition: zsl.h:51
zsl_prob_uni_pdf
zsl_real_t zsl_prob_uni_pdf(zsl_real_t *a, zsl_real_t *b, zsl_real_t *x)
Computes the image of a value x of the uniform probability distribution function (PDF),...
Definition: probability.c:14
zsl_prob_binomial_var
int zsl_prob_binomial_var(int *n, zsl_real_t *p, zsl_real_t *v)
Computes the variance of a binomial probability distribution function.
Definition: probability.c:226
zsl_prob_erf_inv
zsl_real_t zsl_prob_erf_inv(zsl_real_t *x)
Computes the value of the inverse error fuction of a value 'x' using the Chebyshev interpolation to e...
Definition: probability.c:95
ZSL_SQRT
#define ZSL_SQRT
Definition: zsl.h:91
zsl_prob_binomial_cdf
zsl_real_t zsl_prob_binomial_cdf(int *n, zsl_real_t *p, int *x)
Computes the image of a value x of the ubinomial cumulative distribution function (CDF).
Definition: probability.c:244