solstice-solver

Solver library of the solstice app
git clone git://git.meso-star.com/solstice-solver.git
Log | Files | Refs | README | LICENSE

commit 4b1776d27045791c8ebb50170c6f5a7ba02ad4cb
parent 2060dfe39b71247612b73b589649ef0281e95dd9
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Mon,  3 Jun 2019 16:18:59 +0200

Test the RNG state saved by the estimator

Diffstat:
Msrc/ssol.h | 2+-
Msrc/ssol_solver.c | 2+-
Msrc/test_ssol_solver1.c | 26++++++++++++++++++++++++--
Msrc/test_ssol_solver6.c | 42+++++++++++++++++++++++++++++++++++++++++-
4 files changed, 67 insertions(+), 5 deletions(-)

diff --git a/src/ssol.h b/src/ssol.h @@ -1204,7 +1204,7 @@ ssol_mc_shape_get_mc_primitive SSOL_API res_T ssol_solve (struct ssol_scene* scn, - struct ssp_rng* rng, + const struct ssp_rng* rng, const size_t realisations_count, const size_t max_failed_count, const struct ssol_path_tracker* tracker, /* NULL<=>Do not record the paths */ diff --git a/src/ssol_solver.c b/src/ssol_solver.c @@ -1119,7 +1119,7 @@ error: res_T ssol_solve (struct ssol_scene* scn, - struct ssp_rng* rng_state, + const struct ssp_rng* rng_state, const size_t realisations_count, const size_t max_failed_count, const struct ssol_path_tracker* path_tracker, diff --git a/src/test_ssol_solver1.c b/src/test_ssol_solver1.c @@ -49,8 +49,13 @@ main(int argc, char** argv) { struct spectrum_desc desc = {0}; struct mem_allocator allocator; + FILE* stream; struct ssol_device* dev; struct ssp_rng* rng; + struct ssp_rng* rng2; + const struct ssp_rng* rng_state; + struct ssp_rng_type rng_type0; + struct ssp_rng_type rng_type1; struct ssol_scene* scene; struct ssol_shape* dummy; struct ssol_shape* square; @@ -237,6 +242,23 @@ main(int argc, char** argv) CHK(ssol_estimator_get_mc_global(estimator, NULL) == RES_BAD_ARG); CHK(ssol_estimator_get_mc_global(estimator, &mc_global) == RES_OK); + CHK(ssol_estimator_get_rng_state(NULL, &rng_state) == RES_BAD_ARG); + CHK(ssol_estimator_get_rng_state(estimator, NULL) == RES_BAD_ARG); + CHK(ssol_estimator_get_rng_state(estimator, &rng_state) == RES_OK); + CHK(ssp_rng_get_type(rng_state, &rng_type0) == RES_OK); + CHK(ssp_rng_get_type(rng, &rng_type1) == RES_OK); + CHK(ssp_rng_type_eq(&rng_type0, &rng_type1)); + + /* Clone the rng_state */ + CHK(stream = tmpfile()); + CHK(ssp_rng_create(&allocator, &ssp_rng_threefry, &rng2) == RES_OK); + CHK(ssp_rng_write(rng_state, stream) == RES_OK); + rewind(stream); + CHK(ssp_rng_read(rng2, stream) == RES_OK); + CHK(fclose(stream) == 0); + CHK(ssp_rng_get(rng2) != ssp_rng_get(rng)); + CHK(ssp_rng_ref_put(rng2) == RES_OK); + CHK(ssol_estimator_ref_get(NULL) == RES_BAD_ARG); CHK(ssol_estimator_ref_get(estimator) == RES_OK); CHK(ssol_estimator_ref_put(NULL) == RES_BAD_ARG); @@ -324,8 +346,8 @@ main(int argc, char** argv) CHK(GET_MC_RCV(estimator, target, SSOL_FRONT, &mc_rcv) == RES_OK); printf("Ir(target) = %g +/- %g\n", mc_rcv.incoming_flux.E, mc_rcv.incoming_flux.SE); - CHK(eq_eps(mc_rcv.incoming_flux.E, m, 2 * std) == 1); - CHK(eq_eps(mc_rcv.incoming_flux.SE, std, 1e-1) == 1); + CHK(eq_eps(mc_rcv.incoming_flux.E, m, 3 * std) == 1); + CHK(eq_eps(mc_rcv.incoming_flux.SE, std, std*1e-2) == 1); CHK(ssol_estimator_ref_put(estimator) == RES_OK); /* Sample primary mirror only; variance is low */ diff --git a/src/test_ssol_solver6.c b/src/test_ssol_solver6.c @@ -51,6 +51,7 @@ main(int argc, char** argv) struct mem_allocator allocator; struct ssol_device* dev; struct ssp_rng* rng; + const struct ssp_rng* rng_state; struct ssol_object *m_object1; struct ssol_object *m_object2; struct ssol_object* t_object1; @@ -74,11 +75,14 @@ main(int argc, char** argv) struct ssol_sun* sun; struct ssol_spectrum* spectrum; struct ssol_estimator* estimator; + struct ssol_estimator* estimator2; struct ssol_mc_global mc_global; + struct ssol_mc_global mc_global2; struct ssol_mc_receiver mc_rcv; double dir[3]; double transform[12]; /* 3x4 column major matrix */ - + double sum_w, sum_w2, E, V, SE; + size_t count; (void) argc, (void) argv; mem_init_proxy_allocator(&allocator, &mem_default_allocator); @@ -177,6 +181,8 @@ main(int argc, char** argv) #define N__ 10000 #define GET_MC_RCV ssol_estimator_get_mc_receiver CHK(ssol_solve(scene, rng, N__, 0, NULL, &estimator) == RES_OK); + CHK(ssol_estimator_get_realisation_count(estimator, &count) == RES_OK); + CHK(count == N__); CHK(ssol_estimator_get_mc_global(estimator, &mc_global) == RES_OK); PRINT_GLOBAL(mc_global); CHK(eq_eps(mc_global.shadowed.E, 100000, 2 * 100000/sqrt(N__)) == 1); @@ -194,6 +200,39 @@ main(int argc, char** argv) CHK(eq_eps(mc_rcv.incoming_flux.E, 0, 1) == 1); CHK(mc_rcv.incoming_flux.E == mc_rcv.absorbed_flux.E); + /* Launch another run that is statistically independent of the first one and + * that uses 3 more times samples */ + CHK(ssol_estimator_get_rng_state(estimator, &rng_state) == RES_OK); + CHK(ssol_solve(scene, rng_state, N__*3, 0, NULL, &estimator2) == RES_OK); + + /* Check the estimator result */ + CHK(ssol_estimator_get_realisation_count(estimator2, &count) == RES_OK); + CHK(count == N__*3); + CHK(ssol_estimator_get_mc_global(estimator2, &mc_global2) == RES_OK); + CHK(eq_eps(mc_global2.shadowed.E, 100000, 2 * 100000/sqrt(N__)) == 1); + CHK(eq_eps(mc_global.shadowed.SE/sqrt(3), mc_global2.shadowed.SE, 1.e-1)); + + CHK(mc_global.shadowed.E != mc_global2.shadowed.E); + CHK(mc_global.shadowed.SE != mc_global2.shadowed.SE); + + /* Merge the 2 estimations */ + sum_w = mc_global.shadowed.E * N__; + sum_w += mc_global2.shadowed.E * N__*3; + V = mc_global.shadowed.SE * mc_global.shadowed.SE * N__; + sum_w2 = (V + mc_global.shadowed.E * mc_global.shadowed.E) * N__; + V = mc_global2.shadowed.SE * mc_global2.shadowed.SE * N__*3; + sum_w2 += (V + mc_global2.shadowed.E * mc_global2.shadowed.E) * N__*3; + E = sum_w / (4*N__); + V = sum_w2 / (4*N__) - E*E; + SE = sqrt(V/(4*N__)); + + /* Check that the 2 runs are effectively independent, i.e. check the + * convergence ratio. By combining the 2 runs we have 4 more times samples, + * the standard deviation must be thus devided by 2 while the estimate must + * be compatible with the right value regarding the new error */ + CHK(eq_eps(E, 100000, 3*SE)); + CHK(eq_eps(SE, mc_global.shadowed.SE / 2, SE*1.e-2)); + /* Free data */ CHK(ssol_instance_ref_put(heliostat1) == RES_OK); CHK(ssol_instance_ref_put(target1) == RES_OK); @@ -210,6 +249,7 @@ main(int argc, char** argv) CHK(ssol_material_ref_put(v_mtl) == RES_OK); CHK(ssol_device_ref_put(dev) == RES_OK); CHK(ssol_estimator_ref_put(estimator) == RES_OK); + CHK(ssol_estimator_ref_put(estimator2) == RES_OK); CHK(ssol_scene_ref_put(scene) == RES_OK); CHK(ssp_rng_ref_put(rng) == RES_OK); CHK(ssol_spectrum_ref_put(spectrum) == RES_OK);