Skip to content

Latest commit

 

History

History
95 lines (74 loc) · 3.52 KB

numerical-workflows.md

File metadata and controls

95 lines (74 loc) · 3.52 KB

Numerical workflows

Back to the README

Matrix and vector conventions

Matrices use ordinary Rhai arrays of rows. Constructors make orientation explicit and validate numeric values while preserving their INT/FLOAT types:

let values = [1, 2, 3];        // plain Rhai list
let c = col(values);           // N by 1: [[1], [2], [3]]
let r = row(values);           // 1 by N: [[1, 2, 3]]
let A = mat([[1, 2], [3, 4]]); // rectangular numeric matrix

row and col also convert between vector orientations. Constructors reject empty, ragged, or nonnumeric inputs. The returned arrays remain editable; matrix operations check their inputs again. General matrix arithmetic does not implicitly broadcast or turn a flat list into a row or column.

Use mtimes for matrix multiplication and dot for a real scalar inner product:

let A = mat([[1, 2], [3, 4]]);
let x = col([5, 6]);
let prediction = mtimes(A, x); // [[17.0], [39.0]]
let energy = dot(x, x);        // 61.0; also accepts lists or row vectors
let At = transpose(A);
let augmented = horzcat(A, x);
let extended = vertcat(A, row([7, 8]));

dot accepts equal-length, nonempty vectors in any combination of orientations and returns FLOAT. It does not implement MATLAB's matrix/axis overloads or complex conjugation. mtimes requires matching inner dimensions and returns a matrix, including a 1 by 1 matrix for a row times a column.

Statistics, moving/cumulative operations, differences, interpolation, and trapezoidal integration accept numeric lists, rows, and columns. Mixed INT/FLOAT values are supported. Scalar statistics return scalars; sequence operations return flat lists, so use col or row when feeding those results back into matrix operations. Inputs retain their original shape:

let samples = col([1, 2.0, 3]);
let average = mean(samples);         // 2.0
let smoothed = movmean(samples, 3);  // [1.5, 2.0, 2.5]
let area = trapz(row([0, 1, 2]), samples); // 4.0

Empty numeric samples produce a script error where a value is required. The flat-list identities sum([]) == 0, prod([]) == 1, diff([]) == [], and unique([]) == [] remain available.

Regression and predictions

regress(X, y) treats rows as observations and fits an intercept automatically. Do not add a column of ones. The returned parameters, pvalues, and standard_errors correspond to predictor columns in order. The fitted intercept is returned separately:

let X = col([0, 1, 2]);
let fit = regress(X, col([1.1, 2.8, 5.1]));
let linear_part = mtimes(X, col(fit.parameters));
let first_prediction = fit.intercept + linear_part[0][0];

Earlier releases omitted the fitted intercept from the result. Existing result fields are retained; use the new intercept field when calculating predictions.

CSV calibration example

Run from the repository root:

cargo run --example regression_workflow

This loads the bundled calibration CSV, constructs two predictor columns, fits a linear model, predicts responses, and summarizes residuals. The sample has an intercept of 1, slopes of 2 and 0.5, and an RMSE of approximately 0.1414. It uses local data and requires the io and nalgebra features (both on by default). Rust hosts that already have data can pass an observations array to the same script without enabling io.

Development

cargo fmt --all -- --check
cargo test --no-default-features
cargo test --no-default-features --features rand,nalgebra
cargo test --all-features