commit 6247fbfb7bcc3d396f7a29a96b8d6e90ed057849
parent 11e965be4fd5a8e45605fbdbc4213d58d8da936c
Author: NunoSempere <nuno.sempere@protonmail.com>
Date: Sun, 16 Jul 2023 22:58:20 +0200
simplify PROCESS_ERROR macro
Diffstat:
6 files changed, 39 insertions(+), 39 deletions(-)
diff --git a/README.md b/README.md
@@ -12,7 +12,7 @@ A self-contained C99 library that provides a subset of [Squiggle](https://www.sq
- 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
-## The core scheme
+## The core strategy
Have some basic building blocks, like , and return samplers. Use previous samplers to . Then use the final sampler to produce an array of samples.
@@ -26,6 +26,13 @@ You can follow some example usage in the examples/ folder
4. In the fourth example, we define some simple cdfs, and we draw samples from those cdfs. We see that this approach is slower than using the built-in samplers, e.g., the normal sampler.
5. In the fifth example, we define the cdf for the beta distribution, and we draw samples from it.
+## Related projects
+
+- [Squiggle](https://www.squiggle-language.com/)
+- [SquigglePy](https://github.com/rethinkpriorities/squigglepy)
+- [time to botec](https://github.com/NunoSempere/time-to-botec)
+- [simple squiggle](https://nunosempere.com/blog/2022/04/17/simple-squiggle/)
+
## To do list
- [ ] Have some more complicated & realistic example
@@ -34,9 +41,11 @@ You can follow some example usage in the examples/ folder
- Schema: a function which takes a sample and manipulates it,
- and at the end, an array of samples.
- Explain boxes
- - Explain individual examples
+ - [x] Explain individual examples
- Explain nested functions
- [ ] Publish online
+- [ ] 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
## Done
diff --git a/examples/04_sample_from_cdf_simple/example b/examples/04_sample_from_cdf_simple/example
Binary files differ.
diff --git a/examples/05_sample_from_cdf_beta/example b/examples/05_sample_from_cdf_beta/example
Binary files differ.
diff --git a/examples/05_sample_from_cdf_beta/example.c b/examples/05_sample_from_cdf_beta/example.c
@@ -42,7 +42,7 @@ struct box incbeta(float a, float b, float x)
* 3. This notice may not be removed or altered from any source distribution.
*/
if (x < 0.0 || x > 1.0) {
- PROCESS_ERROR("x out of bounds [0, 1], in function incbeta");
+ return PROCESS_ERROR("x out of bounds [0, 1], in function incbeta");
}
/*The continued fraction converges nicely for x < (a+1)/(a+b+2)*/
@@ -102,7 +102,7 @@ struct box incbeta(float a, float b, float x)
}
}
- PROCESS_ERROR("More loops needed, did not converge, in function incbeta");
+ return PROCESS_ERROR("More loops needed, did not converge, in function incbeta");
}
struct box cdf_beta(float x)
diff --git a/squiggle.c b/squiggle.c
@@ -6,20 +6,9 @@
#include <stdlib.h>
#include <time.h>
-#define EXIT_ON_ERROR 0
#define MAX_ERROR_LENGTH 500
-#define PROCESS_ERROR(...) \
- do { \
- if (EXIT_ON_ERROR) { \
- printf("@, in %s (%d)", __FILE__, __LINE__); \
- exit(1); \
- } else { \
- char error_msg[MAX_ERROR_LENGTH]; \
- snprintf(error_msg, MAX_ERROR_LENGTH, "@, in %s (%d)", __FILE__, __LINE__); \
- struct box error = { .empty = 1, .error_msg = error_msg }; \
- return error; \
- } \
- } while (0)
+#define EXIT_ON_ERROR 0
+#define PROCESS_ERROR(error_msg) process_error(error_msg, EXIT_ON_ERROR, __FILE__, __LINE__)
// PI constant
const float PI = 3.14159265358979323846; // M_PI in gcc gnu99
@@ -139,6 +128,18 @@ struct box {
char* error_msg;
};
+struct box process_error(const char* error_msg, int should_exit, char* file, int line){
+ if(should_exit){
+ printf("@, in %s (%d)", file, line);
+ exit(1);
+ }else{
+ char error_msg[MAX_ERROR_LENGTH];
+ snprintf(error_msg, MAX_ERROR_LENGTH, "@, in %s (%d)", file, line);
+ struct box error = { .empty = 1, .error_msg = error_msg };
+ return error;
+ }
+}
+
// Inverse cdf at point
// Two versions of this function:
// - raw, dealing with cdfs that return floats
@@ -176,7 +177,7 @@ struct box inverse_cdf_float(float cdf(float), float p)
}
if (!interval_found) {
- PROCESS_ERROR("Interval containing the target value not found, in function inverse_cdf");
+ return PROCESS_ERROR("Interval containing the target value not found, in function inverse_cdf");
} else {
int convergence_condition = 0;
@@ -205,7 +206,7 @@ struct box inverse_cdf_float(float cdf(float), float p)
struct box result = { .empty = 0, .content = low };
return result;
} else {
- PROCESS_ERROR("Search process did not converge, in function inverse_cdf");
+ return PROCESS_ERROR("Search process did not converge, in function inverse_cdf");
}
}
}
@@ -228,12 +229,12 @@ struct box inverse_cdf_box(struct box cdf_box(float), float p)
// but it's also the *correct* thing to do.
struct box cdf_low = cdf_box(low);
if (cdf_low.empty) {
- PROCESS_ERROR(cdf_low.error_msg);
+ return PROCESS_ERROR(cdf_low.error_msg);
}
struct box cdf_high = cdf_box(high);
if (cdf_high.empty) {
- PROCESS_ERROR(cdf_low.error_msg);
+ return PROCESS_ERROR(cdf_low.error_msg);
}
int low_condition = (cdf_low.content < p);
@@ -248,7 +249,7 @@ struct box inverse_cdf_box(struct box cdf_box(float), float p)
}
if (!interval_found) {
- PROCESS_ERROR("Interval containing the target value not found, in function inverse_cdf");
+ return PROCESS_ERROR("Interval containing the target value not found, in function inverse_cdf");
} else {
int convergence_condition = 0;
@@ -263,7 +264,7 @@ struct box inverse_cdf_box(struct box cdf_box(float), float p)
} else {
struct box cdf_mid = cdf_box(mid);
if (cdf_mid.empty) {
- PROCESS_ERROR(cdf_mid.error_msg);
+ return PROCESS_ERROR(cdf_mid.error_msg);
}
float mid_sign = cdf_mid.content - p;
if (mid_sign < 0) {
@@ -281,19 +282,19 @@ struct box inverse_cdf_box(struct box cdf_box(float), float p)
struct box result = { .empty = 0, .content = low };
return result;
} else {
- PROCESS_ERROR("Search process did not converge, in function inverse_cdf");
+ return PROCESS_ERROR("Search process did not converge, in function inverse_cdf");
}
}
}
// Sampler based on inverse cdf and randomness function
-struct box sampler_box_cdf(struct box cdf(float), uint32_t* seed)
+struct box sampler_cdf_box(struct box cdf(float), uint32_t* seed)
{
float p = rand_0_to_1(seed);
struct box result = inverse_cdf_box(cdf, p);
return result;
}
-struct box sampler_float_cdf(float cdf(float), uint32_t* seed)
+struct box sampler_cdf_float(float cdf(float), uint32_t* seed)
{
float p = rand_0_to_1(seed);
struct box result = inverse_cdf_float(cdf, p);
diff --git a/squiggle.h b/squiggle.h
@@ -33,20 +33,10 @@ struct box {
};
// Macros to handle errors
-#define EXIT_ON_ERROR 0
#define MAX_ERROR_LENGTH 500
-#define PROCESS_ERROR(...) \
- do { \
- if (EXIT_ON_ERROR) { \
- printf("@, in %s (%d)", __FILE__, __LINE__); \
- exit(1); \
- } else { \
- char error_msg[MAX_ERROR_LENGTH]; \
- snprintf(error_msg, MAX_ERROR_LENGTH, "@, in %s (%d)", __FILE__, __LINE__); \
- struct box error = { .empty = 1, .error_msg = error_msg }; \
- return error; \
- } \
- } while (0)
+#define EXIT_ON_ERROR 0
+#define PROCESS_ERROR(error_msg) process_error(error_msg, EXIT_ON_ERROR, __FILE__, __LINE__)
+struct box process_error(const char* error_msg, int should_exit, char* file, int line);
// Inverse cdf
struct box inverse_cdf_float(float cdf(float), float p);