/** * \file prob_distr.h * * \brief Header for prob_distr.c **/ #ifndef TOR_PROB_DISTR_H #define TOR_PROB_DISTR_H #include "lib/cc/compat_compiler.h" #include "lib/cc/torint.h" #include "lib/testsupport/testsupport.h" /** * Container for distribution parameters for sampling, CDF, &c. */ struct dist { const struct dist_ops *ops; }; #define DIST_BASE(OPS) { .ops = (OPS) } #define DIST_BASE_TYPED(OPS, OBJ, TYPE) \ DIST_BASE((OPS) + 0*sizeof(&(OBJ) - (const TYPE *)&(OBJ))) const char *dist_name(const struct dist *); double dist_sample(const struct dist *); double dist_cdf(const struct dist *, double x); double dist_sf(const struct dist *, double x); double dist_icdf(const struct dist *, double p); double dist_isf(const struct dist *, double p); struct dist_ops { const char *name; double (*sample)(const struct dist *); double (*cdf)(const struct dist *, double x); double (*sf)(const struct dist *, double x); double (*icdf)(const struct dist *, double p); double (*isf)(const struct dist *, double p); }; /* Geometric distribution on positive number of trials before first success */ struct geometric { struct dist base; double p; /* success probability */ }; extern const struct dist_ops geometric_ops; #define GEOMETRIC(OBJ) \ DIST_BASE_TYPED(&geometric_ops, OBJ, struct geometric) /* Pareto distribution */ struct genpareto { struct dist base; double mu; double sigma; double xi; }; extern const struct dist_ops genpareto_ops; #define GENPARETO(OBJ) \ DIST_BASE_TYPED(&genpareto_ops, OBJ, struct genpareto) /* Weibull distribution */ struct weibull { struct dist base; double lambda; double k; }; extern const struct dist_ops weibull_ops; #define WEIBULL(OBJ) \ DIST_BASE_TYPED(&weibull_ops, OBJ, struct weibull) /* Log-logistic distribution */ struct log_logistic { struct dist base; double alpha; double beta; }; extern const struct dist_ops log_logistic_ops; #define LOG_LOGISTIC(OBJ) \ DIST_BASE_TYPED(&log_logistic_ops, OBJ, struct log_logistic) /* Logistic distribution */ struct logistic { struct dist base; double mu; double sigma; }; extern const struct dist_ops logistic_ops; #define LOGISTIC(OBJ) \ DIST_BASE_TYPED(&logistic_ops, OBJ, struct logistic) /* Uniform distribution */ struct uniform { struct dist base; double a; double b; }; extern const struct dist_ops uniform_ops; #define UNIFORM(OBJ) \ DIST_BASE_TYPED(&uniform_ops, OBJ, struct uniform) /** Only by unittests */ #ifdef PROB_DISTR_PRIVATE STATIC double logithalf(double p0); STATIC double logit(double p); STATIC double random_uniform_01(void); STATIC double logistic(double x); STATIC double cdf_logistic(double x, double mu, double sigma); STATIC double sf_logistic(double x, double mu, double sigma); STATIC double icdf_logistic(double p, double mu, double sigma); STATIC double isf_logistic(double p, double mu, double sigma); STATIC double sample_logistic(uint32_t s, double t, double p0); STATIC double cdf_log_logistic(double x, double alpha, double beta); STATIC double sf_log_logistic(double x, double alpha, double beta); STATIC double icdf_log_logistic(double p, double alpha, double beta); STATIC double isf_log_logistic(double p, double alpha, double beta); STATIC double sample_log_logistic(uint32_t s, double p0); STATIC double cdf_weibull(double x, double lambda, double k); STATIC double sf_weibull(double x, double lambda, double k); STATIC double icdf_weibull(double p, double lambda, double k); STATIC double isf_weibull(double p, double lambda, double k); STATIC double sample_weibull(uint32_t s, double p0, double lambda, double k); STATIC double sample_uniform_interval(double p0, double a, double b); STATIC double cdf_genpareto(double x, double mu, double sigma, double xi); STATIC double sf_genpareto(double x, double mu, double sigma, double xi); STATIC double icdf_genpareto(double p, double mu, double sigma, double xi); STATIC double isf_genpareto(double p, double mu, double sigma, double xi); STATIC double sample_genpareto(uint32_t s, double p0, double xi); #endif #endif