forked from personal/squiggle.c
add beta distribution samples!!
This commit is contained in:
parent
e94774ae3a
commit
607554f22b
Binary file not shown.
|
@ -211,11 +211,11 @@ struct box incbeta(float a, float b, float x) {
|
|||
|
||||
if (x < 0.0 || x > 1.0){
|
||||
if(EXIT_ON_ERROR){
|
||||
printf("x out of bounds, in function incbeta, in %s (%d)", __FILE__, __LINE__);
|
||||
printf("x = %f, x out of bounds [0, 1], in function incbeta, in %s (%d)", __FILE__, __LINE__);
|
||||
exit(1);
|
||||
}else{
|
||||
char error_msg[200];
|
||||
snprintf(error_msg, 200, "x out of bounds, in function incbeta, in %s (%d)", __FILE__, __LINE__);
|
||||
snprintf(error_msg, 200, "x = %f, x out of bounds [0, 1], in function incbeta, in %s (%d)", x, __FILE__, __LINE__);
|
||||
result.empty = 1;
|
||||
result.error_msg = error_msg;
|
||||
return result;
|
||||
|
@ -286,8 +286,16 @@ struct box incbeta(float a, float b, float x) {
|
|||
}
|
||||
|
||||
struct box cdf_beta(float x){
|
||||
float successes = 1, failures = (2023-1945);
|
||||
return incbeta(successes, failures, x);
|
||||
if(x < 0){
|
||||
struct box result = { .empty = 0, .content = 0};
|
||||
return result;
|
||||
} else if(x > 1){
|
||||
struct box result = { .empty = 0, .content = 1};
|
||||
return result;
|
||||
} else {
|
||||
float successes = 1, failures = (2023-1945);
|
||||
return incbeta(successes, failures, x);
|
||||
}
|
||||
}
|
||||
|
||||
float cdf_dangerous_beta(float x){
|
||||
|
@ -295,20 +303,32 @@ float cdf_dangerous_beta(float x){
|
|||
// But it will propagate through the code
|
||||
// So it doesn't feel like a great architectural choice;
|
||||
// I prefer my choice of setting a variable which will determine whether to exit on failure or not.
|
||||
float successes = 1, failures = (2023-1945);
|
||||
struct box result = incbeta(successes, failures, x);
|
||||
if(result.empty){
|
||||
printf("%s", result.error_msg);
|
||||
exit(1);
|
||||
}else{
|
||||
return result.content;
|
||||
// Ok, so the proper thing to do would be to refactor inverse_cdf
|
||||
// but, I could also use a GOTO? <https://stackoverflow.com/questions/245742/examples-of-good-gotos-in-c-or-c>
|
||||
// Ok, alternatives are:
|
||||
// - Refactor inverse_cdf to take a box, take the small complexity + penalty. Add a helper
|
||||
// - Duplicate the code, have a refactored inverse_cdf as well as a normal cdf
|
||||
// - Do something hacky
|
||||
// a. dangerous beta, which exits
|
||||
// b. clever & hacky go-to statements
|
||||
// i. They actually look fun to implement
|
||||
// ii. But they would be hard for others to use.
|
||||
if(x < 0){
|
||||
return 0;
|
||||
} else if(x > 1){
|
||||
return 1;
|
||||
} else {
|
||||
float successes = 100, failures = 100;
|
||||
struct box result = incbeta(successes, failures, x);
|
||||
if(result.empty){
|
||||
printf("%s\n", result.error_msg);
|
||||
exit(1);
|
||||
return 1;
|
||||
}else{
|
||||
return result.content;
|
||||
}
|
||||
}
|
||||
}
|
||||
struct box dangerous_beta_sampler(uint32_t* seed)
|
||||
// Think through what to do to feed the incbeta box into
|
||||
{
|
||||
return sampler(cdf_dangerous_beta, seed);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
|
@ -373,6 +393,20 @@ int main()
|
|||
clock_t end_2 = clock();
|
||||
float time_spent_2 = (float)(end_2 - begin_2) / CLOCKS_PER_SEC;
|
||||
printf("Time spent: %f", time_spent_2);
|
||||
|
||||
|
||||
// Get some beta samples
|
||||
clock_t begin_3 = clock();
|
||||
printf("\n\nGetting some samples from box sampler_dangerous_beta\n");
|
||||
for (int i = 0; i < n; i++) {
|
||||
struct box sample = sampler(cdf_dangerous_beta, seed);
|
||||
if (sample.empty) {
|
||||
printf("Error in sampler function");
|
||||
} else {
|
||||
printf("%f\n", sample.content);
|
||||
}
|
||||
}
|
||||
clock_t end_3 = clock();
|
||||
float time_spent_3 = (float)(end_3 - begin_3) / CLOCKS_PER_SEC;
|
||||
printf("Time spent: %f", time_spent_3);
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user