Skip to main content

matten_mlprep/
lib.rs

1//! `matten-mlprep` — small, transparent, deterministic preprocessing helpers for
2//! [`matten::Tensor`].
3//!
4//! This companion crate (RFC-024, RFC-028) prepares numeric tensors for use with
5//! external tools. It is **not** an ML framework: there is no model training, no
6//! autograd, no optimizer, and no hidden randomness. Every function is a pure,
7//! deterministic transform you can reason about. It depends only on core
8//! `matten` (no default features) — no `ndarray`, no `candle`, no `rand`.
9//!
10//! # Convention
11//!
12//! All functions operate on **rank-2** tensors with `rows = samples` and
13//! `columns = features`. A non-2D tensor is rejected; there is no silent
14//! transposition.
15//!
16//! # Functions
17//!
18//! - [`standardize_columns`] — per-column z-score (population std).
19//! - [`minmax_scale_columns`] — per-column scaling to `[0, 1]`.
20//! - [`add_bias_column`] — prepend a constant `1.0` intercept column.
21//! - [`train_test_split`] — ordered, deterministic row split.
22//! - [`train_test_split_seeded`] — seeded, shuffled, deterministic row split (RFC-077).
23//!
24//! ```
25//! use matten::Tensor;
26//! use matten_mlprep::{add_bias_column, standardize_columns, train_test_split};
27//!
28//! let x = Tensor::new(vec![1.0, 3.0, 5.0, 7.0], &[4, 1]);
29//! let z = standardize_columns(&x).unwrap();        // zero mean, unit std
30//! let z = add_bias_column(&z).unwrap();            // [4, 2], column 0 = 1.0
31//! let (train, test) = train_test_split(&z, 0.75).unwrap();
32//! assert_eq!(train.shape(), &[3, 2]);
33//! assert_eq!(test.shape(), &[1, 2]);
34//! ```
35//!
36//! # Status
37//!
38//! **Production-ready.** The small surface is stable; usable seriously
39//! within the documented limits. [`train_test_split`] is ordered
40//! (no shuffle); [`train_test_split_seeded`] provides a reproducible shuffled
41//! alternative (RFC-077). Constant (zero-variance) columns are rejected
42//! explicitly by the scalers rather than silently producing a zero column — see
43//! [`MattenMlprepError::ZeroVariance`]. Dynamic tensors are rejected at every
44//! public entry point unconditionally — the guard does not depend on the
45//! companion `dynamic` feature (RFC-031).
46//!
47//! # Feature flags
48//!
49//! - `dynamic` — Compatibility forwarding feature. No longer required for
50//!   dynamic rejection as of v0.19.1. Dynamic tensors are rejected at companion
51//!   boundaries regardless of whether this feature is enabled. Reconsider
52//!   removal no earlier than v0.20.0.
53
54#![forbid(unsafe_code)]
55
56mod bias;
57mod error;
58mod scale;
59mod split;
60mod util;
61
62pub use crate::bias::add_bias_column;
63pub use crate::error::MattenMlprepError;
64pub use crate::scale::{minmax_scale_columns, standardize_columns};
65pub use crate::split::{train_test_split, train_test_split_seeded};