plskit 0.1.0

PLS regression with modern inference. Rust implementation; the same engine drives the Python, R, and Julia wrappers.
Documentation

plskit (Rust)

crates.io License: GPL-3.0-or-later

Rust crate for plskit — Partial Least Squares with modern inference (canonical percentile CIs, split_perm, split_nb). This is the canonical implementation: every plskit language wrapper (Python today; R and Julia planned) calls into this crate.

Part of the plskit project — sibling wrappers, shared test corpus, issues, and PRs all live there.

Install

cargo add plskit

Minimum supported Rust version: 1.85.

A 60-second look

use faer::{Col, Mat};
use plskit::{pls1_fit, FitOpts, KSpec};

// Toy data: replace with your own (n × p) X and length-n y.
let x = Mat::<f64>::from_fn(200, 20, |i, j| (i as f64).sin() + (j as f64).cos());
let y = Col::<f64>::from_fn(200, |i| x[(i, 0)] + x[(i, 1)]);

let model = pls1_fit(
    x.as_ref(),
    y.as_ref(),
    KSpec::Fixed(3),
    None,                  // no observation weights
    FitOpts::default(),
)
.expect("fit failed");

println!("β = {:?}", model.beta);

Confirmatory testing, K-selection, and rotation use the same input shape; the public surface is listed below.

Public surface

  • preprocess
  • pls1_fit, pls1_predict
  • pls1_confirmatory_test
  • pls1_find_k_optimal, pls1_find_k_sequence
  • pls1_perm_null
  • pls1_rotation_stability
  • rotate
  • PlsKitError — error type with a stable .code() for programmatic handling

Each function exports its own opt and output types alongside it (FitOpts, KSpec, Pls1Model, ConfirmatoryArgs, RotateOutput, …).

These names mirror the Python (and forthcoming R / Julia) wrappers, so multi-language code is easy to read across the family.

faer types in the public API

The public API uses faer::Mat and faer::MatRef directly. The crate's Cargo.toml pins faer so downstream consumers do not need to manage that dependency themselves; a faer minor bump is treated as a plskit major bump.

Canonical implementation

All numerical computation, randomness, parallelism, and resampling loops live in this crate. The wrappers are thin FFI shells: they convert their language's array types to f64 slices, call into the engine, and wrap the result. If you want bit-near identical results from Python, R, or Julia, this is what they are calling.

Versioning

The engine and each language wrapper carry their own version number, and the same version number always means the same featuresplskit-rs 0.5.0 and plskit (Python) 0.5.0 ship the same API. The Python, R, or Julia version may lag behind the Rust engine while its surface is being built out, but it can never run ahead of it. Releases use vX.Y.Z for the engine and vX.Y.Z-py / -r / -jl for the wrappers.

API wiring (function names, argument names, result fields) is stable across versions; pin the version if you need numerical reproducibility.

Citation

Lenartowicz, P., Plisiecki, H. (2026). Cheap Per-Component Testing for PLS, Stable Under Rotation (Under Review).

License

GPL-3.0-or-later.