star-sp

Random number generators and distributions
git clone git://git.meso-star.fr/star-sp.git
Log | Files | Refs | README | LICENSE

commit 7988e07b4898f422c200216a9870942fcf4e9572
parent fb337ef6236d964991f8fd43c274a56f7405385f
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Thu,  7 Jul 2016 12:08:33 +0200

API change: *_get distribution functions now return what they produce (was an error code).

Diffstat:
Msrc/ssp.h | 22+++++++++-------------
Msrc/ssp_distributions.cpp | 31++++++++++++-------------------
Msrc/test_ssp_ran_gaussian.c | 7+------
Msrc/test_ssp_ran_piecewise_linear.c | 7+------
Msrc/test_ssp_ran_uniform_disk.c | 6+-----
5 files changed, 24 insertions(+), 49 deletions(-)

diff --git a/src/ssp.h b/src/ssp.h @@ -601,17 +601,15 @@ SSP_API res_T ssp_ran_gaussian_ref_put (struct ssp_ran_type* ran); -SSP_API res_T +SSP_API double ssp_ran_gaussian_get (const struct ssp_ran_type* ran, - struct ssp_rng* rng, - double* res); + struct ssp_rng* rng); -SSP_API res_T +SSP_API double ssp_distribution_gaussian_pdf (const struct ssp_ran_type* ran, - double x, - double* res); + double x); /******************************************************************************* * Piecewise linear distribution @@ -637,30 +635,28 @@ SSP_API res_T ssp_ran_piecewise_linear_ref_put (struct ssp_ran_type* ran); -SSP_API res_T +SSP_API double ssp_ran_piecewise_linear_get (const struct ssp_ran_type *ran, - struct ssp_rng* rng, - double *res); + struct ssp_rng* rng); /******************************************************************************* * Uniform disk distribution ******************************************************************************/ -static FINLINE res_T +static FINLINE double* ssp_ran_uniform_disk (struct ssp_rng* rng, double radius, double pt[2]) { double theta, r; - if(!rng || !pt || radius <= 0) return RES_BAD_ARG; - + ASSERT(rng && pt && radius > 0); theta = ssp_rng_uniform_double(rng, 0, 2 * PI); r = radius * sqrt(ssp_rng_canonical(rng)); pt[0] = r * cos(theta); pt[1] = r * sin(theta); - return RES_OK; + return pt; } END_DECLS diff --git a/src/ssp_distributions.cpp b/src/ssp_distributions.cpp @@ -106,9 +106,7 @@ ssp_ran_gaussian_create } ran->allocator = allocator; state->distrib = static_cast<normal_dist*>(new(tmp) normal_dist); - state->mu = 0; - state->K1 = 1; - state->K2 = 1 / SQRT_2_PI; + state->K1 = -1; /* invalid */ if (out_ran) *out_ran = ran; end: return res; @@ -158,26 +156,24 @@ ssp_ran_gaussian_ref_put return RES_OK; } -res_T +double ssp_ran_gaussian_get - (const struct ssp_ran_type* ran, struct ssp_rng* rng, double* res) + (const struct ssp_ran_type* ran, struct ssp_rng* rng) { - if(!ran || !rng || !res) return RES_BAD_ARG; class rng_cxx r(*rng); ran_gaussian_state* state = static_cast<ran_gaussian_state*>(ran->state); - *res = state->distrib->operator()(r); - return RES_OK; + ASSERT(state->K1 > 0); + return state->distrib->operator()(r); } -res_T +double ssp_ran_gaussian_pdf - (const struct ssp_ran_type* ran, double x, double* res) + (const struct ssp_ran_type* ran, double x) { - if(!ran || !res) return RES_BAD_ARG; ran_gaussian_state* state = static_cast<ran_gaussian_state*>(ran->state); const double tmp = (x - state->mu) * state->K1; - *res = state->K2 * exp(-0.5 * tmp * tmp); - return RES_OK; + ASSERT(state->K1 > 0); + return state->K2 * exp(-0.5 * tmp * tmp); } /******************************************************************************* @@ -266,16 +262,13 @@ ssp_ran_piecewise_linear_ref_put return RES_OK; } -res_T +double ssp_ran_piecewise_linear_get (const struct ssp_ran_type* ran, - struct ssp_rng* rng, - double* res) + struct ssp_rng* rng) { - if(!ran || !rng || !res) return RES_BAD_ARG; class rng_cxx r(*rng); ran_piecewise_linear_state* state = static_cast<ran_piecewise_linear_state*>(ran->state); - *res = state->distrib->operator()(r); - return RES_OK; + return state->distrib->operator()(r); } diff --git a/src/test_ssp_ran_gaussian.c b/src/test_ssp_ran_gaussian.c @@ -71,14 +71,9 @@ main(int argc, char** argv) CHECK(ssp_ran_gaussian_ref_put(NULL), RES_BAD_ARG); CHECK(ssp_ran_gaussian_ref_put(gaussian), RES_OK); - CHECK(ssp_ran_gaussian_get(NULL, rng, &x), RES_BAD_ARG); - CHECK(ssp_ran_gaussian_get(gaussian, NULL, &x), RES_BAD_ARG); - CHECK(ssp_ran_gaussian_get(NULL, NULL, &x), RES_BAD_ARG); - time_current(&start); for (i = 0; i < NBS; i++) { - double _x; - CHECK(ssp_ran_gaussian_get(gaussian, rng, &_x), RES_OK); + double _x = ssp_ran_gaussian_get(gaussian, rng); x += _x; x2 += _x * _x; } diff --git a/src/test_ssp_ran_piecewise_linear.c b/src/test_ssp_ran_piecewise_linear.c @@ -72,13 +72,8 @@ main(int argc, char** argv) CHECK(ssp_ran_piecewise_linear_ref_put(NULL), RES_BAD_ARG); CHECK(ssp_ran_piecewise_linear_ref_put(pwl), RES_OK); - CHECK(ssp_ran_piecewise_linear_get(NULL, rng, &x), RES_BAD_ARG); - CHECK(ssp_ran_piecewise_linear_get(NULL, rng, &x), RES_BAD_ARG); - CHECK(ssp_ran_piecewise_linear_get(pwl, rng, NULL), RES_BAD_ARG); - for (i = 0; i < NBS; i++) { - double _x; - ssp_ran_piecewise_linear_get(pwl, rng, &_x); + double _x = ssp_ran_piecewise_linear_get(pwl, rng); CHECK(0 <= _x && _x <= 10, 1); x += _x; x2 += _x * _x; diff --git a/src/test_ssp_ran_uniform_disk.c b/src/test_ssp_ran_uniform_disk.c @@ -54,12 +54,8 @@ main(int argc, char** argv) CHECK(ssp_rng_proxy_create(&allocator, &ssp_rng_threefry, 1, &proxy), RES_OK); CHECK(ssp_rng_proxy_create_rng(proxy, 0, &rng), RES_OK); - CHECK(ssp_ran_uniform_disk(NULL, 100, pt), RES_BAD_ARG); - CHECK(ssp_ran_uniform_disk(rng, -100, pt), RES_BAD_ARG); - CHECK(ssp_ran_uniform_disk(rng, 100, pt), RES_OK); - for (i = 0; i < NBS; i++) { - CHECK(ssp_ran_uniform_disk(rng, 100, pt), RES_OK); + ssp_ran_uniform_disk(rng, 100, pt); /* locate pt in a 10x10 grid */ r = (unsigned)((100 + pt[0]) / 20); c = (unsigned)((100 + pt[1]) / 20);