PallasLFSR128RNG#

class brainevent.PallasLFSR128RNG(seed)#

Combined LFSR random number generator (LFSR128).

Implements the LFSR128 algorithm, an extension of the LFSR family of Linear Feedback Shift Register random number generators. The algorithm combines four independent LFSRs with expanded state to produce high-quality pseudorandom numbers with a very long period of approximately 2^128.

Parameters:

seed (int) – An integer used to initialize the four-component state. The seed is diversified using additive constants and bitwise transformations to produce distinct starting values for each component.

See also

PallasLFSR88RNG

Three-component variant with period ~2^88.

PallasLFSR113RNG

Four-component variant with period ~2^113.

LFSRBase

Abstract base class defining the LFSR interface.

Notes

The LFSR128 algorithm uses four Tausworthe generators with customized shift and mask parameters:

  • Component 1: shift (7, 9), mask 0xFFFFFFFE, left-shift 15

  • Component 2: shift (5, 23), mask 0xFFFFFFF0, left-shift 6

  • Component 3: shift (11, 17), mask 0xFFFFFF80, left-shift 8

  • Component 4: shift (13, 7), mask 0xFFFFFFE0, left-shift 10

Each component advances independently, and the final output is the XOR of all four component values.

The seed initialization uses different bitwise transformations (addition, XOR, shift, complement) with distinct constants for each component to ensure diverse starting points even for sequential seed values.

Examples

>>> rng = PallasLFSR128RNG(seed=42)
>>> rand_float = rng.rand()        # Random float in [0, 1)
>>> rand_int = rng.randint()        # Random 32-bit unsigned integer
>>> norm_val = rng.normal(0, 1)     # Value from N(0, 1)
>>> unif_val = rng.uniform(5.0, 10.0)  # Float in [5, 10)
generate_key(seed)[source]#

Initialize the random key of the LFSR128 algorithm.

Creates a 4-element state tuple from the given seed using different bitwise transformations for each component to ensure diverse starting points.

Parameters:

seed (int) – An integer seed value used to initialize the generator state.

Returns:

A tuple of four jnp.uint32 scalars containing the initial state.

Return type:

Tuple[uint32, uint32, uint32, uint32]

Notes

The four components are derived from the seed as follows:

  • s1 = seed + 123

  • s2 = seed ^ 0xFEDC7890

  • s3 = (seed << 3) + 0x1A2B3C4D

  • s4 = ~(seed + 0x5F6E7D8C)

All arithmetic is performed in uint32 to prevent overflow.

Examples

>>> rng = PallasLFSR128RNG.__new__(PallasLFSR128RNG)
>>> key = rng.generate_key(42)
>>> len(key)
4
generate_next_key()[source]#

Generate the next random key and update the internal state.

Computes the next state of the LFSR128 generator by applying customized LFSR transformations to each of the four components of the state.

Returns:

A tuple of four jnp.uint32 scalars containing the new state after one iteration.

Return type:

Tuple[uint32, uint32, uint32, uint32]

Notes

This method mutates the internal _key attribute.

Examples

>>> rng = PallasLFSR128RNG(seed=42)
>>> new_key = rng.generate_next_key()
>>> len(new_key)
4
rand()[source]#

Generate a uniformly distributed random float in [0, 1).

Advances the generator state and converts the resulting integer to a floating-point number by multiplying with 1 / (2^32 - 1).

Returns:

A scalar float32 value in the range [0, 1).

Return type:

Array

See also

randint

Generate a raw 32-bit unsigned integer.

uniform

Generate a float in an arbitrary range.

Examples

>>> rng = PallasLFSR128RNG(seed=42)
>>> value = rng.rand()
randint()[source]#

Generate a uniformly distributed random 32-bit unsigned integer.

Advances the generator state and returns a mixed result of all four components via XOR.

Returns:

A scalar uint32 value in the range [0, 2^32 - 1].

Return type:

Array

See also

rand

Generate a random float in [0, 1).

random_integers

Generate a random integer in a specified range.

Examples

>>> rng = PallasLFSR128RNG(seed=42)
>>> value = rng.randint()
randn(epsilon=1e-10)[source]#

Generate a random number from the standard normal distribution N(0, 1).

Uses the Box-Muller transform to convert two uniform random numbers into a normally distributed value.

Parameters:

epsilon (float) – A small positive value used to clamp the first uniform sample away from zero, preventing log(0). Defaults to 1e-10.

Returns:

A scalar float32 value sampled from N(0, 1).

Return type:

Array

See also

normal

Generate a value from N(mu, sigma).

rand

Generate a uniform float in [0, 1).

Notes

The Box-Muller transform generates two independent standard normal values from two independent uniform values. This implementation returns only the sine component.

References: Box-Muller transform, https://en.wikipedia.org/wiki/Box%E2%80%93Muller_transform

Examples

>>> rng = PallasLFSR128RNG(seed=42)
>>> value = rng.randn()