DOC: make the CustomSampler examples answer to their seed - #1097
Conversation
Both examples build a generator with np.random.default_rng(seed) and drop it, then sample from the process-global np.random. reset_seed is a no-op, so a sampler written by following this page ignores random_seed. The study runs and the numbers look reasonable; only a second run with the same seed shows they were never reproducible. The bivariate generator needs two more things. It caches 1000 samples, so reset_seed has to discard them or the first 1000 draws after a reseed still come from the generator that was replaced. And its refill test compares samples_generated against used_samples, which only becomes true after the cache has run out, so a study longer than the cache silently got short lists: sample(n_samples=1) returns [] at simulation 1001 and dict_generator raises IndexError on [0]. Signed-off-by: thc1006 <84045975+thc1006@users.noreply.github.com>
|
Worth knowing when reviewing this one: the Documentation workflow is scoped to For the record, that run was Happy to open a separate issue about the branch filter if you think docs PRs onto |
Closes #1096.
Pull request type
Checklist
The other three items are removed rather than ticked. Nothing under
rocketpy/ortests/changes, so the suite and the linters have nothing to say about this branch and I did not run them on it. What I did run is the documentation build and the code the page contains, both below.Current behavior
Both
CustomSamplerexamples build a generator and discard it:Nothing is assigned, so the call has no effect, and
samplegoes on drawing from the process-globalnp.random. A sampler written by following this page ignoresrandom_seedentirely. The failure is quiet: the study runs, the numbers look reasonable, and only a second run with the same seed shows they were never reproducible. Nothing in RocketPy seeds the global RNG, so there is no accident that would rescue it.The bivariate generator has two further defects, found while fixing the first.
It caches 1000 samples up front. Even with
reset_seedcorrected, those samples came from the generator that was replaced, so the first 1000 draws after a reseed would still ignore the new seed.Its refill test is
which only becomes true once the cache has already run out, and the slice that follows is not bounded either. A study longer than the cache silently receives short lists:
New behavior
reset_seedkeeps the generator,sampledraws from it, and__init__routes throughreset_seedso construction and reseeding agree. For the bivariate generator,reset_seedalso drops the cache, and the refill covers the shortfall rather than reacting after the fact.Executing the code blocks straight out of the page, before and after:
The last row is the property the shared generator exists for. The measured correlation matches 0.171/sqrt(0.2*0.3) = 0.6981, so splitting the seeding did not split the two wind components.
I ran those checks by parsing the
jupyter-executeblocks out of the.rstand executing them, rather than retyping the classes, so what passed is what the page says.The added
.. warning::is there because the mistake is easy to repeat and produces no error when repeated.Breaking change
Documentation only. No module in
rocketpy/is touched.Additional information
The same mistake was in
tests/fixtures/monte_carlo/custom_sampler_fixtures.pyand is fixed in #1054. This uses the same corrected shape so the two do not drift apart. It is independent of that PR and can go in first or second.Sphinx built clean with the CI settings (
-W --keep-going,DOCS_SKIP_EXECUTE=1): no warning fromcustom_sampler.rst, and the rendered page contains the corrected code with no global draws left.Related: #1093, #1094, #1095, filed from the same review.