add gamma distribution & documentation.

This commit is contained in:
NunoSempere 2023-07-22 21:40:35 +02:00
parent baa8a532a2
commit fee06aec65
5 changed files with 49 additions and 3 deletions

View File

@ -10,8 +10,10 @@ A self-contained C99 library that provides a subset of [Squiggle](https://www.sq
- Because it will last long - Because it will last long
- Because it can fit in my head - Because it can fit in my head
- Because if you can implement something in C, you can implement it anywhere else - Because if you can implement something in C, you can implement it anywhere else
- Because it can be made faster if need be, e.g., with a multi-threading library like OpenMP, or by adding more algorithmic complexity - Because it can be made faster if need be
- **Because there are few abstractions between it and the bare metal: C -> assembly = CPU instructions**, leading to fewer errors beyond the programmer's control. - e.g., with a multi-threading library like OpenMP, or by adding more algorithmic complexity
- or more simply, by inlining the sampling functions (adding an `inline` directive before their function declaration)
- **Because there are few abstractions between it and machine code** (C => assembly => machine code with gcc, or C => machine code, with tcc), leading to fewer errors beyond the programmer's control.
## Getting started ## Getting started
@ -79,8 +81,13 @@ Behaviour on error can be toggled by the `EXIT_ON_ERROR` variable. This library
- [ ] Have some more complicated & realistic example - [ ] Have some more complicated & realistic example
- [ ] Add summarization functions: 90% ci (or all c.i.?) - [ ] Add summarization functions: 90% ci (or all c.i.?)
- [ ] Systematize references
- [ ] Publish online - [ ] Publish online
- [ ] Add efficient sampling from a beta distribution - [ ] Add efficient sampling from a beta distribution
- https://dl.acm.org/doi/10.1145/358407.358414
- https://link.springer.com/article/10.1007/bf02293108
- https://stats.stackexchange.com/questions/502146/how-does-numpy-generate-samples-from-a-beta-distribution
- https://github.com/numpy/numpy/blob/5cae51e794d69dd553104099305e9f92db237c53/numpy/random/src/distributions/distributions.c
- [ ] Support all distribution functions in <https://www.squiggle-language.com/docs/Api/Dist> - [ ] Support all distribution functions in <https://www.squiggle-language.com/docs/Api/Dist>
- [ ] Support all distribution functions in <https://www.squiggle-language.com/docs/Api/Dist>, and do so efficiently - [ ] Support all distribution functions in <https://www.squiggle-language.com/docs/Api/Dist>, and do so efficiently
@ -107,3 +114,5 @@ Behaviour on error can be toggled by the `EXIT_ON_ERROR` variable. This library
- [x] Explain individual examples - [x] Explain individual examples
- [x] Rename functions to something more self-explanatory, e.g,. `sample_unit_normal`. - [x] Rename functions to something more self-explanatory, e.g,. `sample_unit_normal`.
- [x] Add summarization functions: mean, std - [x] Add summarization functions: mean, std
- [x] Add sampling from a gamma distribution
- https://dl.acm.org/doi/pdf/10.1145/358407.358414

View File

@ -18,12 +18,13 @@ DEPENDENCIES=$(MATH)
# OPENMP=-fopenmp # OPENMP=-fopenmp
## Flags ## Flags
VERBOSE=#-v
DEBUG= #'-g' DEBUG= #'-g'
STANDARD=-std=c99 ## gnu99 allows for nested functions. STANDARD=-std=c99 ## gnu99 allows for nested functions.
EXTENSIONS= #-fnested-functions EXTENSIONS= #-fnested-functions
WARNINGS=-Wall WARNINGS=-Wall
OPTIMIZED=-O3#-Ofast OPTIMIZED=-O3#-Ofast
CFLAGS=$(DEBUG) $(STANDARD) $(EXTENSIONS) $(WARNINGS) $(OPTIMIZED) CFLAGS=$(VERBOSE) $(DEBUG) $(STANDARD) $(EXTENSIONS) $(WARNINGS) $(OPTIMIZED)
## Formatter ## Formatter
STYLE_BLUEPRINT=webkit STYLE_BLUEPRINT=webkit

Binary file not shown.

View File

@ -73,6 +73,42 @@ float sample_to(float low, float high, uint32_t* seed)
return sample_lognormal(logmean, logsigma, seed); return sample_lognormal(logmean, logsigma, seed);
} }
float sample_gamma(float alpha, uint32_t* seed){
// A Simple Method for Generating Gamma Variables, Marsaglia and Wan Tsang, 2001
// https://dl.acm.org/doi/pdf/10.1145/358407.358414
// see also the references/ folder
if(alpha >=1){
float d, c, x, v, u;
d = alpha - 1.0/3.0;
c = 1.0/sqrt(9.0 * d);
while(1){
do {
x = sample_unit_normal(seed);
v = 1.0 + c * x;
} while(v <= 0.0);
v = pow(v, 3);
u = sample_unit_uniform(seed);
if( u < 1.0 - 0.0331 * pow(x, 4)){ // Condition 1
// the 0.0331 doesn't inspire much confidence
// however, this isn't the whole story
// by knowing that Condition 1 implies condition 2
// we realize that this is just a way of making the algorithm faster
// i.e., of not using the logarithms
return d*v;
}
if(log(u) < 0.5*pow(x,2) + d*(1.0 - v + log(v))){ // Condition 2
return d*v;
}
}
}else{
return sample_gamma(1 + alpha, seed) * pow(sample_unit_uniform(seed), 1/alpha);
// see note in p. 371 of https://dl.acm.org/doi/pdf/10.1145/358407.358414
}
}
// Array helpers // Array helpers
float array_sum(float* array, int length) float array_sum(float* array, int length)
{ {