rename sampler functions, elaborate on README, etc.

This commit is contained in:
NunoSempere 2023-07-16 22:32:03 +02:00
parent ea80c930e6
commit 11e965be4f
9 changed files with 46 additions and 29 deletions

View File

@ -1,15 +1,30 @@
# Squiggle.c # Squiggle.c
A self-contained C99 library that provides a subset of [Squiggle](https://www.squiggle-language.com/)'s functionality in C.
## Why C? ## Why C?
- Because it is fast - 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 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 ## To do list

View File

@ -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); printf("\nGetting some samples from %s:\n", cdf_name);
clock_t begin = clock(); clock_t begin = clock();
for (int i = 0; i < NUM_SAMPLES; i++) { 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) { if (sample.empty) {
printf("Error in sampler function for %s", cdf_name); printf("Error in sampler function for %s", cdf_name);
} else { } else {

View File

@ -19,7 +19,7 @@ DEPENDENCIES=$(MATH)
## Flags ## Flags
DEBUG= #'-g' DEBUG= #'-g'
STANDARD=-std=gnu99 ## allows for nested functions. STANDARD=-std=c99 ## gnu99 allows for nested functions.
EXTENSIONS= #-fnested-functions EXTENSIONS= #-fnested-functions
WARNINGS=-Wall WARNINGS=-Wall
OPTIMIZED=-O3#-Ofast OPTIMIZED=-O3#-Ofast

View File

@ -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); printf("\nGetting some samples from %s:\n", cdf_name);
clock_t begin = clock(); clock_t begin = clock();
for (int i = 0; i < NUM_SAMPLES; i++) { 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) { if (sample.empty) {
printf("Error in sampler function for %s", cdf_name); printf("Error in sampler function for %s", cdf_name);
} else { } else {

View File

@ -19,7 +19,7 @@ DEPENDENCIES=$(MATH)
## Flags ## Flags
DEBUG= #'-g' DEBUG= #'-g'
STANDARD=-std=gnu99 ## allows for nested functions. STANDARD=-std=c99 ## gnu99 allows for nested functions.
EXTENSIONS= #-fnested-functions EXTENSIONS= #-fnested-functions
WARNINGS=-Wall WARNINGS=-Wall
OPTIMIZED=-O3#-Ofast OPTIMIZED=-O3#-Ofast

View File

@ -22,7 +22,7 @@
} while (0) } while (0)
// PI constant // PI constant
const float PI = M_PI; // 3.14159265358979323846; const float PI = 3.14159265358979323846; // M_PI in gcc gnu99
// Pseudo Random number generator // Pseudo Random number generator

View File

@ -4,29 +4,15 @@
// uint32_t header // uint32_t header
#include <stdint.h> #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 // Pseudo Random number generator
uint32_t xorshift32(uint32_t* seed); uint32_t xorshift32(uint32_t* seed);
// Distribution & sampling functions // Basic distribution sampling functions
float rand_0_to_1(uint32_t* seed); float rand_0_to_1(uint32_t* seed);
float rand_float(float max, uint32_t* seed); float rand_float(float max, uint32_t* seed);
float unit_normal(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_uniform(float from, float to, uint32_t* seed);
float random_normal(float mean, float sigma, uint32_t* seed); float random_normal(float mean, float sigma, uint32_t* seed);
float random_lognormal(float logmean, float logsigma, uint32_t* seed); float random_lognormal(float logmean, float logsigma, uint32_t* seed);
@ -46,12 +32,28 @@ struct box {
char* error_msg; 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 // Inverse cdf
struct box inverse_cdf_float(float cdf(float), float p); struct box inverse_cdf_float(float cdf(float), float p);
struct box inverse_cdf_box(struct box cdf_box(float), float p); struct box inverse_cdf_box(struct box cdf_box(float), float p);
// Samplers from cdf // Samplers from cdf
struct box sampler_box_cdf(struct box cdf(float), uint32_t* seed); struct box sampler_cdf_float(float cdf(float), uint32_t* seed);
struct box sampler_float_cdf(float cdf(float), uint32_t* seed); struct box sampler_cdf_box(struct box cdf(float), uint32_t* seed);
#endif #endif