Files
smoothlife/docs/historical-options.md

294 lines
17 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Retained historical options
## 1. Policy and scope
There is no legacy engine, compatibility profile, legacy preset format, or migration mode. Exactly three localized choices are retained:
```text
Rk4RelaxationReference::StepOrigin
FftAlgorithm::LegacyPackedUnitary
SphereModel::Legacy
```
Their counterparts are the new defaults:
```text
Rk4RelaxationReference::StageState
FftAlgorithm::Standard
SphereModel::Corrected
```
The three settings are independent and affect only the subsystem named by their type. Selecting one must not change seeds, initializers, curves, kernels, scheduling, another option, or unrelated defaults. A configuration must not offer a global `legacy`, `compatibility`, or version-emulation switch.
Only newly authored presets are supported. The project does **not** support, capture, bundle, import, deduplicate, or migrate rows from any legacy preset catalogue. A new preset may explicitly select one of the three options, but that does not make the preset a migrated legacy preset.
Safe deterministic infrastructure always applies: all storage is initialized, updates ping-pong, dot products are clamped before `acos`, kernels have complete contract-defined support except for the explicitly retained Legacy sphere stencil, and invalid/unsupported requests fail rather than falling back.
`docs/model-contract.md` is the mathematical authority. This document defines the historical deltas and their provenance.
## 2. Applicability matrix
| Type | Value | Default | Applicable only to | Invalid elsewhere |
| --- | --- | --- | --- | --- |
| `Rk4RelaxationReference` | `StageState` | yes | planar Relaxation+RK4 | field must be absent |
| | `StepOrigin` | no | planar Relaxation+RK4 | field must be absent |
| `FftAlgorithm` | `Standard` | yes | planar and multiscale convolution | variant must reject unsupported value |
| | `LegacyPackedUnitary` | no | supported GPU planar/multiscale FFT | CPU/unsupported GPU request fails |
| `SphereModel` | `Corrected` | yes | sphere variant | field absent outside sphere |
| | `Legacy` | no | sphere variant | field absent outside sphere |
An option is structurally absent when inapplicable, not accepted and ignored. Any option change invalidates AB derivative history. Exact checkpoints include every applicable choice in their validated arithmetic descriptor.
## 3. `Rk4RelaxationReference::StepOrigin`
### 3.1 Exact semantic delta
Let `A0` be the state at the beginning of one RK4 step. Intermediate states are still formed and clamped exactly as in the ordinary RK4 contract, and every `S(Yj)` is recomputed from that clamped stage:
```text
k1 = S(A0)-A0
Y2 = clamp01(A0 + dt*k1/2)
k2 = S(Y2)-A0
Y3 = clamp01(A0 + dt*k2/2)
k3 = S(Y3)-A0
Y4 = clamp01(A0 + dt*k3)
k4 = S(Y4)-A0
next = clamp01(A0 + dt*(k1+2*k2+2*k3+k4)/6)
```
Only the subtraction reference differs. Neighborhoods and targets are never evaluated from `A0` in place of the stage. The default `StageState` instead subtracts `Y2`, `Y3`, and `Y4` from the corresponding targets.
### 3.2 Constraints
- Valid only for Relaxation dynamics with RK4 integration.
- It has no meaning for Discrete, Growth, Euler, AB3, multiscale composition, sphere, or delayed time.
- Every stage and final clamp remains mandatory.
- Curves and targets may overshoot; this option introduces no additional clamp.
- Switching the value invalidates AB history even though a valid configuration cannot simultaneously use AB3. This keeps the global invalidation policy uniform.
### 3.3 Retained versus rejected behavior
Retained: the historical use of the step-origin state as the relaxation subtraction reference at stages 24. Source evidence: `SmoothLife/main.cpp:2603-2611,2968-2976` (SHA-256 `26b21bfa7fb262f02f5eec4c2615aa501639471ccebce33b2abeb4fb6ee02e58`).
Rejected: stale neighborhoods, unclamped RK stages, implicit timestep changes, numeric mode aliases, and carrying the selector in configurations where it is ignored.
## 4. `FftAlgorithm::LegacyPackedUnitary`
### 4.1 Exact semantic delta
This option selects the complete operation-ordered binary32 algorithm in `model-contract.md` section 6.2:
- adjacent x samples are packed as real/imaginary pairs;
- x spectra contain `Nx/2+1` complex values;
- integer bit reversal and radix-2 stage order are fixed;
- each butterfly is scaled by binary32 `1/sqrt(2)`;
- forward/inverse real-complex conversions are fixed;
- remaining dimensions use full unitary complex transforms;
- spectral multiplication applies `sqrt(sample_count)/kernel_sum` before inverse stages;
- fixtures freeze every plan, stage, conversion, spectrum, and convolution with the stated bit-exact/absolute-relative tolerances.
The option changes the convolution algorithm and its explicitly retained f32 arithmetic. It does not change sampled kernel values, kernel support, normalization intent, rule evaluation, dynamics, integration, state clamp points, or initializer.
### 4.2 Constraints and failure behavior
- Valid only for planar and multiscale convolution.
- Every active extent is a power of two; `Nx` is even and at least 2.
- It is a GPU application backend. The scalar CPU implementation exists only as a stage oracle and is not a selectable simulation backend.
- The GPU must provide the required binary32 operations, deterministic ping-pong resources, half-spectrum storage, and validated plan limits.
- A CPU request, unsupported shape, unsupported GPU, failed shader/resource creation, or failed algorithm validation is a configuration/runtime error. It must never silently select `Standard`.
- Kernel sums are computed from the same complete sampled kernels as Standard. A zero or non-finite sum is an error.
- The semantic oracle compares results in f64. A production GPU may retain f32 values through the common rule/integration pipeline and must satisfy the documented f32 backend tolerances; ordinary execution requires no readback or widening.
### 4.3 Retained versus rejected behavior
Retained: packed adjacent-real storage, half-width x spectra, historical bit-reversal/twiddle stages, unitary butterflies, real/complex conversion, and matching `sqrt(V)/kernel_sum` correction. Primary evidence is `SmoothLife/main.cpp:1442-1967` (SHA-256 `26b21bfa7fb262f02f5eec4c2615aa501639471ccebce33b2abeb4fb6ee02e58`) and the packed FFT shaders listed in section 7.
Rejected:
- treating this as a whole-application compatibility mode;
- incomplete or connected-component-cutoff kernels;
- old OpenGL compatibility syntax;
- shader lookup relative to the process working directory;
- framebuffer/texture feedback;
- uninitialized plans or textures;
- resource leaks or allocation during steady-state passes;
- silent CPU or Standard fallback;
- permitting compiler FMA/reassociation to redefine the stage oracle.
## 5. `SphereModel::Legacy`
### 5.1 Shared safe geometry
Legacy uses the six face order, face frames, `K×K` active cells, `R=K/2`, center directions, exact cell areas, clamped-dot geodesic distance, and common rule curves from `model-contract.md` section 8. `K` must be even. Active arrays are always initialized, and commits ping-pong.
The input radius is `ra_planar`; validate
```text
ra_planar > 0
ceil(2*ra_planar) <= K
```
The second condition is mandatory and is intentionally specific to Legacy. It ensures its doubled-planar-radius face-local search and side gutters fit one face. Convert radii exactly as
```text
ri_planar = ra_planar/3
ri = R*acos(1-ri_planar²/(2R²))
ra = R*acos(1-ra_planar²/(2R²))
```
Both transition widths are `1`. The `ceil(2*ra_planar)<=K` constraint implies valid conversion arguments; they must still be validated as finite.
### 5.2 Face-local stencil and side gutters
Legacy does not perform corrected all-face enumeration. Its conceptual atlas is `18K×3K`: face `f` owns a `3K×3K` tile, and its active rectangle is `[3fK+K,3fK+2K) × [K,2K)`. The four adjacent `K×K` rectangles are side gutters copied from edge-neighbor active faces with rotation/reflection; the four corner `K×K` rectangles remain deterministically masked zero. Persistent atlas storage is not required, but candidate resolution must be equivalent to this geometry.
For each center cell `(face,x,y)`, let
```text
h = ceil(2*ra_planar)
dx,dy ∈ {-h,...,+h}
x' = x+dx
y' = y+dy
```
Enumerate candidates in `dy` then `dx` order. Resolve each candidate as follows:
1. If `0≤x'<K` and `0≤y'<K`, sample `(face,x',y')`.
2. If both x and y are outside, the candidate belongs to a diagonal/corner sector and is **masked**: it contributes neither numerator nor any sampled weight. This deterministic zero mask replaces undefined corner atlas contents.
3. If exactly one coordinate is outside, resolve it through that edge's side gutter.
The side-gutter transform is normative. Define extended face coordinates
```text
s = 2*(x'+0.5)/K - 1
t = 2*(y'+0.5)/K - 1
```
For one crossed edge, form a cube-surface vector `q`:
```text
s > 1: δ=s-1; q=+u_axis + (1-δ)*normal + t*v_axis
s < -1: δ=-1-s; q=-u_axis + (1-δ)*normal + t*v_axis
t > 1: δ=t-1; q=+v_axis + (1-δ)*normal + s*u_axis
t < -1: δ=-1-t; q=-v_axis + (1-δ)*normal + s*u_axis
```
The destination face is the one whose normal is the first signed axis term (`±u_axis` or `±v_axis`). With that destination's fixed frame, compute
```text
sd = q·destination_u_axis
td = q·destination_v_axis
xd = clamp(floor((sd+1)*K/2), 0, K-1)
yd = clamp(floor((td+1)*K/2), 0, K-1)
```
and sample destination active cell `(xd,yd)`. The clamp resolves exact edge arithmetic only; it does not fill a corner sector. Each stencil offset contributes independently even if finite discretization maps two offsets to the same destination cell. Side gutters are derived from initialized active arrays on every evaluation; they are not persistent undefined storage.
This local square is the entire Legacy search stencil. It is not expanded to capture transition weights beyond `h`, and it never follows a second edge into a masked diagonal sector. These omissions are retained characteristics of this option.
### 5.3 Accumulation and analytic normalization
For each resolved candidate `j`, compute the geodesic distance from the center direction to the resolved active-cell direction and evaluate
```text
KD(r)=1-L(r;ri,1)
KR(r)=L(r;ri,1)*(1-L(r;ra,1))
```
Accumulate `cell_area(j)*weight*A(j)` in stencil order. Masked candidates contribute nothing. Normalize with analytic spherical cap areas, not actual sampled denominators:
```text
cap(r) = 2πR²*(1-cos(r/R))
M = Σ_j cell_area(j)*KD(distance)*A(j) / cap(ri)
N = Σ_j cell_area(j)*KR(distance)*A(j) / (cap(ra)-cap(ri))
```
The denominators must be finite and strictly positive. They intentionally ignore transition-profile area, cell sampling, duplicate gutter mappings, and masked sectors. Consequently Legacy is not required to preserve a constant field, and center/edge/corner results may differ. Do not “correct” those differences while this option is selected.
Both update modes remain exact:
```text
Direct: next = clamp01(S)
Smooth: next = clamp01(A + 0.1*(2*S-1))
```
The geodesic sphere-overlay initializer is shared with Corrected. It paints all six active arrays globally across seams and corners before the Legacy gutter view is derived; no historical atlas garbage is reproduced.
### 5.4 Corrected comparison
`SphereModel::Corrected` differs in all of the following as one coherent model:
- globally enumerates all six active arrays for every center;
- includes every nonzero geodesic support sample, including seams and corners;
- has no side-gutter search limit or corner mask;
- uses actual per-center `Σ(cell_area*kernel_weight)` for disk and ring;
- preserves every finite constant field (up to specified arithmetic tolerance);
- does not require `ceil(2*ra_planar)<=K`, although its general radius/domain validation still applies.
Mixing corrected enumeration with analytic normalization, or Legacy masking with sampled normalization, is forbidden. There are exactly two coherent sphere models, not independent toggles for geometry and normalization.
### 5.5 Retained versus rejected behavior
Retained: face-local direct stencil, four side gutters, deterministic masked diagonal/corner sectors, planar-to-geodesic radius conversion, analytic cap normalization, Direct replacement, and fixed-`0.1` Smooth update. Source evidence: `SmoothLifeSphere/main.cpp:351-858,1368-1392` (SHA-256 `c770fb36c562135d4bc65aeae36d71ae725286b05aa0ee37f92b6e6f0ddf8b1e`) and `SmoothLifeSphere/program.frag:110-162` (SHA-256 `037da34db6a050422c372bb458c78553df5ca00e22a26e1ced455f0007c6ce21`).
Rejected:
- uninitialized gutter or corner texels;
- nondeterministic diagonal ownership;
- sampling from a texture while rendering into it;
- unclamped `acos` arguments;
- out-of-range stencils or accepting `ceil(2*ra_planar)>K`;
- preserving atlas memory layout as public state;
- using atlas behavior in Corrected;
- sphere-specific random-number streams or seam-clipped initializers.
## 6. Behaviors with no historical option
The following are permanently rejected rather than configurable:
| Rejected behavior | Contract replacement |
| --- | --- |
| historical kernel connected-component cutoff | complete sampled nonzero support and diagnostics |
| undefined AB derivative buffers | Euler, then AB2, then AB3 startup; authoritative invalidation |
| experimental numeric dynamics modes 3/4 | named Discrete, Growth, Relaxation only |
| stale chained multiscale fields | recompute from the required stage/snapshot |
| additive mode-0 multiscale response | Discrete rejected until a target aggregator is specified |
| undefined multiscale relaxation source | sequential stage or shared-snapshot `A0` reference |
| multiscale texture feedback | safe snapshot/ping-pong evaluation |
| delayed-time head anomaly | `head=next overwrite`, `latest=head-1`, causal nearest layer |
| gradual or undefined delayed-history initialization | one periodic box field replicated to all 16 layers |
| platform `rand()` behavior | exact seeded ChaCha12 stream |
| seam-clipped planar/sphere initialization | periodic splats and global geodesic overlays |
| undefined state, atlas, texture, or framebuffer contents | explicit initialization everywhere |
| legacy scheduling quirks | fixed deterministic simulation scheduling |
| legacy presets/catalogues/importers | newly authored presets only; no capture or migration |
Discovering that a retired implementation behaved differently does not create a fourth option. A change requires an explicit contract revision, rationale, fixtures, and provenance update.
## 7. Provenance and authority trail
The checked-in planning record froze which source-observed behaviors remain selectable. The references below are provenance evidence, not runtime inputs and not competing implementation specifications.
Legacy source-relative paths below are rooted at `/home/fpasqua/Nextcloud/VecchiProgetti/SmoothLifeAll/`; hashes cover complete file bytes. They are evidence only, and implementation never opens that root.
| Topic | Provenance source | Complete-file hash | Relevant range |
| --- | --- | --- | --- |
| Step-origin subtraction | `SmoothLife/main.cpp` | SHA-256 `26b21bfa7fb262f02f5eec4c2615aa501639471ccebce33b2abeb4fb6ee02e58` | 26032611, 29682976 |
| Packed plans/dispatch/correction | `SmoothLife/main.cpp` | SHA-256 `26b21bfa7fb262f02f5eec4c2615aa501639471ccebce33b2abeb4fb6ee02e58` | 14421967 |
| Packed butterfly/tangle operations | `SmoothLife/shaders/fft2D.frag` | SHA-256 `da1d4af18e4b6340a936a036ed010e7e03b3d548d4925f386c26f3fa310af99f` | 153 |
| Packed real/complex copies | `SmoothLife/shaders/copybufferrc2D.frag`; `copybuffercr2D.frag` | SHA-256 `5c325aaf44b5dfb6dd2f2cc1f831596cae1d61f1259bbafbdc5ddb55050e6914`; `fb26244b12c6bad90fa84c9e784e72d409d024d1e66360fa7d0209c99059ab00` | 113; 122 |
| Sphere directions/areas/side table | `SmoothLifeSphere/main.cpp` | SHA-256 `c770fb36c562135d4bc65aeae36d71ae725286b05aa0ee37f92b6e6f0ddf8b1e` | 351858 |
| Sphere radius setup/frame loop | `SmoothLifeSphere/main.cpp` | same SHA-256 | 12201506 |
| Sphere stencil/rule/update | `SmoothLifeSphere/program.frag` | SHA-256 `037da34db6a050422c372bb458c78553df5ca00e22a26e1ced455f0007c6ce21` | 1162 |
| Contract decisions | `plans/00_model_contract_and_historical_options.md` | Git blob SHA-1 `d277a98d3c34799903bc5036c147df0e17b7fc0d` | 109170, 206236 |
| Exactly-three policy | `plans/README.md` | Git blob SHA-1 `6e7d79c55989f82ca29673f695e427085e521d9e` | 112137 |
No retired source tree is needed to interpret these options, and no old executable or preset catalogue is an oracle. Normative precedence is:
1. `docs/model-contract.md` for shared mathematics and arithmetic;
2. this document for the three historical deltas and their constraints;
3. checked-in fixtures for concrete values, with discrepancies resolved by updating documentation and fixtures together;
4. plans as provenance and delivery history only.
Future consultation of retired source is permitted only to investigate a concrete documented discrepancy. Any accepted finding must be restated locally as deterministic semantics, accompanied by fixtures and a provenance entry; merely citing external code is insufficient.