simplify PROCESS_ERROR macro

This commit is contained in:
NunoSempere 2023-07-16 22:58:20 +02:00
parent 11e965be4f
commit 6247fbfb7b
6 changed files with 39 additions and 39 deletions

View File

@ -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

View File

@ -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)

View File

@ -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);

View File

@ -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);