NSQ Validation Report#
This page summarizes the non-sequential (NSQ) engine’s validation suite
(tests/nonsequential/validation/), run in CI alongside the rest of the
test suite. It exists so a user integrating NSQ into their own QA process
has a single place pointing at exactly what is checked, how, and to what
tolerance – rather than having to read test source to find out.
Closed-form analytic benchmarks#
Each benchmark traces a scene whose answer is known exactly (or to a well-defined statistical tolerance) from closed-form physics, independent of the NSQ engine itself.
Benchmark |
Asserted quantity |
Module |
|---|---|---|
Point source -> small flat patch |
Exact inverse-square law, \(E = F / (4\pi d^2)\) |
|
Small Lambertian disc -> parallel plane |
\(\cos^4\theta\) off-axis falloff |
|
Uncoated plane-parallel window |
Total transmittance incl. all internal reflections: \(T = 2n/(n^2+1)\) |
|
Single interface, swept incidence angle |
Unpolarized Fresnel \(R_\text{unpol}(\theta)\) vs. the analytic curve |
|
Total internal reflection |
Sharp cutoff at \(\theta_c = \arcsin(n_2/n_1)\) |
|
Absorbing slab |
Beer-Lambert \(\exp(-4\pi k L/\lambda)\), swept over \(k\) and \(L\) |
|
Thin lens |
Focal spot sharpest near the paraxial thin-lens prediction |
|
AR-coated interface |
Reflectance/transmittance match |
|
Deliberately deferred, not silently missing:
Prism at minimum deviation. Requires a two-plane wedge geometry and a minimum-deviation angle search; not yet built. The single-interface Fresnel and TIR benchmarks above already exercise the same underlying refraction code a prism would.
Integrating sphere. Requires a detector patch conformal to a curved wall (a flat
IrradianceDetectortangent to a sphere does not intersect the interior rays correctly) and enough bounce depth / Russian-roulette tuning for near-unity-reflectance convergence. The underlying mechanism (deterministic per-bounce reflectance loss viaReflectiveComponent+ a Lambertian BSDF) is exercised bytest_nsq_coatings.pyand the roulette invariant tests, just not assembled into the full sphere-multiplier benchmark.
Invariants#
Checked as properties that must hold across a family of scenes and settings, rather than against one closed-form number.
Invariant |
Statement |
Module |
|---|---|---|
Energy closure |
|
|
Batch invariance |
Bit-identical results for |
|
Convergence |
Error shrinks as \(N^{-1/2}\) over a swept ray count (fitted exponent \(-0.5 \pm 0.1\)) |
|
Rigid invariance |
A global rotation + translation of the entire scene (via a shared
|
|
Reciprocity |
Swapping a matched-extent Lambertian source and detector transfers the same flux in both directions |
|
Estimator unbiasedness |
|
|
Splitting agreement |
|
|
Sequential agreement |
NSQ matches Optiland’s sequential tracer for singlet/doublet/aspheric systems |
|
Gradient validation#
Finite-difference checks for parameters documented as differentiable.
Beyond the pre-existing coverage (source total_flux, BSDF reflectance,
lens/mirror geometry, detector total_flux), this pass added:
``scatter_fraction`` (D-5). Writing this check caught that D-5 was never actually fixed despite being marked done:
BaseComponentforcedscatter_fractionthrough a barefloat()at construction (detaching any tensor immediately), and neitherRefractiveComponentnorReflectiveComponentapplied a compensating attached weight to either branch of the scatter/specular split. Both are now fixed with the same detached-sample / attached-weight estimator used for the Fresnel branch. Seetest_gradient_scatter_fraction.py.Beer-Lambert ``k`` (D-13).
test_gradient_absorption_k.py.
Existing coverage retained as part of this suite’s contract:
test_nsq_geometric_gradients.py’s assertion that visibility gradients are zero – a known, documented v1 limitation (see NSQ Limitations & Roadmap), not a regression to silently fix here.test_nsq_geometric_gradients.py’sTestDifferentiableParameterContract: every parameter not on the differentiable list raises viaas_detached_paramrather than silently detaching – no third category of dead variables.
Running the suite#
.venv/Scripts/python.exe -m pytest -v tests/nonsequential/validation/
Individual benchmarks are ordinary parametrized pytest tests; failures report which ray count / angle / material combination diverged and by how much, the same as any other test in the suite.