star-sp

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

commit 054a3047f0239db55b9ee6582b4318e25c6feacc
parent 0e55da9835f1afc59fa342544e00d94f1c15c158
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Mon, 14 Dec 2015 11:10:46 +0100

Fix the ssp_ran_hemisphere_<cos|uniform> routines

The returned sample was wrong when the submitted up vector aliased the
returned sample.

Diffstat:
Msrc/ssp.h | 12++++++++----
Msrc/test_ssp_ran_hemisphere.c | 22++++++++++++++++++++++
2 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/src/ssp.h b/src/ssp.h @@ -427,9 +427,11 @@ ssp_ran_hemisphere_uniform (struct ssp_rng* rng, const float up[3], float sample[4]) { float basis[9]; + float sample_local[3]; ASSERT(rng && up && sample && f3_is_normalized(up)); - ssp_ran_hemisphere_uniform_local(rng, sample); - return f33_mulf3(sample, f33_basis(basis, up), sample); + ssp_ran_hemisphere_uniform_local(rng, sample_local); + sample[3] = sample_local[3]; + return f33_mulf3(sample, f33_basis(basis, up), sample_local); } /* Return the probability distribution for an hemispheric uniform random @@ -474,10 +476,12 @@ ssp_ran_hemisphere_cos_local_pdf(const float sample[3]) static INLINE float* ssp_ran_hemisphere_cos(struct ssp_rng* rng, const float up[3], float sample[4]) { + float sample_local[4]; float basis[9]; ASSERT(rng && up && sample && f3_is_normalized(up)); - ssp_ran_hemisphere_cos_local(rng, sample); - return f33_mulf3(sample, f33_basis(basis, up), sample); + ssp_ran_hemisphere_cos_local(rng, sample_local); + sample[3] = sample_local[3]; + return f33_mulf3(sample, f33_basis(basis, up), sample_local); } /* Return the probability distribution for an hemispheric cosine weighted diff --git a/src/test_ssp_ran_hemisphere.c b/src/test_ssp_ran_hemisphere.c @@ -93,6 +93,17 @@ main(int argc, char** argv) } } + samps1[1][0] = (float)ssp_rng_uniform_double(rng1, -1.0, 1.0); + samps1[1][1] = (float)ssp_rng_uniform_double(rng1, -1.0, 1.0); + samps1[1][2] = (float)ssp_rng_uniform_double(rng1, -1.0, 1.0); + f3_normalize(samps1[1], samps1[1]); + + ssp_rng_set(rng0, 0); + ssp_ran_hemisphere_uniform(rng0, samps1[1], samps0[0]); + ssp_rng_set(rng0, 0); + ssp_ran_hemisphere_uniform(rng0, samps1[1], samps1[1]); + CHECK(f4_eq(samps0[0], samps1[1]), 1); + ssp_rng_set(rng0, 0); FOR_EACH(i, 0, NSAMPS) { float frame[9]; @@ -137,6 +148,17 @@ main(int argc, char** argv) } } + samps1[1][0] = (float)ssp_rng_uniform_double(rng1, -1.0, 1.0); + samps1[1][1] = (float)ssp_rng_uniform_double(rng1, -1.0, 1.0); + samps1[1][2] = (float)ssp_rng_uniform_double(rng1, -1.0, 1.0); + f3_normalize(samps1[1], samps1[1]); + + ssp_rng_set(rng0, 0); + ssp_ran_hemisphere_cos(rng0, samps1[1], samps0[0]); + ssp_rng_set(rng0, 0); + ssp_ran_hemisphere_cos(rng0, samps1[1], samps1[1]); + CHECK(f4_eq(samps0[0], samps1[1]), 1); + ssp_rng_ref_put(rng0); ssp_rng_ref_put(rng1); check_memory_allocator(&allocator);