https://mooseframework.inl.gov
Loading...
Searching...
No Matches
MooseRandomPerturbation.h
Go to the documentation of this file.
1//* This file is part of the MOOSE framework
2//* https://mooseframework.inl.gov
3//*
4//* All rights reserved, see COPYRIGHT for full restrictions
5//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6//*
7//* Licensed under LGPL 2.1, please see LICENSE for details
8//* https://www.gnu.org/licenses/lgpl-2.1.html
9
10#pragma once
11
12#include "DataIO.h"
13#include "MooseError.h"
14
15#include <cstdint>
16
33{
34public:
43 MooseRandomPerturbation(uint64_t seed, unsigned int n, unsigned int rounds = 8);
44
55 uint32_t permute(uint32_t x) const;
56
65 uint32_t invert(uint32_t y) const;
66
67private:
76 uint32_t permutePadded(uint32_t x) const;
77
84 uint32_t invertPadded(uint32_t y) const;
85
97 uint32_t roundFunction(uint32_t half, unsigned int round) const;
98
105 static unsigned int ceilLog2(uint32_t n);
106
114 static uint32_t mix32(uint32_t x);
115
117 const uint32_t _k0;
119 const uint32_t _k1;
121 const unsigned int _n;
123 const unsigned int _half_bits;
125 const uint32_t _half_mask;
127 const unsigned int _rounds;
128
129 // for restart capability
130 friend void dataStore<MooseRandomPerturbation>(std::ostream &, MooseRandomPerturbation &, void *);
131};
132
133template <>
134inline void
135dataStore(std::ostream & stream, MooseRandomPerturbation & v, void * context)
136{
137 uint64_t seed = (static_cast<uint64_t>(v._k1) << 32) | v._k0;
138 dataStore(stream, seed, context);
139 dataStore(stream, v._n, context);
140 dataStore(stream, v._rounds, context);
141}
142
143template <>
144inline void
145dataStore(std::ostream & stream, std::unique_ptr<MooseRandomPerturbation> & v, void * context)
146{
147 dataStore(stream, *v, context);
148}
149
150template <>
151inline void
152dataLoad(std::istream & stream, std::unique_ptr<MooseRandomPerturbation> & v, void * context)
153{
154 uint64_t seed;
155 unsigned int n, rounds;
156 dataLoad(stream, seed, context);
157 dataLoad(stream, n, context);
158 dataLoad(stream, rounds, context);
159 v = std::make_unique<MooseRandomPerturbation>(seed, n, rounds);
160}
void dataLoad(std::istream &stream, std::unique_ptr< MooseRandomPerturbation > &v, void *context)
void dataStore(std::ostream &stream, MooseRandomPerturbation &v, void *context)
Generates a keyed pseudo-random permutation of the integers [0, n) using a balanced Feistel network.
const uint32_t _k0
Lower 32 bits of the seed, used as the first subkey in the round function.
const unsigned int _n
Size of the permutation domain [0, n)
uint32_t invert(uint32_t y) const
Recover the original index from a permuted value, i.e.
const uint32_t _k1
Upper 32 bits of the seed, used as the second subkey in the round function.
const unsigned int _half_bits
Number of bits in each Feistel half-block: ceil((ceil(log2(n)) + 1) / 2)
const unsigned int _rounds
Number of Feistel rounds to apply per permute/invert call.
static uint32_t mix32(uint32_t x)
Bijective 32-bit avalanche hash (finalizer from Murmur3 / degski hash).
static unsigned int ceilLog2(uint32_t n)
Return the number of bits needed to represent values in [0, n-1], i.e.
const uint32_t _half_mask
Bitmask of width _half_bits, used to keep half-block arithmetic in range.
uint32_t permute(uint32_t x) const
Map x to its permuted index in [0, n).
uint32_t permutePadded(uint32_t x) const
Apply one full pass of the balanced Feistel network over the padded domain [0, 2^(2*half_bits)).
uint32_t roundFunction(uint32_t half, unsigned int round) const
Keyed round function F(half, round) used in each Feistel step.
uint32_t invertPadded(uint32_t y) const
Invert one full pass of the Feistel network by running rounds in reverse.