-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Implement Feistel-based permutation for LHS and convert samplers to stateless RNG #32833
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
zachmprince
wants to merge
19
commits into
idaholab:next
Choose a base branch
from
zachmprince:new_latin_sampling
base: next
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
0dbeffe
Implementation of Feistel mixing for pseudo-random perturbation #32194
zachmprince ade07ee
Implementing the Feistel perturbation into Latin hypercube sampling.
zachmprince b3b8551
Converting some of the easy samplers to using stateless RNG
zachmprince 78bd8a7
Removing sampleSetUp dependence of ActiveLearningMonteCarloSampler #3…
zachmprince 2ff398f
Using correct sample index in AdaptiveImportanceSampler #32194
zachmprince 73da1c8
Removing sampleSetUp dependence of ParallelSubsetSimulation #32194
zachmprince 40a8a1f
Removing sampleSetUp dependence in GenericActiveLearningSampler #32194
zachmprince 1000fb6
Removing dependence on sampleSetUp in all parallel MCMC samplers
zachmprince e06941a
Fixing bi-fidelity active learning #32194
zachmprince 2091a88
Removing now unused Sampler methods #32194
zachmprince 5d2f35a
Making sure LHS is executed before requesting samples #32194
zachmprince a4db8ba
Needed to regold dynamic sampler tests because generator advancement …
zachmprince 3f75bdb
Regolding all the tests that use LHS #32194
zachmprince 2294df6
Removing more unneeded sampler methods #32194
zachmprince d498eb1
Error test was hanging due to advancing generators with a ludicrous n…
zachmprince 87c06da
Reducing number of random seeds in MCMC and active learning tests so …
zachmprince b86aa2e
Recruiting AdaptiveImportanceSampler into the executeSetUp fold #32194
zachmprince 2d9487f
Updating subtleties in Sampler doxygen #32194 #32775
zachmprince 79ac28e
Moving MooseRandomPerturbation methods to a source file #32194
zachmprince File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,127 @@ | ||
| //* This file is part of the MOOSE framework | ||
| //* https://mooseframework.inl.gov | ||
| //* | ||
| //* All rights reserved, see COPYRIGHT for full restrictions | ||
| //* https://github.com/idaholab/moose/blob/master/COPYRIGHT | ||
| //* | ||
| //* Licensed under LGPL 2.1, please see LICENSE for details | ||
| //* https://www.gnu.org/licenses/lgpl-2.1.html | ||
|
|
||
| #pragma once | ||
|
|
||
| #include "MooseError.h" | ||
|
|
||
| #include <cstdint> | ||
|
|
||
| /** | ||
| * Generates a keyed pseudo-random permutation of the integers [0, n) using a | ||
| * balanced Feistel network. Given the same seed and n, the mapping is fully | ||
| * deterministic and bijective: every input in [0, n) maps to a unique output | ||
| * in [0, n). Different seeds produce statistically independent permutations. | ||
| * | ||
| * Because n need not be a power of two, the Feistel network operates on a | ||
| * padded domain of size 2^(2*half_bits) >= n and uses cycle-walking: if the | ||
| * raw output falls outside [0, n) it is re-applied until a valid index is | ||
| * reached. This guarantees termination because the padded permutation is | ||
| * itself a bijection and n > 0 ensures at least one valid output exists. | ||
| * | ||
| * The permutation is also invertible via invert(), which runs the Feistel | ||
| * rounds in reverse order. | ||
| */ | ||
| class MooseRandomPerturbation | ||
| { | ||
| public: | ||
| /** | ||
| * Construct a permutation of [0, \p n) keyed by \p seed. | ||
| * | ||
| * @param seed 64-bit seed; split into two 32-bit subkeys for the round function. | ||
| * @param n Size of the domain to permute; must be > 0. | ||
| * @param rounds Number of Feistel rounds. More rounds improve mixing at the | ||
| * cost of throughput; 8 is sufficient for sampling applications. | ||
| */ | ||
| MooseRandomPerturbation(uint64_t seed, unsigned int n, unsigned int rounds = 8); | ||
|
|
||
| /** | ||
| * Map \p x to its permuted index in [0, n). | ||
| * | ||
| * Applies the Feistel network to the padded domain and cycle-walks until | ||
| * the result falls within [0, n). | ||
| * | ||
| * @param x Input index; must satisfy x < n. | ||
| * @return A unique index in [0, n). Calling permute for every x in [0, n) | ||
| * yields each value in [0, n) exactly once. | ||
| */ | ||
| uint32_t permute(uint32_t x) const; | ||
|
|
||
| /** | ||
| * Recover the original index from a permuted value, i.e. invert(permute(x)) == x. | ||
| * | ||
| * Runs the Feistel rounds in reverse order and cycle-walks back into [0, n). | ||
| * | ||
| * @param y Permuted index; must satisfy y < n. | ||
| * @return The unique x in [0, n) such that permute(x) == y. | ||
| */ | ||
| uint32_t invert(uint32_t y) const; | ||
|
|
||
| private: | ||
| /** | ||
| * Apply one full pass of the balanced Feistel network over the padded | ||
| * domain [0, 2^(2*half_bits)). The result may fall outside [0, n); the | ||
| * caller is responsible for cycle-walking. | ||
| * | ||
| * @param x Input value in the padded domain. | ||
| * @return Permuted value in the padded domain. | ||
| */ | ||
| uint32_t permutePadded(uint32_t x) const; | ||
|
|
||
| /** | ||
| * Invert one full pass of the Feistel network by running rounds in reverse. | ||
| * | ||
| * @param y Value in the padded domain produced by permutePadded. | ||
| * @return The original input to permutePadded that produced \p y. | ||
| */ | ||
| uint32_t invertPadded(uint32_t y) const; | ||
|
|
||
| /** | ||
| * Keyed round function F(half, round) used in each Feistel step. | ||
| * | ||
| * Mixes the half-block with both subkeys and a round-dependent constant | ||
| * derived from the golden-ratio fractional bits (0x9e3779b9), then passes | ||
| * the result through a 32-bit avalanche hash (mix32). | ||
| * | ||
| * @param half The half-block value (R in the forward direction). | ||
| * @param round Zero-based round index, used to vary the constant each round. | ||
| * @return Mixed value masked to \p _half_bits width. | ||
| */ | ||
| uint32_t roundFunction(uint32_t half, unsigned int round) const; | ||
|
|
||
| /** | ||
| * Return the number of bits needed to represent values in [0, n-1], i.e. | ||
| * ceil(log2(n)). Returns 0 for n == 1 (no bits needed to index a single element). | ||
| * | ||
| * @param n Must be > 0. | ||
| */ | ||
| static unsigned int ceilLog2(uint32_t n); | ||
|
|
||
| /** | ||
| * Bijective 32-bit avalanche hash (finalizer from Murmur3 / degski hash). | ||
| * Used inside the round function to achieve good bit diffusion. | ||
| * | ||
| * @param x 32-bit input. | ||
| * @return Hashed 32-bit output; the mapping is invertible. | ||
| */ | ||
| static uint32_t mix32(uint32_t x); | ||
|
|
||
| /// Lower 32 bits of the seed, used as the first subkey in the round function | ||
| const uint32_t _k0; | ||
| /// Upper 32 bits of the seed, used as the second subkey in the round function | ||
| const uint32_t _k1; | ||
| /// Size of the permutation domain [0, n) | ||
| const unsigned int _n; | ||
| /// Number of bits in each Feistel half-block: ceil((ceil(log2(n)) + 1) / 2) | ||
| const unsigned int _half_bits; | ||
| /// Bitmask of width _half_bits, used to keep half-block arithmetic in range | ||
| const uint32_t _half_mask; | ||
| /// Number of Feistel rounds to apply per permute/invert call | ||
| const unsigned int _rounds; | ||
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.