# 0.2.0 numerical contracts

## Reference families

Classic Simplex follows Stefan Gustavson's 2012 `grad3`-based 2D/3D/4D
algorithm. The package keeps its own deterministic seeded permutation, so its
Classic values are regression vectors for that permutation rather than values
from Gustavson's fixed reference permutation. In 0.2.0 the 2D implementation
uses the canonical 12-entry `grad3` projection and normalization factor `70`.

OpenSimplex2 and OpenSimplex2S are ports of FastNoiseLite 1.1.1. The test suite
contains official-reference values for seed 42 and an independently generated
multi-seed corpus. The extra corpus was generated by compiling the official
FastNoiseLite 1.1.1 C++ header with frequency `1.0`:

| algorithm | seed | coordinate | official f32 value |
| --- | ---: | --- | ---: |
| OpenSimplex2 2D | 0 | `(-1.25, 3.5)` | `-0.362422585` |
| OpenSimplex2 3D | 1 | `(-1.25, 3.5, 0.75)` | `0.437037081` |
| OpenSimplex2S 2D | -1 / `UInt` max | `(-1.25, 3.5)` | `0.0927135125` |
| OpenSimplex2S 3D | 7 | `(-1.25, 3.5, 0.75)` | `0.825979948` |

MoonBit assertions use a `2e-6` tolerance because the reference API returns
`float` while this package computes with `Double`.

Sources:

- <https://github.com/stegu/perlin-noise/blob/master/src/simplexnoise1234.c>
- <https://github.com/Auburn/FastNoiseLite/tree/v1.1.1>
- <https://github.com/Razaekel/noise-rs/blob/develop/src/noise_fns/generators/fractals/ridgedmulti.rs>

## Input policy

All core sources accept only finite coordinates whose absolute value is at
most `MAX_COORDINATE` (`100000000.0`). Invalid coordinates return NaN. This
explicitly avoids backend-dependent behavior when a floating lattice index no
longer fits the signed 32-bit integer used by the hash path.

Fractal frequency growth can move an otherwise valid input outside that
domain. Callers using many octaves should choose frequency, lacunarity and
coordinates so every sampled octave remains inside the core coordinate limit.
