# gizlang:random

a seeded generator (SplitMix64), so a run can be repeated from its seed. `System.entropy()` gives an unpredictable seed.

```gizlang
import * as Random from "gizlang:random";
```

## Types

### `Random`

```gizlang
type Random
```

gizlang:random: a seeded generator (SplitMix64), so a run can be repeated
from its seed. `System.entropy()` gives an unpredictable seed.

Opaque: create and use it through this module's functions.

### `Mt19937`

```gizlang
type Mt19937
```

PyTorch's CPU generator, `torch.Generator("cpu").manual_seed(seed)`: MT19937 as std::mt19937 (32-bit words), so
a program repeats the noise of a PyTorch program with the same seed (as diffusion models' reference pipelines).

Opaque: create and use it through this module's functions.

## Functions

### `newRandom`

```gizlang
function newRandom(seed: u64): Random
```

A fast deterministic generator started from SEED: the same seed gives the same numbers.

### `uniformBelow`

```gizlang
function uniformBelow(value: u64, n: i64): Option<i64> requires n> 0 { const limit = u64(n)
```

Map an independent uniform 64-bit draw into [0,n); rejection requires a
fresh draw from the original source, including OS-backed secure randomness.

Effects: fail.

### `mt19937`

```gizlang
function mt19937(seed: u64): Mt19937
```

A Mersenne Twister (MT19937) started from SEED, as C++ and NumPy start it.

Effects: fail.

## Methods

### `Random.state`

```gizlang
function Random.state(self: Random): u64
```

The exact state for durable continuation and deterministic replay.

### `Random.next`

```gizlang
function Random.next(self: mut Random): u64
```

The next 64 random bits.

Effects: fail.

### `Random.below`

```gizlang
function Random.below(self: mut Random, n: i64): i64 requires n> 0 { let accepted = uniformBelow(self.next(), n)
```

A uniform integer in [0, n), for n > 0, without modulo bias.

Effects: fail.

### `Random.float`

```gizlang
function Random.float(self: mut Random): f64
```

A uniform f64 in [0, 1).

Effects: fail.

### `Mt19937.next`

```gizlang
function Mt19937.next(self: mut Mt19937): u64
```

The next 32 random bits.

Effects: fail.

### `Mt19937.torchNormals`

```gizlang
function Mt19937.torchNormals(self: mut Mt19937, n: i64): Vec<f32>
```

`torch.randn(n)` (float32, n >= 16) on this generator, as PyTorch computes it on an x86 CPU with AVX2: uniforms of
24 bits, then Box-Muller over each 16 (the radius of 1 - u[j], the angle of u[j + 8]) with avx_mathfun's Cephes
log, sine and cosine in f32; when n is not a multiple of 16, the last 16 again from 16 new uniforms. Equal to
PyTorch's within a unit in the last place (its compiler may fuse a multiply and an add).

Effects: fail.

