Skip to main content

Module regression

Module regression 

Source
Expand description

Wavelet-domain scalar-on-function regression (wcr, WAV-03).

wcr transforms each functional predictor curve into its multi-level DWT coefficient pyramid (via the Phase 69 primitive), concatenates the bands into a single per-curve coefficient vector, and fits a scalar-on-function regression in coefficient space — either PCR (reusing crate::regression::fdata_to_pc_1d) or PLS (reusing crate::regression::fdata_to_pls_1d). The fitted coefficient-space weights are then mapped back to the time-domain functional coefficient β(t) by the inverse DWT (crate::wavelet::reconstruct).

§Why this recovers β(t) exactly

The multi-level orthogonal DWT is a linear, orthonormal map W: the design row for curve i is c_i = W x_i (wavelet coefficients). If the true relationship is y = α + C β_c in coefficient space (with C the coefficient design), then in the time domain y = α + X (Wᵀ β_c), so the time-domain coefficient is β(t) = Wᵀ β_c — exactly the inverse DWT of the coefficient-space weights. [coeff_weights_to_beta_t] performs that inverse DWT.

§Shared seams (reused by the wnet regressor, Plan 70-02)

  • [curves_to_coeff_design] — the curves → concatenated-coefficient-design seam.
  • [coeff_weights_to_beta_t] — the coefficient-weights → β(t) seam.

§End-to-end example (via the prelude, WAV-06)

use fdars_core::prelude::*;

fn main() -> Result<(), fdars_core::FdarError> {
    // 6 curves of length 32 (a db4-decomposable grid), built deterministically.
    let (n, m) = (6usize, 32usize);
    let mut flat = vec![0.0_f64; n * m];
    for i in 0..n {
        for j in 0..m {
            // A smooth, per-curve-varying fill (no RNG → deterministic doctest).
            let t = j as f64 / m as f64;
            flat[i + j * n] = ((i as f64 + 1.0) * t).sin() + 0.5 * (i as f64) * t;
        }
    }
    let data = FdMatrix::from_column_major(flat, n, m)?;
    let y: Vec<f64> = (0..n).map(|i| 1.0 + 0.3 * i as f64).collect();

    // Fit the wavelet-domain PCR regressor, then predict + read the coefficients.
    let fit = wcr(&data, &y, &WcrConfig::default())?;
    let preds = fit.predict(&data)?;
    let beta = fit.beta_t();
    let fitted = fit.fitted_values();

    assert_eq!(preds.len(), fitted.len());
    assert_eq!(beta.len(), m);

    // Self-consistency: predicting on the TRAINING curves reproduces the stored
    // fitted values exactly (the affine intercept folds in the centering offset).
    for (p, f) in preds.iter().zip(fitted) {
        assert!((p - f).abs() < 1e-7, "predict diverges from fitted: {p} vs {f}");
    }
    Ok(())
}

The full wavelet surface (DWT primitives + wcr/wnet + config/result types) is re-exported at the crate root and via crate::prelude (Phase 71, WAV-06).

Structs§

WcrConfig
Configuration for wcr.
WcrResult
Result of a wcr fit.
WnetConfig
Configuration for wnet.
WnetResult
Result of a wnet fit.

Enums§

WcrMethod
Which coefficient-space fit wcr uses.

Functions§

wcr
Fit the wavelet-domain scalar-on-function regressor wcr (WAV-03).
wnet
Fit the wavelet-domain elastic-net scalar-on-function regressor wnet (WAV-04).