commit 11e965be4fd5a8e45605fbdbc4213d58d8da936c
parent ea80c930e617c66b2bea71695dbb6df80cfd3d5e
Author: NunoSempere <nuno.sempere@protonmail.com>
Date: Sun, 16 Jul 2023 22:32:03 +0200
rename sampler functions, elaborate on README, etc.
Diffstat:
9 files changed, 46 insertions(+), 29 deletions(-)
diff --git a/README.md b/README.md
@@ -1,15 +1,30 @@
# Squiggle.c
-
+A self-contained C99 library that provides a subset of [Squiggle](https://www.squiggle-language.com/)'s functionality in C.
## Why C?
- Because it is fast
-- Because it can be made faster if need be, e.g., with a multi-threading library like OpenMP
-- Because if you can implement something in C, you can implement it anywhere else
-- Because it will last long
-- Because the language is honest
- Because I enjoy it
+- Because C is honest
+- Because it will last long
+- Because it can fit in my head
+- 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
+
+Have some basic building blocks, like , and return samplers. Use previous samplers to . Then use the final sampler to produce an array of samples.
+
+## Getting started
+
+You can follow some example usage in the examples/ folder
+
+1. In the first example, we define a small model, and draw one sample from it
+2. In the second example, we define a small model, and return many samples
+3. In the third example, we use a gcc extension—nested functions—to rewrite the code from point 2. in a more linear way.
+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.
## To do list
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/04_sample_from_cdf_simple/example.c b/examples/04_sample_from_cdf_simple/example.c
@@ -54,7 +54,7 @@ void test_and_time_sampler_float(char* cdf_name, float cdf_float(float), uint32_
printf("\nGetting some samples from %s:\n", cdf_name);
clock_t begin = clock();
for (int i = 0; i < NUM_SAMPLES; i++) {
- struct box sample = sampler_float_cdf(cdf_float, seed);
+ struct box sample = sampler_cdf_float(cdf_float, seed);
if (sample.empty) {
printf("Error in sampler function for %s", cdf_name);
} else {
diff --git a/examples/04_sample_from_cdf_simple/makefile b/examples/04_sample_from_cdf_simple/makefile
@@ -19,7 +19,7 @@ DEPENDENCIES=$(MATH)
## Flags
DEBUG= #'-g'
-STANDARD=-std=gnu99 ## allows for nested functions.
+STANDARD=-std=c99 ## gnu99 allows for nested functions.
EXTENSIONS= #-fnested-functions
WARNINGS=-Wall
OPTIMIZED=-O3#-Ofast
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
@@ -136,7 +136,7 @@ void test_and_time_sampler_box(char* cdf_name, struct box cdf_box(float), uint32
printf("\nGetting some samples from %s:\n", cdf_name);
clock_t begin = clock();
for (int i = 0; i < NUM_SAMPLES; i++) {
- struct box sample = sampler_box_cdf(cdf_box, seed);
+ struct box sample = sampler_cdf_box(cdf_box, seed);
if (sample.empty) {
printf("Error in sampler function for %s", cdf_name);
} else {
diff --git a/examples/05_sample_from_cdf_beta/makefile b/examples/05_sample_from_cdf_beta/makefile
@@ -19,7 +19,7 @@ DEPENDENCIES=$(MATH)
## Flags
DEBUG= #'-g'
-STANDARD=-std=gnu99 ## allows for nested functions.
+STANDARD=-std=c99 ## gnu99 allows for nested functions.
EXTENSIONS= #-fnested-functions
WARNINGS=-Wall
OPTIMIZED=-O3#-Ofast
diff --git a/squiggle.c b/squiggle.c
@@ -22,7 +22,7 @@
} while (0)
// PI constant
-const float PI = M_PI; // 3.14159265358979323846;
+const float PI = 3.14159265358979323846; // M_PI in gcc gnu99
// Pseudo Random number generator
diff --git a/squiggle.h b/squiggle.h
@@ -4,29 +4,15 @@
// uint32_t header
#include <stdint.h>
-// Macros
-#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)
-
// Pseudo Random number generator
uint32_t xorshift32(uint32_t* seed);
-// Distribution & sampling functions
+// Basic distribution sampling functions
float rand_0_to_1(uint32_t* seed);
float rand_float(float max, uint32_t* seed);
float unit_normal(uint32_t* seed);
+
+// Composite distribution sampling functions
float random_uniform(float from, float to, uint32_t* seed);
float random_normal(float mean, float sigma, uint32_t* seed);
float random_lognormal(float logmean, float logsigma, uint32_t* seed);
@@ -46,12 +32,28 @@ struct box {
char* error_msg;
};
+// 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)
+
// Inverse cdf
struct box inverse_cdf_float(float cdf(float), float p);
struct box inverse_cdf_box(struct box cdf_box(float), float p);
// Samplers from cdf
-struct box sampler_box_cdf(struct box cdf(float), uint32_t* seed);
-struct box sampler_float_cdf(float cdf(float), uint32_t* seed);
+struct box sampler_cdf_float(float cdf(float), uint32_t* seed);
+struct box sampler_cdf_box(struct box cdf(float), uint32_t* seed);
#endif