commit 607554f22b67531c8b0e75cf3611257b9bfbc18f
parent e94774ae3aa05fe84470cb092d256b18fd42e464
Author: NunoSempere <nuno.sempere@protonmail.com>
Date: Sun, 16 Jul 2023 14:38:12 +0200
add beta distribution samples!!
Diffstat:
2 files changed, 51 insertions(+), 17 deletions(-)
diff --git a/scratchpad/scratchpad b/scratchpad/scratchpad
Binary files differ.
diff --git a/scratchpad/scratchpad.c b/scratchpad/scratchpad.c
@@ -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;
}