moments

Native moment substrate for exact row-additive linear screens.

ABI

  • n4m_moments_compute(ctx, X, Y, out_result)

  • n4m_moments_subset_compute(ctx, X, Y, row_indices, n_indices, out_result)

  • n4m_moments_subtract(ctx, lhs, rhs, out_result)

All outputs are returned through n4m_method_result_t.

Outputs

Double matrices:

  • x_sum (1, p), y_sum (1, q)

  • xtx (p, p), xty (p, q), yty (q, q) raw moments

  • x_mean (1, p), y_mean (1, q)

  • cxx (p, p), cxy (p, q), cyy (q, q) centered moments

Scalars:

  • n_samples

  • n_features

  • n_targets

Exact Fold Subtraction

The raw buffers are additive over rows. A train fold can therefore be computed as:

  1. all = n4m_moments_compute(X, Y)

  2. heldout = n4m_moments_subset_compute(X, Y, heldout_indices)

  3. train = n4m_moments_subtract(all, heldout)

n4m_moments_subtract subtracts only raw sums/products and then recomputes x_mean, y_mean, cxx, cxy and cyy from the remaining row count. This is the important train-only centering invariant for PLS/Ridge screening.

Python

The grouped facade is available as n4m.moment. It intentionally uses the singular name so the historical n4m.moments(...) function stays callable.

import n4m.moment as moment

stats = moment.moments(X, y)
screen = moment.sweep_run(X, y, heads=("ridge",))
ridge_model = moment.NativeRidgeRegressor(alpha=0.1).fit(X, y)
y_hat = ridge_model.predict(X_test)
inventory = moment.available_methods()
import n4m

stats = n4m.moments(X, y)
subset = n4m.moments(X, y, row_indices=[0, 3, 5])
train = n4m.moments_train_from_heldout(X, y, heldout_indices=[1, 2, 8])

moment.available_methods() returns JSON-safe metadata for the moment surfaces: sufficient statistics, sweep_run, direct Ridge/CPPLS/continuum/ECR heads, reusable direct sklearn wrappers, the AOM/moment fast screen-refit campaign preset and the CPU/CUDA backend recommendation helper. It is an inventory for tooling and documentation, not a model-selection policy.

For broad strict-linear preprocessing screens from the moment namespace, use moment.aom_moment_screen_refit_campaign(...). It is the same function as n4m.aom_moment_screen_refit_campaign: a preset wrapper around aom_chain_screen_refit_campaign with strict moment routes, prefix chunking, split-head Ridge/PLS scoring, PLS GCV-proxy first-pass ranking and exact-CV refit.

The direct sklearn wrappers are:

  • NativeRidgeRegressor

  • NativeCPPLSRegressor

  • NativeContinuumRegressionRegressor

  • NativeECRRegressor

They replay the native MethodResult train predictions from input-space coefficients plus an intercept and can predict on new X without re-running a screen.

The preconfigured AOM/moment screen-refit estimators are also re-exported from n4m.moment:

  • NativeAOMMomentScreenRefitRegressor

  • NativeAOMMomentPLSScreenRefitRegressor

  • NativeAOMMomentPLSExactScreenRefitRegressor

  • NativeAOMMomentRidgeScreenRefitRegressor

These are the reusable estimator counterparts to moment.aom_moment_screen_refit_campaign: they screen strict-linear preprocessing chains, exact-refit retained candidates, then build a final-only winner model with folded input coefficients for prediction on new spectra.

Winner reuse helpers from the same workflow are available without leaving the moment namespace:

  • moment.aom_screen_refit_candidate_pool(report)

  • moment.aom_refit_execution_plan(report)

  • moment.aom_refit_candidates(X, y, rows, ...)

  • moment.aom_chain_fixed_fit_run(X, y, chain, ...)

  • moment.NativeAOMFixedCandidateRegressor.from_refit_report(report)

Audit and report helpers are exposed from the same namespace:

  • moment.build_aom_strict_chain_grid(...)

  • moment.decode_aom_chains(report)

  • moment.aom_candidate_table(report)

  • moment.aom_evaluate_candidates(X_train, y_train, X_eval, y_eval, rows, ...)

  • moment.aom_candidate_operator_summary(report_or_rows)

  • moment.aom_candidate_route_summary(report_or_rows)

  • moment.aom_candidate_rank_diagnostics(report_or_rows)

  • moment.aom_candidate_report_records(report_or_rows)

  • moment.aom_save_candidate_report(path, report_or_rows)

  • moment.aom_load_candidate_report(path)

aom_evaluate_candidates is the explicit holdout audit path: it refits decoded candidate rows on the caller’s train split and reports CV-vs-eval rank fields. aom_candidate_route_summary reports whether retained rows were scored through dense, banded or structured operator moments, or through the materialized fallback, by head and by chain. When a campaign/refit report contains aggregate counters, it also returns reported_total so the full screen/refit coverage can be audited even when only top-k rows are retained. The save/load helpers preserve decoded chains for offline comparison and later winner replay. These helpers operate on explicit candidate/report rows and do not add any dataset-name routing.

Backend

The default build accumulates in F64 on CPU. In CUDA-enabled builds the Gram products (X'X, X'Y, Y'Y) use the existing compile-time linalg dispatch to cuBLAS. This is a reusable moment substrate, not yet the fused batched CUDA operator-chain sweep.

For a route smoke of the Python facades on one GPU:

CUDA_VISIBLE_DEVICES=0 python benchmarks/cross_binding/aom_moment_cuda_facade_smoke.py

The smoke uses n4m.moment and n4m.aom through the CUDA build and asserts that wide PLS1 screens report CUDA-device moment CV fits rather than host or materialized PLS CV fits.