Skip to main content

standardize_columns/
standardize_columns.rs

1//! Standardise (z-score normalise) each column of a matrix.
2//!
3//! Run: cargo run --example standardize_columns
4//!
5//! Each column is transformed to zero mean, unit variance using only
6//! existing matten ops: mean_axis, broadcasting, and element-wise arithmetic.
7
8use matten::Tensor;
9
10fn main() {
11    // 4 samples × 3 features
12    let data = Tensor::new(
13        vec![2.0, 4.0, 1.0, 4.0, 6.0, 3.0, 6.0, 8.0, 5.0, 8.0, 10.0, 7.0],
14        &[4, 3],
15    );
16
17    // Column means: shape [3]
18    let means = data.mean_axis(0);
19    // Centre: broadcast [3] across [4, 3]
20    let centred = &data - &means;
21
22    // Column std dev: sqrt(mean of squared deviations)
23    let sq = &centred * &centred;
24    let variance = sq.mean_axis(0);
25    let std_dev_vals: Vec<f64> = variance.as_slice().iter().map(|v| v.sqrt()).collect();
26    let std_dev = Tensor::new(std_dev_vals, &[3]);
27
28    // Standardise
29    let standardised = &centred / &std_dev;
30
31    println!("means    = {:?}", means.as_slice());
32    println!("std devs = {:?}", std_dev.as_slice());
33    println!("result shape = {:?}", standardised.shape());
34
35    // Each column should have mean ≈ 0 and std ≈ 1
36    let col_means = standardised.mean_axis(0);
37    for &m in col_means.as_slice() {
38        assert!(m.abs() < 1e-10, "column mean not zero: {m}");
39    }
40    println!("Column means ≈ 0: OK");
41}