Tor 0.4.9.0-alpha-dev
prob_distr.h
Go to the documentation of this file.
1
2/**
3 * \file prob_distr.h
4 *
5 * \brief Header for prob_distr.c
6 **/
7
8#ifndef TOR_PROB_DISTR_H
9#define TOR_PROB_DISTR_H
10
12#include "lib/cc/torint.h"
14
15/**
16 * Container for distribution parameters for sampling, CDF, &c.
17 */
18struct dist_t {
19 const struct dist_ops_t *ops;
20};
21
22/**
23 * Untyped initializer element for struct dist_t using the specified
24 * struct dist_ops_t pointer. Don't actually use this directly -- use
25 * the type-specific macro built out of DIST_BASE_TYPED below -- but if
26 * you did use this directly, it would be something like:
27 *
28 * struct weibull mydist = {
29 * DIST_BASE(&weibull_ops),
30 * .lambda = ...,
31 * .k = ...,
32 * };
33 *
34 * Note there is NO COMPILER FEEDBACK if you accidentally do something
35 * like
36 *
37 * struct geometric mydist = {
38 * DIST_BASE(&weibull_ops),
39 * ...
40 * };
41 */
42#define DIST_BASE(OPS) { .ops = (OPS) }
43
44/** A compile-time type-checking macro for use with DIST_BASE_TYPED.
45 *
46 * This macro works by checking that &OBJ is a pointer type that is the same
47 * type (except for qualifiers) as (const TYPE *)&OBJ. It's a C constraint
48 * violation (which requires a diagnostic) if two pointers are different types
49 * and are subtracted. The sizeof() forces compile-time evaluation, and the
50 * multiplication by zero is to discard the result of the sizeof() from the
51 * expression.
52 *
53 * We define this conditionally to suppress false positives from
54 * Coverity, which gets confused by the sizeof business.
55 */
56#ifdef __COVERITY__
57#define TYPE_CHECK_OBJ(OPS, OBJ, TYPE) 0
58#else
59#define TYPE_CHECK_OBJ(OPS, OBJ, TYPE) \
60 (0*sizeof(&(OBJ) - (const TYPE *)&(OBJ)))
61#endif /* defined(__COVERITY__) */
62
63/**
64* Typed initializer element for struct dist_t using the specified struct
65* dist_ops_t pointer. Don't actually use this directly -- use a
66* type-specific macro built out of it -- but if you did use this
67* directly, it would be something like:
68*
69* struct weibull mydist = {
70* DIST_BASE_TYPED(&weibull_ops, mydist, struct weibull_t),
71* .lambda = ...,
72* .k = ...,
73* };
74*
75* If you want to define a distribution type, define a canonical set of
76* operations and define a type-specific initializer element like so:
77*
78* struct foo_t {
79* struct dist_t base;
80* int omega;
81* double tau;
82* double phi;
83* };
84*
85* struct dist_ops_t foo_ops = ...;
86*
87* #define FOO(OBJ) DIST_BASE_TYPED(&foo_ops, OBJ, struct foo_t)
88*
89* Then users can do:
90*
91* struct foo_t mydist = {
92* FOO(mydist),
93* .omega = ...,
94* .tau = ...,
95* .phi = ...,
96* };
97*
98* If you accidentally write
99*
100* struct bar_t mydist = {
101* FOO(mydist),
102* ...
103* };
104*
105* then the compiler will report a type mismatch in the sizeof
106* expression, which otherwise evaporates at runtime.
107*/
108#define DIST_BASE_TYPED(OPS, OBJ, TYPE) \
109 DIST_BASE((OPS) + TYPE_CHECK_OBJ(OPS,OBJ,TYPE))
110
111/**
112 * Generic operations on distributions. These simply defer to the
113 * corresponding dist_ops_t function. In the parlance of C++, these call
114 * virtual member functions.
115 */
116const char *dist_name(const struct dist_t *);
117double dist_sample(const struct dist_t *);
118double dist_cdf(const struct dist_t *, double x);
119double dist_sf(const struct dist_t *, double x);
120double dist_icdf(const struct dist_t *, double p);
121double dist_isf(const struct dist_t *, double p);
122
123/**
124 * Set of operations on a potentially parametric family of
125 * distributions. In the parlance of C++, this would be called a
126 * `vtable' and the members are virtual member functions.
127 */
129 const char *name;
130 double (*sample)(const struct dist_t *);
131 double (*cdf)(const struct dist_t *, double x);
132 double (*sf)(const struct dist_t *, double x);
133 double (*icdf)(const struct dist_t *, double p);
134 double (*isf)(const struct dist_t *, double p);
135};
136
137/* Geometric distribution on positive number of trials before first success */
138
140 struct dist_t base;
141 double p; /* success probability */
142};
143
144extern const struct dist_ops_t geometric_ops;
145
146#define GEOMETRIC(OBJ) \
147 DIST_BASE_TYPED(&geometric_ops, OBJ, struct geometric_t)
148
149/* Pareto distribution */
150
152 struct dist_t base;
153 double mu;
154 double sigma;
155 double xi;
156};
157
158extern const struct dist_ops_t genpareto_ops;
159
160#define GENPARETO(OBJ) \
161 DIST_BASE_TYPED(&genpareto_ops, OBJ, struct genpareto_t)
162
163/* Weibull distribution */
164
165struct weibull_t {
166 struct dist_t base;
167 double lambda;
168 double k;
169};
170
171extern const struct dist_ops_t weibull_ops;
172
173#define WEIBULL(OBJ) \
174 DIST_BASE_TYPED(&weibull_ops, OBJ, struct weibull_t)
175
176/* Log-logistic distribution */
177
179 struct dist_t base;
180 double alpha;
181 double beta;
182};
183
184extern const struct dist_ops_t log_logistic_ops;
185
186#define LOG_LOGISTIC(OBJ) \
187 DIST_BASE_TYPED(&log_logistic_ops, OBJ, struct log_logistic_t)
188
189/* Logistic distribution */
190
192 struct dist_t base;
193 double mu;
194 double sigma;
195};
196
197extern const struct dist_ops_t logistic_ops;
198
199#define LOGISTIC(OBJ) \
200 DIST_BASE_TYPED(&logistic_ops, OBJ, struct logistic_t)
201
202/* Uniform distribution */
203
204struct uniform_t {
205 struct dist_t base;
206 double a;
207 double b;
208};
209
210extern const struct dist_ops_t uniform_ops;
211
212#define UNIFORM(OBJ) \
213 DIST_BASE_TYPED(&uniform_ops, OBJ, struct uniform_t)
214
215/** Only by unittests */
216
217#ifdef PROB_DISTR_PRIVATE
218
219STATIC double logithalf(double p0);
220STATIC double logit(double p);
221
222STATIC double random_uniform_01(void);
223
224STATIC double logistic(double x);
225STATIC double cdf_logistic(double x, double mu, double sigma);
226STATIC double sf_logistic(double x, double mu, double sigma);
227STATIC double icdf_logistic(double p, double mu, double sigma);
228STATIC double isf_logistic(double p, double mu, double sigma);
229STATIC double sample_logistic(uint32_t s, double t, double p0);
230
231STATIC double cdf_log_logistic(double x, double alpha, double beta);
232STATIC double sf_log_logistic(double x, double alpha, double beta);
233STATIC double icdf_log_logistic(double p, double alpha, double beta);
234STATIC double isf_log_logistic(double p, double alpha, double beta);
235STATIC double sample_log_logistic(uint32_t s, double p0);
236
237STATIC double cdf_weibull(double x, double lambda, double k);
238STATIC double sf_weibull(double x, double lambda, double k);
239STATIC double icdf_weibull(double p, double lambda, double k);
240STATIC double isf_weibull(double p, double lambda, double k);
241STATIC double sample_weibull(uint32_t s, double p0, double lambda, double k);
242
243STATIC double sample_uniform_interval(double p0, double a, double b);
244
245STATIC double cdf_genpareto(double x, double mu, double sigma, double xi);
246STATIC double sf_genpareto(double x, double mu, double sigma, double xi);
247STATIC double icdf_genpareto(double p, double mu, double sigma, double xi);
248STATIC double isf_genpareto(double p, double mu, double sigma, double xi);
249STATIC double sample_genpareto(uint32_t s, double p0, double xi);
250
251#endif /* defined(PROB_DISTR_PRIVATE) */
252
253#endif /* !defined(TOR_PROB_DISTR_H) */
Utility macros to handle different features and behavior in different compilers.
STATIC double icdf_log_logistic(double p, double alpha, double beta)
Definition: prob_distr.c:675
STATIC double cdf_weibull(double x, double lambda, double k)
Definition: prob_distr.c:711
STATIC double sample_genpareto(uint32_t s, double p0, double xi)
Definition: prob_distr.c:1231
STATIC double random_uniform_01(void)
Definition: prob_distr.c:453
STATIC double cdf_log_logistic(double x, double alpha, double beta)
Definition: prob_distr.c:598
STATIC double sf_weibull(double x, double lambda, double k)
Definition: prob_distr.c:726
STATIC double cdf_logistic(double x, double mu, double sigma)
Definition: prob_distr.c:511
STATIC double sf_log_logistic(double x, double alpha, double beta)
Definition: prob_distr.c:659
STATIC double isf_weibull(double p, double lambda, double k)
Definition: prob_distr.c:752
STATIC double isf_logistic(double p, double mu, double sigma)
Definition: prob_distr.c:545
STATIC double sf_logistic(double x, double mu, double sigma)
Definition: prob_distr.c:523
STATIC double logithalf(double p0)
Definition: prob_distr.c:360
STATIC double isf_genpareto(double p, double mu, double sigma, double xi)
Definition: prob_distr.c:899
STATIC double icdf_weibull(double p, double lambda, double k)
Definition: prob_distr.c:739
STATIC double sample_logistic(uint32_t s, double t, double p0)
Definition: prob_distr.c:1094
STATIC double sample_weibull(uint32_t s, double p0, double lambda, double k)
Definition: prob_distr.c:1219
STATIC double logistic(double x)
Definition: prob_distr.c:193
STATIC double sample_log_logistic(uint32_t s, double p0)
Definition: prob_distr.c:1160
STATIC double icdf_logistic(double p, double mu, double sigma)
Definition: prob_distr.c:534
STATIC double cdf_genpareto(double x, double mu, double sigma, double xi)
Definition: prob_distr.c:792
STATIC double icdf_genpareto(double p, double mu, double sigma, double xi)
Definition: prob_distr.c:853
STATIC double logit(double p)
Definition: prob_distr.c:280
STATIC double sample_uniform_interval(double p0, double a, double b)
Definition: prob_distr.c:941
STATIC double isf_log_logistic(double p, double alpha, double beta)
Definition: prob_distr.c:686
STATIC double sf_genpareto(double x, double mu, double sigma, double xi)
Definition: prob_distr.c:836
double dist_cdf(const struct dist_t *, double x)
Definition: prob_distr.c:1345
double dist_sf(const struct dist_t *, double x)
Definition: prob_distr.c:1352
double dist_isf(const struct dist_t *, double p)
Definition: prob_distr.c:1366
double dist_icdf(const struct dist_t *, double p)
Definition: prob_distr.c:1359
const char * dist_name(const struct dist_t *)
Definition: prob_distr.c:1331
Macros to implement mocking and selective exposure for the test code.
#define STATIC
Definition: testsupport.h:32
Integer definitions used throughout Tor.