Parity tolerances

This table records the documented per-pair tolerances between every two reference PLS implementations pls4all cross-checks against. Numbers in bold are the relaxations applied after Codex review of the Phase 0 roadmap.

For cross-algorithm rows the comparator gates on predictions, coefficients, intercept, x_mean, x_scale, y_mean, y_scale only — raw latent matrices (weights_W, loadings_P, y_loadings_Q, rotations_R, scores_T, y_scores_U) are diagnostic when algorithms differ.

Truth-source legend

  • 📐 marks the column (A or B) whose implementation produced the expected values in the corresponding fixture under parity/fixtures/. The pls4all C++ kernel and other binding-side ports are tested for bit-equivalence against that side; the marked column is the library-of-record for the row.

    • For pairs where the producer is pls4all itself (e.g. pls4all-refcpu-vs-pls4all-blas, pls4all-linux-vs-pls4all-macos-arm64), the 📐 sits on column A (the REFERENCE_CPU build) — that build is the deterministic baseline every other build is compared against.

    • For solver-parity rows generated by a NumPy / sklearn / R mirror (e.g. pls4all-numpy-simpls, sklearn/PLSRegression/self_roundtrip, pls-r-oscorespls), the 📐 sits on column A (the generator side).

    • For the bench-AOM_v0-* rows, the 📐 sits on column A — the bench oracle is the canonical AOM reference per user policy.

  • 📜 flags rows whose A/B pair is documented but has no active fixture producer yet (e.g. R-generator stubs still on the roadmap). These rows describe the intended tolerance once the matching fixture is wired up; they are not gating any test today.

  • Unmarked rows are pair-tolerance specifications that don’t yet correspond to a single canonical producer (typically cross-implementation comparisons where neither side is strictly the truth).

This convention mirrors the 📐 icon used in the per-method benchmark dashboards under docs/methods/, sourced from benchmarks/parity_timing/registry.py. The two layers gate different surfaces — JSON fixtures + C++ ctest here, live cross-binding runs there — but both honour the same “registry-declared canonical reference” notion.

Row key

A

B

Variant

Algorithm

abs_tol

rel_tol

Comparison set

Notes

sklearn/PLSRegression/self_roundtrip

📐 sklearn 1.4 PLSRegression

sklearn (round-trip)

regression

NIPALS

1e-15

1e-15

all

sanity

sklearn-vs-pls-kernelpls

sklearn 1.4 PLSRegression

R pls 2.8 plsr(method='kernel')

regression

NIPALS vs kernel

5e-7

1e-6

predictions, coefficients, intercept, x/y mean+scale

cross-algorithm — 📜 documented pair (no active fixture producer)

sklearn-vs-pls-simpls

sklearn 1.4 PLSRegression

R pls 2.8 plsr(method='simpls')

regression

NIPALS vs SIMPLS

1e-5

1e-4

predictions, coefficients, intercept, x/y mean+scale

cross-algorithm — 📜 documented pair (no active fixture producer)

sklearn-vs-mixomics-pls

sklearn 1.4 PLSRegression

mixOmics 6.28 pls

regression

NIPALS

1e-7

1e-7

predictions, coefficients, intercept, x/y mean+scale

mixOmics scales differently — predictions agree; 📜 documented pair (no active fixture producer)

sklearn-vs-nirs4all-simpls

sklearn 1.4 PLSRegression

nirs4all 0.8 SIMPLS

regression

SIMPLS

1e-6

1e-5

predictions, coefficients, intercept, x/y mean+scale

cross-algorithm — 📜 documented pair (no active fixture producer)

pls4all-numpy-preprocessing

📐 NumPy/SciPy preprocessing fixture

pls4all C++ n4m_pipeline_*

preprocessing

identity / center / autoscale / Pareto / SNV / MSC / EMSC / detrend / Savitzky-Golay / Norris-Williams / ASLS / Haar wavelet / OSC / EPO

1e-12

1e-12

transform outputs

operator parity

pls4all-numpy-aom-preprocessing

📐 NumPy soft/hard AOM preprocessing-bank fixture

pls4all C++ internal AOM preprocessing kernel

preprocessing

operator-bank output mixing

1e-10

1e-10

operator outputs, gating weights, mixed transform, operator kind trace

Phase 6a AOM preprocessing parity

bench-AOM_v0-aom-operators

📐 nirs4all/bench/AOM_v0/aompls strict-linear operators

pls4all C++ internal AOM strict operator kernels

AOM

identity / detrend / zero-padded SG / finite difference / Norris-Williams / Whittaker / FCK

1e-10

1e-10

operator transform outputs

Phase 6c/6d bench AOM_v0 operator parity

bench-AOM_v0-aom-selection

📐 nirs4all/bench/AOM_v0/aompls global AOM CV fixture

pls4all C++ internal AOM global-selection kernel

AOM

SIMPLS materialized global selection

1e-8

1e-8

per-operator RMSE curves, best scores, selected operator/component count, predictions

Phase 6b/6c/6d bench AOM_v0 parity; current tranche covers identity, detrend, zero-padded SG, finite difference, Norris-Williams, Whittaker and FCK strict-linear operators

bench-AOM_v0-pop-selection

📐 nirs4all/bench/AOM_v0/aompls POP per-component CV fixture

pls4all C++ internal POP selection kernel

POP

SIMPLS covariance per-component selection

1e-8

1e-8

component candidate scores, prefix scores, selected operator sequence, predictions

Phase 6e bench AOM_v0 parity; intentionally matches bench POP’s historical PLS1 CV residual broadcasting

pls4all-numpy-regression-metrics

📐 NumPy regression metrics fixture

pls4all C++ internal metric kernels

validation

RMSE / MAE / bias / R2 / Q2 / slope / intercept / RPD / RPIQ

1e-12

1e-12

scalar metrics

metric parity

pls4all-numpy-binary-classification-metrics

📐 NumPy binary classification metrics fixture

pls4all C++ internal metric kernels

validation

sensitivity / specificity / balanced accuracy / precision / F1 / MCC / AUC

1e-12

1e-12

scalar metrics

metric parity

pls4all-numpy-classification-extensions

📐 NumPy classification extension fixtures

pls4all C++ internal metric kernels

validation

multiclass macro/micro metrics / one-vs-rest AUC / fixed-bin calibration

1e-12

1e-12

scalar metrics, confusion matrix, calibration bins

extension parity

sklearn/PLSRegression/variable-importance

📐 sklearn 1.4 PLSRegression score/loading formulas

pls4all C++ internal variable-importance kernels

validation

VIP / selectivity ratio

1e-8

1e-8

per-feature vectors

variable importance parity

sklearn/PLSRegression-variable-selection-rankers

📐 sklearn 1.4 PLSRegression score/loading/coefficient formulas

pls4all C++ internal variable-selection rankers

selection

VIP / coefficient magnitude / selectivity ratio

1e-8

1e-8

per-feature scores plus exact top-k indices

deterministic score-desc/index-asc ranker parity

sklearn/PLSRegression-interval-selection-cv

📐 sklearn 1.4 PLSRegression with deterministic k-fold intervals

pls4all C++ internal interval-selection kernel

selection

moving-window / interval CV

1e-8

1e-8

metrics by interval, RMSE vector, exact best interval

contiguous interval scan parity

sklearn/PLSRegression-biPLS-selection

📐 sklearn 1.4 PLSRegression deterministic backward interval elimination

pls4all C++ internal biPLS-selection kernel

selection

backward interval PLS

1e-8

1e-8

interval partition, removal path, RMSE path, best step, selected interval/feature indices

deterministic biPLS parity

sklearn/PLSRegression-siPLS-selection

📐 sklearn 1.4 PLSRegression deterministic exhaustive interval combinations

pls4all C++ internal siPLS-selection kernel

selection

synergy interval PLS

1e-8

1e-8

interval partition, candidate interval matrix, RMSE by combination, best combination, selected interval/feature indices

deterministic siPLS parity

sklearn/PLSRegression-coefficient-stability

📐 sklearn 1.4 PLSRegression over deterministic Monte-Carlo subsets

pls4all C++ internal stability-selection kernel

selection

MCUVE-style coefficient stability

1e-8

1e-8

mean/std coefficients, stability scores, exact top-k indices

Monte-Carlo subset parity

sklearn/PLSRegression-UVE

📐 sklearn 1.4 PLSRegression over deterministic Monte-Carlo subsets plus artificial variables

pls4all C++ internal UVE-selection kernel

selection

UVE artificial-variable threshold

1e-8

1e-8

real/noise stability scores, max-noise threshold, exact selected indices

deterministic SplitMix64 artificial-variable parity

sklearn/PLSRegression-EMCUVE

📐 sklearn 1.4 PLSRegression over deterministic ensemble MC-UVE members

pls4all C++ internal EMCUVE-selection kernel

selection

EMCUVE ensemble vote rule

1e-8

1e-8

mean real stability scores, vote frequencies, noise thresholds, exact selected indices

deterministic ensemble MC-UVE parity

sklearn/PLSRegression-randomization-selection

📐 sklearn 1.4 PLSRegression coefficient scores with deterministic Y permutations

pls4all C++ internal randomization-selection kernel

selection

randomization-test PLS selector

1e-8

1e-8

observed scores, p-values, exceedance counts, exact selected indices

deterministic SplitMix64 permutation parity

sklearn/PLSRegression-SPA-selection

📐 sklearn 1.4 PLSRegression coefficient seed plus NumPy successive projections

pls4all C++ internal SPA-selection kernel

selection

SPA-PLS projection selector

1e-8

1e-8

coefficient scores, selection step scores, exact selected indices

deterministic projection parity

sklearn/PLSRegression-CARS-selection

📐 sklearn 1.4 PLSRegression deterministic exponential-retention CV

pls4all C++ internal CARS-selection kernel

selection

CARS-PLS competitive adaptive reweighted sampling

1e-8

1e-8

coefficient scores by iteration, RMSE path, retained counts, exact selected indices

deterministic CARS parity

sklearn/PLSRegression-RandomFrog-selection

📐 sklearn 1.4 PLSRegression deterministic Random Frog subset walk

pls4all C++ internal Random-Frog-selection kernel

selection

Random Frog PLS inclusion-frequency selector

1e-8

1e-8

global scores, inclusion frequencies, RMSE path, subset sizes, exact selected indices

deterministic Random Frog parity

sklearn/PLSRegression-SCARS-selection

📐 sklearn 1.4 PLSRegression deterministic stability-weighted subsampling CV

pls4all C++ internal SCARS-selection kernel

selection

SCARS-PLS stability competitive adaptive reweighted sampling

1e-8

1e-8

coefficient scores by iteration, stability scores, RMSE path, retained counts, exact selected indices

deterministic SCARS parity

sklearn/PLSRegression-GA-selection

📐 sklearn 1.4 PLSRegression deterministic genetic subset search

pls4all C++ internal GA-selection kernel

selection

GA-PLS population search

1e-8

1e-8

global scores, inclusion frequencies, best/mean RMSE path, best subset sizes, exact selected indices

deterministic GA-PLS parity

sklearn/PLSRegression-Shaving-selection

📐 sklearn 1.4 PLSRegression deterministic recursive coefficient shaving

pls4all C++ internal Shaving-selection kernel

selection

shaving PLS recursive elimination

1e-8

1e-8

coefficient scores by step, RMSE path, retained counts, exact selected indices

deterministic shaving parity

sklearn/PLSRegression-REP-selection

📐 sklearn 1.4 PLSRegression deterministic fixed-count recursive elimination

pls4all C++ internal REP-selection kernel

selection

REP-PLS recursive elimination

1e-8

1e-8

coefficient scores by step, RMSE path, retained counts, removed counts/indices, exact selected indices

deterministic REP parity

sklearn/PLSRegression-IPW-selection

📐 sklearn 1.4 PLSRegression deterministic coefficient reweighting

pls4all C++ internal IPW-selection kernel

selection

IPW-PLS iterative predictor weighting

1e-8

1e-8

score path, weight path, RMSE path, ranking indices, exact selected indices

deterministic IPW parity

sklearn/PLSRegression-ST-selection

📐 sklearn 1.4 PLSRegression deterministic score thresholds

pls4all C++ internal ST-selection kernel

selection

ST-PLS score-threshold selector

1e-8

1e-8

normalized coefficient scores, threshold RMSE path, masks/counts, ranking indices, exact selected indices

deterministic ST-PLS parity

sklearn/PLSRegression-BVE-selection

📐 sklearn 1.4 PLSRegression deterministic backward variable elimination

pls4all C++ internal BVE-selection kernel

selection

BVE-PLS backward elimination

1e-8

1e-8

candidate RMSE matrix, chosen RMSE path, retained counts, removed indices, exact selected indices

deterministic BVE parity

sklearn/PLSRegression-T2-selection

📐 sklearn 1.4 PLSRegression plus plsVarSel-style Hotelling T2 thresholds

pls4all C++ internal T2-selection kernel

selection

T2-PLS loading-weight selection

1e-8

1e-8

T2 scores, UCL per alpha, RMSE path, selected masks/counts, exact selected indices

deterministic T2-PLS parity

numpy/WVC-PLS-selection

📐 NumPy mirror of plsVarSel WVC-PLS numeric-regression WVC2

pls4all C++ internal WVC-selection kernel

selection

WVC-PLS weighted variable contribution

1e-8

1e-8

weights, loadings, WVC score matrix, final scores, exact top-k indices

deterministic WVC-PLS parity

numpy/WVC-PLS-threshold-selection

📐 NumPy WVC-PLS threshold/factor rule over WVC2 scores

pls4all C++ internal WVC-threshold-selection kernel

selection

thresholded/factor WVC-PLS

1e-8

1e-8

final scores, ranked indices, mean score, effective threshold, selected indices

deterministic WVC threshold/factor parity

sklearn/PLSRegression/component-coefficients

📐 sklearn 1.4 PLSRegression prefix coefficient formulas

pls4all C++ internal component coefficient kernels

validation

original-scale coefficients per latent prefix

1e-8

1e-8

component-major coefficient blocks

component-count model selection support

pls4all-python-validation-splits

📐 Python deterministic split fixture

pls4all C++ internal split generators

validation

k-fold / LOO / holdout

exact

exact

train/test index plans

splitter parity

pls4all-python-advanced-validation-splits

📐 Python deterministic split fixture

pls4all C++ internal split generators

validation

external folds / repeated k-fold / Monte-Carlo / Kennard-Stone / SPXY

exact

exact

train/test index plans

advanced splitter parity

sklearn/PLSRegression/kfold-cv

📐 sklearn 1.4 PLSRegression with deterministic k-fold splits

pls4all C++ internal CV engine

validation

NIPALS PLS regression CV

1e-8

1e-8

out-of-sample predictions, aggregate metrics, test index plan

cross-validation parity

pls4all-numpy-simpls-component-cv

📐 NumPy SIMPLS with deterministic k-fold splits

pls4all C++ internal model-selection kernel

validation

SIMPLS component-count CV

1e-8

1e-8

metrics by component, best component count

component selection parity

pls4all-numpy-simpls

📐 pls4all NumPy SIMPLS fixture

pls4all C++ N4M_SOLVER_SIMPLS

regression

SIMPLS

1e-9

1e-9

predictions, coefficients, intercept, x/y mean+scale, latent arrays

solver parity

pls4all-numpy-svd

📐 pls4all NumPy SVD fixture

pls4all C++ N4M_SOLVER_SVD

regression

SVD

1e-9

1e-9

predictions, coefficients, intercept, x/y mean+scale, latent arrays

solver parity

pls4all-numpy-power

📐 pls4all NumPy power-iteration fixture

pls4all C++ N4M_SOLVER_POWER

regression

power PLS

1e-9

1e-9

predictions, coefficients, intercept, x/y mean+scale, latent arrays

solver parity

pls4all-numpy-randomized-svd

📐 pls4all NumPy randomized-SVD fixture

pls4all C++ N4M_SOLVER_RANDOMIZED_SVD

regression

randomized SVD PLS

1e-9

1e-9

predictions, coefficients, intercept, x/y mean+scale, latent arrays

solver parity

sklearn/PLSCanonical/nipals

📐 NumPy mirror of sklearn 1.4 PLSCanonical(algorithm='nipals')

pls4all C++ N4M_ALGO_PLS_CANONICAL + N4M_SOLVER_NIPALS

canonical

NIPALS + canonical deflation

1e-9

1e-9

predictions, coefficients, intercept, x/y mean+scale, latent arrays

algorithm parity

sklearn/PLSCanonical/svd

📐 NumPy mirror of sklearn 1.4 PLSCanonical(algorithm='svd')

pls4all C++ N4M_ALGO_PLS_CANONICAL + N4M_SOLVER_SVD

canonical

SVD + canonical deflation

1e-9

1e-9

predictions, coefficients, intercept, x/y mean+scale, latent arrays

algorithm parity

sklearn/PLSSVD

📐 NumPy mirror of sklearn 1.4 PLSSVD

pls4all C++ N4M_ALGO_PLS_SVD + N4M_SOLVER_SVD

cross-decomposition

direct cross-covariance SVD score model

1e-9

1e-9

transform scores, weights, projection predictions, preprocessing stats

algorithm parity; predict is pls4all latent projection

sklearn/PLSDA-dummy/PLSRegression

📐 sklearn 1.4 PLSRegression on dummy-coded Y

pls4all C++ N4M_ALGO_PLS_DA + N4M_SOLVER_NIPALS

discriminant

PLS-DA dummy-response scores

1e-9

1e-9

predictions, coefficients, intercept, x/y mean+scale, latent arrays

algorithm parity; predictions are continuous class scores

sklearn/PLSRegression-scores-plus-numpy-LDA

📐 sklearn 1.4 PLSRegression scores + NumPy pooled-covariance LDA

pls4all C++ internal PLS-LDA kernel

discriminant

PLS score-space LDA

1e-8

1e-8

predictions, decision scores

classifier parity

sklearn/PLSRegression-scores-plus-numpy-logistic

📐 sklearn 1.4 PLSRegression scores + NumPy baseline multinomial logistic Newton

pls4all C++ internal PLS-logistic kernel

discriminant

PLS score-space logistic

1e-8

1e-8

predictions, decision scores, probabilities, intercepts, coefficients

classifier parity

sklearn/PLSRegression-block-weighted-MBPLS

📐 NumPy block autoscaling + sklearn 1.4 PLSRegression(scale=False)

pls4all C++ internal MB-PLS kernel

regression

block-weighted MB-PLS

1e-8

1e-8

predictions, coefficients, intercept, block weights, x preprocessing stats

multi-block parity

sklearn/PLSRegression-local-window-LWPLS

📐 Gaussian-weighted local PLS on raw rows (λ = max(1, 0.5·n_neighbors)), mirroring nirs4all lwpls.py::_lwpls_predict

pls4all C++ internal LW-PLS kernel

regression

local-window LW-PLS

1e-8

1e-8

predictions, neighbor indices

local model parity; fixture agrees with the C++ core to ~7e-16

pls4all-numpy-opls

📐 pls4all NumPy OPLS1 fixture

pls4all C++ N4M_ALGO_OPLS + N4M_SOLVER_NIPALS

orthogonal

OPLS1 + orthogonal corrections

1e-9

1e-9

predictions, coefficients, intercept, x/y mean+scale, latent arrays

algorithm parity; first score column is predictive, later columns are orthogonal

pls4all-numpy-opls-da-binary

📐 pls4all NumPy OPLS1 fixture on one-column dummy Y

pls4all C++ N4M_ALGO_OPLS_DA + N4M_SOLVER_NIPALS

discriminant

binary OPLS-DA dummy-response scores

1e-9

1e-9

predictions, coefficients, intercept, x/y mean+scale, latent arrays

algorithm parity

pls4all-numpy-opls-da-multiclass

📐 pls4all NumPy multivariate OPLS fixture on one-hot Y

pls4all C++ N4M_ALGO_OPLS_DA + N4M_SOLVER_NIPALS

discriminant

multi-class OPLS-DA common predictive score

1e-9

1e-9

predictions, coefficients, intercept, x/y mean+scale, latent arrays

algorithm parity; one shared predictive subspace

pls4all-numpy-kernelpls

📐 pls4all NumPy kernel PLS fixture

pls4all C++ N4M_SOLVER_KERNEL_ALGORITHM

regression

kernel PLS

1e-9

1e-9

predictions, coefficients, intercept, x/y mean+scale, latent arrays

solver parity

pls4all-numpy-wide-kernelpls

📐 pls4all NumPy wide-kernel PLS fixture

pls4all C++ N4M_SOLVER_WIDE_KERNEL

regression

wide-kernel PLS

1e-9

1e-9

predictions, coefficients, intercept, x/y mean+scale, latent arrays

solver parity

pls-r-oscorespls

📐 NumPy port of R pls oscorespls.fit

pls4all C++ N4M_SOLVER_ORTHOGONAL_SCORES

regression

orthogonal-scores PLS

1e-9

1e-9

predictions, coefficients, intercept, x/y mean+scale, latent arrays

solver parity

pls4all-numpy-pcr

📐 pls4all NumPy PCR fixture

pls4all C++ N4M_ALGO_PCR + N4M_SOLVER_SVD

regression

PCR

1e-9

1e-9

predictions, coefficients, intercept, x/y mean+scale, latent arrays

algorithm parity

sklearn-canonical-vs-mixomics-canonical

sklearn 1.4 PLSCanonical

mixOmics 6.28 pls(mode='canonical')

canonical

NIPALS

1e-7

1e-7

predictions, coefficients, intercept, x/y mean+scale

cross-impl — 📜 documented pair (no active fixture producer)

ropls-opls-vs-nirs4all-opls

ropls 1.34 opls

nirs4all 0.8 OPLS

orthogonal

OPLS-NIPALS

1e-5

1e-4

predictions only

OPLS sign + ordering vary; 📜 documented pair (no active fixture producer)

bench-AOM_v0-vs-pls4all-aom

📐 nirs4all/bench/AOM_v0/aompls

pls4all (Phase 6)

AOM

SIMPLS + operator bank

TBD

TBD

selection curves, selected operators/components, predictions

Source-of-truth is the bench AOM_v0 reference, not the packaged nirs4all model API

pls4all-refcpu-vs-pls4all-blas

📐 pls4all REFERENCE_CPU

pls4all BLAS

any

any

1e-10

1e-9

all

same algorithm, different SGEMM path; fixed reduction order, no FMA

pls4all-refcpu-vs-pls4all-cuda

📐 pls4all REFERENCE_CPU

pls4all CUDA

any

any

1e-9

1e-8

predictions

fp64 GPU drift envelope

pls4all-linux-vs-pls4all-macos-arm64

📐 pls4all REFERENCE_CPU (Linux x86_64)

pls4all REFERENCE_CPU (macOS arm64)

any

any

1e-11

1e-11

all

cross-platform sanity

The tolerance_table_row key in each fixture’s comparison_policy block points to a row by name. The comparator resolves missing per-field tolerances against this row.