add shift for normals and scaling for lognormals

This commit is contained in:
NunoSempere 2023-08-01 14:08:19 +02:00
parent e0df88633c
commit 555ac7371b
2 changed files with 59 additions and 18 deletions

View File

@ -20,7 +20,7 @@ uint64_t xorshift32(uint32_t* seed)
// See <https://stackoverflow.com/questions/53886131/how-does-xorshift64-works> // See <https://stackoverflow.com/questions/53886131/how-does-xorshift64-works>
// https://en.wikipedia.org/wiki/Xorshift // https://en.wikipedia.org/wiki/Xorshift
// Also some drama: <https://www.pcg-random.org/posts/on-vignas-pcg-critique.html>, <https://prng.di.unimi.it/> // Also some drama: <https://www.pcg-random.org/posts/on-vignas-pcg-critique.html>, <https://prng.di.unimi.it/>
// for floats
uint64_t x = *seed; uint64_t x = *seed;
x ^= x << 13; x ^= x << 13;
x ^= x >> 17; x ^= x >> 17;
@ -30,11 +30,7 @@ uint64_t xorshift32(uint32_t* seed)
uint64_t xorshift64(uint64_t* seed) uint64_t xorshift64(uint64_t* seed)
{ {
// Algorithm "xor" from p. 4 of Marsaglia, "Xorshift RNGs" // same as above, but for generating doubles
// See <https://stackoverflow.com/questions/53886131/how-does-xorshift64-works>
// https://en.wikipedia.org/wiki/Xorshift
// Also some drama: <https://www.pcg-random.org/posts/on-vignas-pcg-critique.html>, <https://prng.di.unimi.it/>
uint64_t x = *seed; uint64_t x = *seed;
x ^= x << 13; x ^= x << 13;
x ^= x >> 7; x ^= x >> 7;
@ -383,6 +379,19 @@ struct box sampler_cdf_double(double cdf(double), uint64_t* seed)
return result; return result;
} }
/* Could also define other variations, e.g.,
double sampler_danger(struct box cdf(double), uint64_t* seed)
{
double p = sample_unit_uniform(seed);
struct box result = inverse_cdf_box(cdf, p);
if(result.empty){
exit(1);
}else{
return result.content;
}
}
*/
// Get confidence intervals, given a sampler // Get confidence intervals, given a sampler
struct c_i { struct c_i {
@ -422,15 +431,47 @@ struct c_i get_90_confidence_interval(double (*sampler)(uint64_t*), uint64_t* se
return result; return result;
} }
/* Could also define other variations, e.g., // Do algebra over lognormals and normals
double sampler_danger(struct box cdf(double), uint64_t* seed) struct normal_parameters {
double mean;
double std;
};
struct lognormal_parameters {
double logmean;
double logstd;
};
struct normal_parameters algebra_sum_normals(struct normal_parameters a, struct normal_parameters b)
{ {
double p = sample_unit_uniform(seed); struct normal_parameters result = {
struct box result = inverse_cdf_box(cdf, p); .mean = a.mean + b.mean,
if(result.empty){ .std = sqrt((a.std * a.std) + (b.std * b.std)),
exit(1); };
}else{ return result;
return result.content;
} }
struct normal_parameters algebra_shift_normal(struct normal_parameters a, double shift)
{
struct normal_parameters result = {
.mean = a.mean + shift,
.std = a.std,
};
return result;
}
struct lognormal_parameters algebra_product_lognormals(struct lognormal_parameters a, struct lognormal_parameters b)
{
struct lognormal_parameters result = {
.logmean = a.logmean + b.logmean,
.logstd = sqrt((a.logstd * a.logstd) + (b.logstd * b.logstd)),
};
return result;
}
struct lognormal_parameters algebra_scale_lognormal(struct lognormal_parameters a, double k)
{
struct lognormal_parameters result = {
.logmean = a.logmean + k,
.logstd = a.logstd,
};
return result;
} }
*/