give more expressive names to main functions
This bash function was helpful:
function replace(){
  grep "$1" -rl .
  grep "$1" -rl . | xargs sed -i "s/$1/$2/g";
}
			
			
This commit is contained in:
		
							parent
							
								
									8cc63dce4b
								
							
						
					
					
						commit
						04070a934e
					
				| 
						 | 
				
			
			@ -77,7 +77,7 @@ Behaviour on error can be toggled by the `EXIT_ON_ERROR` variable. This library
 | 
			
		|||
 | 
			
		||||
## To do list
 | 
			
		||||
 | 
			
		||||
- [ ] Rename functions to something more self-explanatory, e.g,. sample_unit_normal.
 | 
			
		||||
- [ ] Rename functions to something more self-explanatory, e.g,. sample_sample_sample_unit_normal.
 | 
			
		||||
- [ ] Have some more complicated & realistic example
 | 
			
		||||
- [ ] Add summarization functions, like mean, std, 90% ci (or all c.i.?)
 | 
			
		||||
- [ ] Publish online
 | 
			
		||||
| 
						 | 
				
			
			@ -90,7 +90,7 @@ Behaviour on error can be toggled by the `EXIT_ON_ERROR` variable. This library
 | 
			
		|||
- [x] Add example for many samples
 | 
			
		||||
- ~~[ ] Add a custom preprocessor to allow simple nested functions that don't rely on local scope?~~
 | 
			
		||||
- [x] Use gcc extension to define functions nested inside main.
 | 
			
		||||
- [x] Chain various mixture functions
 | 
			
		||||
- [x] Chain various sample_mixture functions
 | 
			
		||||
- [x] Add beta distribution
 | 
			
		||||
  - See <https://stats.stackexchange.com/questions/502146/how-does-numpy-generate-samples-from-a-beta-distribution> for a faster method.
 | 
			
		||||
- ~~[-] Use OpenMP for acceleration~~
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
										
											Binary file not shown.
										
									
								
							| 
						 | 
				
			
			@ -16,12 +16,12 @@ float sample_1(uint32_t* seed)
 | 
			
		|||
 | 
			
		||||
float sample_few(uint32_t* seed)
 | 
			
		||||
{
 | 
			
		||||
    return random_to(1, 3, seed);
 | 
			
		||||
    return sample_to(1, 3, seed);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
float sample_many(uint32_t* seed)
 | 
			
		||||
{
 | 
			
		||||
    return random_to(2, 10, seed);
 | 
			
		||||
    return sample_to(2, 10, seed);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int main(){
 | 
			
		||||
| 
						 | 
				
			
			@ -37,7 +37,7 @@ int main(){
 | 
			
		|||
    float weights[] = { 1 - p_c, p_c / 2, p_c / 4, p_c / 4 };
 | 
			
		||||
    float (*samplers[])(uint32_t*) = { sample_0, sample_1, sample_few, sample_many };
 | 
			
		||||
 | 
			
		||||
    float result_one = mixture(samplers, weights, n_dists, seed);
 | 
			
		||||
    float result_one = sample_mixture(samplers, weights, n_dists, seed);
 | 
			
		||||
		printf("result_one: %f\n", result_one);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
										
											Binary file not shown.
										
									
								
							| 
						 | 
				
			
			@ -16,12 +16,12 @@ float sample_1(uint32_t* seed)
 | 
			
		|||
 | 
			
		||||
float sample_few(uint32_t* seed)
 | 
			
		||||
{
 | 
			
		||||
    return random_to(1, 3, seed);
 | 
			
		||||
    return sample_to(1, 3, seed);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
float sample_many(uint32_t* seed)
 | 
			
		||||
{
 | 
			
		||||
    return random_to(2, 10, seed);
 | 
			
		||||
    return sample_to(2, 10, seed);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int main(){
 | 
			
		||||
| 
						 | 
				
			
			@ -40,7 +40,7 @@ int main(){
 | 
			
		|||
		int n_samples = 1000000;
 | 
			
		||||
		float* result_many = (float *) malloc(n_samples * sizeof(float));
 | 
			
		||||
		for(int i=0; i<n_samples; i++){
 | 
			
		||||
      result_many[i] = mixture(samplers, weights, n_dists, seed);
 | 
			
		||||
      result_many[i] = sample_mixture(samplers, weights, n_dists, seed);
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		printf("result_many: [");
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
										
											Binary file not shown.
										
									
								
							| 
						 | 
				
			
			@ -16,8 +16,8 @@ int main(){
 | 
			
		|||
		
 | 
			
		||||
		float sample_0(uint32_t* seed){ return 0; }
 | 
			
		||||
		float sample_1(uint32_t* seed) { return 1; }
 | 
			
		||||
		float sample_few(uint32_t* seed){ return random_to(1, 3, seed); }
 | 
			
		||||
		float sample_many(uint32_t* seed){ return random_to(2, 10, seed); } 
 | 
			
		||||
		float sample_few(uint32_t* seed){ return sample_to(1, 3, seed); }
 | 
			
		||||
		float sample_many(uint32_t* seed){ return sample_to(2, 10, seed); } 
 | 
			
		||||
		
 | 
			
		||||
    float (*samplers[])(uint32_t*) = { sample_0, sample_1, sample_few, sample_many };
 | 
			
		||||
		float weights[] = { 1 - p_c, p_c / 2, p_c / 4, p_c / 4 };
 | 
			
		||||
| 
						 | 
				
			
			@ -25,7 +25,7 @@ int main(){
 | 
			
		|||
		int n_samples = 1000000;
 | 
			
		||||
		float* result_many = (float *) malloc(n_samples * sizeof(float));
 | 
			
		||||
		for(int i=0; i<n_samples; i++){
 | 
			
		||||
      result_many[i] = mixture(samplers, weights, n_dists, seed);
 | 
			
		||||
      result_many[i] = sample_mixture(samplers, weights, n_dists, seed);
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		printf("result_many: [");
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
										
											Binary file not shown.
										
									
								
							| 
						 | 
				
			
			@ -84,12 +84,12 @@ int main()
 | 
			
		|||
    test_and_time_sampler_float("cdf_normal_0_1", cdf_normal_0_1, seed);
 | 
			
		||||
 | 
			
		||||
    // Get some normal samples using a previous approach
 | 
			
		||||
    printf("\nGetting some samples from unit_normal\n");
 | 
			
		||||
    printf("\nGetting some samples from sample_unit_normal\n");
 | 
			
		||||
 | 
			
		||||
    clock_t begin_2 = clock();
 | 
			
		||||
 | 
			
		||||
    for (int i = 0; i < NUM_SAMPLES; i++) {
 | 
			
		||||
        float normal_sample = unit_normal(seed);
 | 
			
		||||
        float normal_sample = sample_unit_normal(seed);
 | 
			
		||||
        // printf("%f\n", normal_sample);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										40
									
								
								squiggle.c
									
									
									
									
									
								
							
							
						
						
									
										40
									
								
								squiggle.c
									
									
									
									
									
								
							| 
						 | 
				
			
			@ -28,48 +28,44 @@ uint32_t xorshift32(uint32_t* seed)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
// Distribution & sampling functions
 | 
			
		||||
float rand_0_to_1(uint32_t* seed)
 | 
			
		||||
float sample_unit_uniform(uint32_t* seed)
 | 
			
		||||
{
 | 
			
		||||
	  // samples uniform from [0,1] interval.
 | 
			
		||||
    return ((float)xorshift32(seed)) / ((float)UINT32_MAX);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
float rand_float(float max, uint32_t* seed)
 | 
			
		||||
{
 | 
			
		||||
    return rand_0_to_1(seed) * max;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
float unit_normal(uint32_t* seed)
 | 
			
		||||
float sample_unit_normal(uint32_t* seed)
 | 
			
		||||
{
 | 
			
		||||
    // See: <https://en.wikipedia.org/wiki/Box%E2%80%93Muller_transform>
 | 
			
		||||
    float u1 = rand_0_to_1(seed);
 | 
			
		||||
    float u2 = rand_0_to_1(seed);
 | 
			
		||||
    float u1 = sample_unit_uniform(seed);
 | 
			
		||||
    float u2 = sample_unit_uniform(seed);
 | 
			
		||||
    float z = sqrtf(-2.0 * log(u1)) * sin(2 * PI * u2);
 | 
			
		||||
    return z;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
float random_uniform(float from, float to, uint32_t* seed)
 | 
			
		||||
float sample_uniform(float from, float to, uint32_t* seed)
 | 
			
		||||
{
 | 
			
		||||
    return rand_0_to_1(seed) * (to - from) + from;
 | 
			
		||||
    return sample_unit_uniform(seed) * (to - from) + from;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
float random_normal(float mean, float sigma, uint32_t* seed)
 | 
			
		||||
float sample_normal(float mean, float sigma, uint32_t* seed)
 | 
			
		||||
{
 | 
			
		||||
    return (mean + sigma * unit_normal(seed));
 | 
			
		||||
    return (mean + sigma * sample_unit_normal(seed));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
float random_lognormal(float logmean, float logsigma, uint32_t* seed)
 | 
			
		||||
float sample_lognormal(float logmean, float logsigma, uint32_t* seed)
 | 
			
		||||
{
 | 
			
		||||
    return expf(random_normal(logmean, logsigma, seed));
 | 
			
		||||
    return expf(sample_normal(logmean, logsigma, seed));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
float random_to(float low, float high, uint32_t* seed)
 | 
			
		||||
float sample_to(float low, float high, uint32_t* seed)
 | 
			
		||||
{
 | 
			
		||||
    const float NORMAL95CONFIDENCE = 1.6448536269514722;
 | 
			
		||||
    float loglow = logf(low);
 | 
			
		||||
    float loghigh = logf(high);
 | 
			
		||||
    float logmean = (loglow + loghigh) / 2;
 | 
			
		||||
    float logsigma = (loghigh - loglow) / (2.0 * NORMAL95CONFIDENCE);
 | 
			
		||||
    return random_lognormal(logmean, logsigma, seed);
 | 
			
		||||
    return sample_lognormal(logmean, logsigma, seed);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Array helpers
 | 
			
		||||
| 
						 | 
				
			
			@ -91,7 +87,7 @@ void array_cumsum(float* array_to_sum, float* array_cumsummed, int length)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
// Mixture function
 | 
			
		||||
float mixture(float (*samplers[])(uint32_t*), float* weights, int n_dists, uint32_t* seed)
 | 
			
		||||
float sample_mixture(float (*samplers[])(uint32_t*), float* weights, int n_dists, uint32_t* seed)
 | 
			
		||||
{
 | 
			
		||||
    // You can see a simpler version of this function in the git history
 | 
			
		||||
    // or in C-02-better-algorithm-one-thread/
 | 
			
		||||
| 
						 | 
				
			
			@ -104,7 +100,7 @@ float mixture(float (*samplers[])(uint32_t*), float* weights, int n_dists, uint3
 | 
			
		|||
 | 
			
		||||
    float result;
 | 
			
		||||
    int result_set_flag = 0;
 | 
			
		||||
    float p = random_uniform(0, 1, seed);
 | 
			
		||||
    float p = sample_uniform(0, 1, seed);
 | 
			
		||||
    for (int k = 0; k < n_dists; k++) {
 | 
			
		||||
        if (p < cumsummed_normalized_weights[k]) {
 | 
			
		||||
            result = samplers[k](seed);
 | 
			
		||||
| 
						 | 
				
			
			@ -289,13 +285,13 @@ struct box inverse_cdf_box(struct box cdf_box(float), float p)
 | 
			
		|||
// Sampler based on inverse cdf and randomness function
 | 
			
		||||
struct box sampler_cdf_box(struct box cdf(float), uint32_t* seed)
 | 
			
		||||
{
 | 
			
		||||
    float p = rand_0_to_1(seed);
 | 
			
		||||
    float p = sample_unit_uniform(seed);
 | 
			
		||||
    struct box result = inverse_cdf_box(cdf, p);
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
struct box sampler_cdf_float(float cdf(float), uint32_t* seed)
 | 
			
		||||
{
 | 
			
		||||
    float p = rand_0_to_1(seed);
 | 
			
		||||
    float p = sample_unit_uniform(seed);
 | 
			
		||||
    struct box result = inverse_cdf_float(cdf, p);
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -303,7 +299,7 @@ struct box sampler_cdf_float(float cdf(float), uint32_t* seed)
 | 
			
		|||
/* Could also define other variations, e.g.,
 | 
			
		||||
float sampler_danger(struct box cdf(float), uint32_t* seed)
 | 
			
		||||
{
 | 
			
		||||
    float p = rand_0_to_1(seed);
 | 
			
		||||
    float p = sample_unit_uniform(seed);
 | 
			
		||||
    struct box result = inverse_cdf_box(cdf, p);
 | 
			
		||||
		if(result.empty){
 | 
			
		||||
			exit(1);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										15
									
								
								squiggle.h
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								squiggle.h
									
									
									
									
									
								
							| 
						 | 
				
			
			@ -8,22 +8,21 @@
 | 
			
		|||
uint32_t xorshift32(uint32_t* seed);
 | 
			
		||||
 | 
			
		||||
// 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);
 | 
			
		||||
float sample_unit_uniform(uint32_t* seed);
 | 
			
		||||
float sample_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);
 | 
			
		||||
float random_to(float low, float high, uint32_t* seed);
 | 
			
		||||
float sample_uniform(float from, float to, uint32_t* seed);
 | 
			
		||||
float sample_normal(float mean, float sigma, uint32_t* seed);
 | 
			
		||||
float sample_lognormal(float logmean, float logsigma, uint32_t* seed);
 | 
			
		||||
float sample_to(float low, float high, uint32_t* seed);
 | 
			
		||||
 | 
			
		||||
// Array helpers
 | 
			
		||||
float array_sum(float* array, int length);
 | 
			
		||||
void array_cumsum(float* array_to_sum, float* array_cumsummed, int length);
 | 
			
		||||
 | 
			
		||||
// Mixture function
 | 
			
		||||
float mixture(float (*samplers[])(uint32_t*), float* weights, int n_dists, uint32_t* seed);
 | 
			
		||||
float sample_mixture(float (*samplers[])(uint32_t*), float* weights, int n_dists, uint32_t* seed);
 | 
			
		||||
 | 
			
		||||
// Box
 | 
			
		||||
struct box {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user