Getting started

A 5-minute path to a fitted PLS model in your language of choice.

The shared assumption: X is an (n × p) matrix of predictors and y is an (n,) (or (n × q)) response. Centring is on, scaling defaults to off — the spectroscopy convention.

Python

Install (Python)

# 1. build the C library (or install the wheel when published)
cmake --preset dev-release
cmake --build --preset dev-release --parallel

# 2. install the Python binding
pip install ./bindings/python

Fit a model — sklearn-style

from pls4all.sklearn import PLSRegression

mdl = PLSRegression(n_components=5).fit(X, y)
yhat = mdl.predict(X_test)
score = mdl.score(X_test, y_test)        # R²

The estimator is a real sklearn BaseEstimator — drop it in a Pipeline, GridSearchCV, or any cross-validator.

Fit a model — Python raw

import pls4all

with pls4all.Context() as ctx, pls4all.Config() as cfg:
    cfg.algorithm = pls4all.Algorithm.PLS_REGRESSION
    cfg.solver    = pls4all.Solver.SIMPLS
    cfg.n_components = 5
    model = pls4all.Model.fit(ctx, cfg, X, y)
    yhat  = model.predict(ctx, X_test)
    payload = model.to_bytes()  # raw N4MM bytes; no canonical file extension
    restored = pls4all.Model.from_bytes(ctx, payload)
    yhat_restored = restored.predict(ctx, X_test)
    restored.close()
    model.close()

R

Install (R)

# from the repo's bindings/r/pls4all directory:
install.packages(".", repos = NULL, type = "source")

Fit a model — formula + S3

library(pls4all)
fit  <- pls(y ~ ., data = train_df, ncomp = 5)
yhat <- predict(fit, newdata = test_df)
summary(fit)

Fit a model — R raw dispatcher

res  <- pls4all_method("pls", X, y, n_components = 5)
yhat <- n4m_predict(res, X_test)

The dispatcher covers all 71 methods; switch by changing the first arg (e.g. "sparse_simpls", "cppls", "opls", "cars_select").

MATLAB / Octave

Install (MATLAB / Octave)

% from bindings/matlab/
build_mex                          % produces +n4m/n4m_*_mex.mex
addpath(pwd);                      % make +n4m visible

Fit a model — Statistics-toolbox style

mdl  = n4m.fitrpls(X, y, "NumComponents", 5);
yhat = predict(mdl, Xtest);
mse  = loss (mdl, Xtest, ytest);

Fit a model — MATLAB raw dispatcher

res = n4m.fit("pls", X, y, "NumComponents", 5);
yhat = predict(res, Xtest);

JavaScript / WebAssembly

The WebAssembly binding ships the same surface; see bindings/js. The library is loaded as an ES module:

import * as n4m from '@nirs4all/methods';

await n4m.loadModule();   // loads n4m.wasm
// Raw row-major Float64Array matrices in, typed arrays out (see
// bindings/js/INPUT_CONTRACT.md).
const model = n4m.fitPls({ data: X, rows, cols }, { data: y, rows, cols: 1 }, 5);
const yhat = n4m.predictPls(model, { data: Xtest, rows: rowsTest, cols });

Serialize raw fitted state

# Python slim binding
payload = mdl.to_bytes()
loaded = pls4all.Model.from_bytes(ctx, payload)
assert payload[:4] == b"N4MM"
loaded.close()

N4MM is a raw fitted-model payload behind the C ABI, not a full pipeline bundle. It has no canonical filename extension. Corruption and unsupported N4MM format versions fail; the writer ABI triple is provenance and an ABI difference currently produces a context warning rather than a load failure.

R, MATLAB and JS do not yet expose N4MM model import/export wrappers. The .n4a extension remains reserved for the nirs4all full-pipeline bundle, which has a separate lifecycle and contract.

Next steps