mirror of
https://github.com/Magnus167/rustframe.git
synced 2025-08-20 04:00:01 +00:00
Merge pull request #61 from Magnus167/add-examples
Adding examples for various functionalities
This commit is contained in:
commit
556b08216f
16
.github/scripts/run_examples.sh
vendored
Normal file
16
.github/scripts/run_examples.sh
vendored
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
cargo build --release --examples
|
||||||
|
|
||||||
|
for ex in examples/*.rs; do
|
||||||
|
name=$(basename "$ex" .rs)
|
||||||
|
echo
|
||||||
|
echo "🟡 Running example: $name"
|
||||||
|
|
||||||
|
if ! cargo run --release --example "$name" -- --debug; then
|
||||||
|
echo
|
||||||
|
echo "❌ Example '$name' failed. Aborting."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "✅ All examples ran successfully."
|
17
.github/workflows/run-unit-tests.yml
vendored
17
.github/workflows/run-unit-tests.yml
vendored
@ -12,14 +12,12 @@ concurrency:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
pick-runner:
|
pick-runner:
|
||||||
|
|
||||||
if: github.event.pull_request.draft == false
|
if: github.event.pull_request.draft == false
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
outputs:
|
outputs:
|
||||||
runner: ${{ steps.choose.outputs.use-runner }}
|
runner: ${{ steps.choose.outputs.use-runner }}
|
||||||
steps:
|
steps:
|
||||||
|
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- id: choose
|
- id: choose
|
||||||
uses: ./.github/actions/runner-fallback
|
uses: ./.github/actions/runner-fallback
|
||||||
@ -28,7 +26,6 @@ jobs:
|
|||||||
fallback-runner: "ubuntu-latest"
|
fallback-runner: "ubuntu-latest"
|
||||||
github-token: ${{ secrets.CUSTOM_GH_TOKEN }}
|
github-token: ${{ secrets.CUSTOM_GH_TOKEN }}
|
||||||
|
|
||||||
|
|
||||||
run-unit-tests:
|
run-unit-tests:
|
||||||
needs: pick-runner
|
needs: pick-runner
|
||||||
if: github.event.pull_request.draft == false
|
if: github.event.pull_request.draft == false
|
||||||
@ -56,6 +53,20 @@ jobs:
|
|||||||
- name: Test docs generation
|
- name: Test docs generation
|
||||||
run: cargo doc --no-deps --release
|
run: cargo doc --no-deps --release
|
||||||
|
|
||||||
|
- name: Test examples
|
||||||
|
run: cargo test --examples --release
|
||||||
|
|
||||||
|
- name: Run all examples
|
||||||
|
run: |
|
||||||
|
for example in examples/*.rs; do
|
||||||
|
name=$(basename "$example" .rs)
|
||||||
|
echo "Running example: $name"
|
||||||
|
cargo run --release --example "$name" -- --debug || exit 1
|
||||||
|
done
|
||||||
|
|
||||||
|
- name: Cargo test all targets
|
||||||
|
run: cargo test --all-targets --release
|
||||||
|
|
||||||
- name: Upload coverage to Codecov
|
- name: Upload coverage to Codecov
|
||||||
uses: codecov/codecov-action@v3
|
uses: codecov/codecov-action@v3
|
||||||
with:
|
with:
|
||||||
|
23
README.md
23
README.md
@ -192,6 +192,29 @@ E.g. to run the `game_of_life` example:
|
|||||||
cargo run --example game_of_life
|
cargo run --example game_of_life
|
||||||
```
|
```
|
||||||
|
|
||||||
|
More demos:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cargo run --example linear_regression
|
||||||
|
cargo run --example logistic_regression
|
||||||
|
cargo run --example k_means
|
||||||
|
cargo run --example pca
|
||||||
|
cargo run --example stats_overview
|
||||||
|
cargo run --example descriptive_stats
|
||||||
|
cargo run --example correlation
|
||||||
|
cargo run --example inferential_stats
|
||||||
|
cargo run --example distributions
|
||||||
|
```
|
||||||
|
|
||||||
|
To simply list all available examples, you can run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# this technically raises an error, but it will list all examples
|
||||||
|
cargo run --example
|
||||||
|
```
|
||||||
|
|
||||||
|
Each demo runs a couple of mini-scenarios showcasing the APIs.
|
||||||
|
|
||||||
### Running benchmarks
|
### Running benchmarks
|
||||||
|
|
||||||
To run the benchmarks, use:
|
To run the benchmarks, use:
|
||||||
|
45
examples/correlation.rs
Normal file
45
examples/correlation.rs
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
use rustframe::compute::stats::{covariance, covariance_matrix, pearson};
|
||||||
|
use rustframe::matrix::{Axis, Matrix};
|
||||||
|
|
||||||
|
/// Demonstrates covariance and correlation utilities.
|
||||||
|
fn main() {
|
||||||
|
pairwise_cov();
|
||||||
|
println!("\n-----\n");
|
||||||
|
matrix_cov();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pairwise_cov() {
|
||||||
|
println!("Covariance & Pearson r\n----------------------");
|
||||||
|
let x = Matrix::from_vec(vec![1.0, 2.0, 3.0, 4.0], 2, 2);
|
||||||
|
let y = Matrix::from_vec(vec![1.0, 2.0, 3.0, 5.0], 2, 2);
|
||||||
|
println!("covariance : {:.2}", covariance(&x, &y));
|
||||||
|
println!("pearson r : {:.3}", pearson(&x, &y));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn matrix_cov() {
|
||||||
|
println!("Covariance matrix\n-----------------");
|
||||||
|
let data = Matrix::from_rows_vec(vec![1.0, 2.0, 3.0, 4.0], 2, 2);
|
||||||
|
let cov = covariance_matrix(&data, Axis::Col);
|
||||||
|
println!("cov matrix : {:?}", cov.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
const EPS: f64 = 1e-8;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_pairwise_cov() {
|
||||||
|
let x = Matrix::from_vec(vec![1.0, 2.0, 3.0, 4.0], 2, 2);
|
||||||
|
let y = Matrix::from_vec(vec![1.0, 2.0, 3.0, 5.0], 2, 2);
|
||||||
|
assert!((covariance(&x, &y) - 1.625).abs() < EPS);
|
||||||
|
assert!((pearson(&x, &y) - 0.9827076298239908).abs() < 1e-5,);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_matrix_cov() {
|
||||||
|
let data = Matrix::from_rows_vec(vec![1.0, 2.0, 3.0, 4.0], 2, 2);
|
||||||
|
let cov = covariance_matrix(&data, Axis::Col);
|
||||||
|
assert_eq!(cov.data(), &[2.0, 2.0, 2.0, 2.0]);
|
||||||
|
}
|
||||||
|
}
|
56
examples/descriptive_stats.rs
Normal file
56
examples/descriptive_stats.rs
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
use rustframe::compute::stats::{mean, mean_horizontal, mean_vertical, median, percentile, stddev};
|
||||||
|
use rustframe::matrix::Matrix;
|
||||||
|
|
||||||
|
/// Demonstrates descriptive statistics utilities.
|
||||||
|
///
|
||||||
|
/// Part 1: simple mean/stddev/median/percentile on a vector.
|
||||||
|
/// Part 2: mean across rows and columns.
|
||||||
|
fn main() {
|
||||||
|
simple_stats();
|
||||||
|
println!("\n-----\n");
|
||||||
|
axis_stats();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn simple_stats() {
|
||||||
|
println!("Basic stats\n-----------");
|
||||||
|
let data = Matrix::from_vec(vec![1.0, 2.0, 3.0, 4.0, 5.0], 1, 5);
|
||||||
|
println!("mean : {:.2}", mean(&data));
|
||||||
|
println!("stddev : {:.2}", stddev(&data));
|
||||||
|
println!("median : {:.2}", median(&data));
|
||||||
|
println!("90th pct. : {:.2}", percentile(&data, 90.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn axis_stats() {
|
||||||
|
println!("Row/column means\n----------------");
|
||||||
|
// 2x3 matrix
|
||||||
|
let data = Matrix::from_rows_vec(vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0], 2, 3);
|
||||||
|
let v = mean_vertical(&data); // 1x3
|
||||||
|
let h = mean_horizontal(&data); // 2x1
|
||||||
|
println!("vertical means : {:?}", v.data());
|
||||||
|
println!("horizontal means: {:?}", h.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
const EPS: f64 = 1e-8;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_simple_stats() {
|
||||||
|
let data = Matrix::from_vec(vec![1.0, 2.0, 3.0, 4.0, 5.0], 1, 5);
|
||||||
|
assert!((mean(&data) - 3.0).abs() < EPS);
|
||||||
|
assert!((stddev(&data) - 1.4142135623730951).abs() < EPS);
|
||||||
|
assert!((median(&data) - 3.0).abs() < EPS);
|
||||||
|
assert!((percentile(&data, 90.0) - 5.0).abs() < EPS);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_axis_stats() {
|
||||||
|
let data = Matrix::from_rows_vec(vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0], 2, 3);
|
||||||
|
let v = mean_vertical(&data);
|
||||||
|
assert_eq!(v.data(), &[2.5, 3.5, 4.5]);
|
||||||
|
let h = mean_horizontal(&data);
|
||||||
|
assert_eq!(h.data(), &[2.0, 5.0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
66
examples/distributions.rs
Normal file
66
examples/distributions.rs
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
use rustframe::compute::stats::{binomial_cdf, binomial_pmf, normal_cdf, normal_pdf, poisson_pmf};
|
||||||
|
use rustframe::matrix::Matrix;
|
||||||
|
|
||||||
|
/// Demonstrates some probability distribution helpers.
|
||||||
|
fn main() {
|
||||||
|
normal_example();
|
||||||
|
println!("\n-----\n");
|
||||||
|
binomial_example();
|
||||||
|
println!("\n-----\n");
|
||||||
|
poisson_example();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn normal_example() {
|
||||||
|
println!("Normal distribution\n-------------------");
|
||||||
|
let x = Matrix::from_vec(vec![0.0, 1.0], 1, 2);
|
||||||
|
let pdf = normal_pdf(x.clone(), 0.0, 1.0);
|
||||||
|
let cdf = normal_cdf(x, 0.0, 1.0);
|
||||||
|
println!("pdf : {:?}", pdf.data());
|
||||||
|
println!("cdf : {:?}", cdf.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn binomial_example() {
|
||||||
|
println!("Binomial distribution\n---------------------");
|
||||||
|
let k = Matrix::from_vec(vec![0_u64, 1, 2], 1, 3);
|
||||||
|
let pmf = binomial_pmf(4, k.clone(), 0.5);
|
||||||
|
let cdf = binomial_cdf(4, k, 0.5);
|
||||||
|
println!("pmf : {:?}", pmf.data());
|
||||||
|
println!("cdf : {:?}", cdf.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn poisson_example() {
|
||||||
|
println!("Poisson distribution\n--------------------");
|
||||||
|
let k = Matrix::from_vec(vec![0_u64, 1, 2], 1, 3);
|
||||||
|
let pmf = poisson_pmf(3.0, k);
|
||||||
|
println!("pmf : {:?}", pmf.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_normal_example() {
|
||||||
|
let x = Matrix::from_vec(vec![0.0, 1.0], 1, 2);
|
||||||
|
let pdf = normal_pdf(x.clone(), 0.0, 1.0);
|
||||||
|
let cdf = normal_cdf(x, 0.0, 1.0);
|
||||||
|
assert!((pdf.get(0, 0) - 0.39894228).abs() < 1e-6);
|
||||||
|
assert!((cdf.get(0, 1) - 0.8413447).abs() < 1e-6);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_binomial_example() {
|
||||||
|
let k = Matrix::from_vec(vec![0_u64, 1, 2], 1, 3);
|
||||||
|
let pmf = binomial_pmf(4, k.clone(), 0.5);
|
||||||
|
let cdf = binomial_cdf(4, k, 0.5);
|
||||||
|
assert!((pmf.get(0, 2) - 0.375).abs() < 1e-6);
|
||||||
|
assert!((cdf.get(0, 2) - 0.6875).abs() < 1e-6);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_poisson_example() {
|
||||||
|
let k = Matrix::from_vec(vec![0_u64, 1, 2], 1, 3);
|
||||||
|
let pmf = poisson_pmf(3.0, k);
|
||||||
|
assert!((pmf.get(0, 1) - 3.0_f64 * (-3.0_f64).exp()).abs() < 1e-6);
|
||||||
|
}
|
||||||
|
}
|
@ -1,11 +1,26 @@
|
|||||||
|
//! Conway's Game of Life Example
|
||||||
|
//! This example implements Conway's Game of Life using a `BoolMatrix` to represent the game board.
|
||||||
|
//! It demonstrates matrix operations like shifting, counting neighbors, and applying game rules.
|
||||||
|
//! The game runs in a loop, updating the board state and printing it to the console.
|
||||||
|
//! To modify the behaviour of the example, please change the constants at the top of this file.
|
||||||
|
//! By default,
|
||||||
|
|
||||||
use rand::{self, Rng};
|
use rand::{self, Rng};
|
||||||
use rustframe::matrix::{BoolMatrix, BoolOps, IntMatrix, Matrix};
|
use rustframe::matrix::{BoolMatrix, BoolOps, IntMatrix, Matrix};
|
||||||
use std::{thread, time};
|
use std::{thread, time};
|
||||||
|
|
||||||
const BOARD_SIZE: usize = 50; // Size of the board (50x50)
|
const BOARD_SIZE: usize = 20; // Size of the board (50x50)
|
||||||
const TICK_DURATION_MS: u64 = 10; // Milliseconds per frame
|
const MAX_FRAMES: u32 = 1000;
|
||||||
|
|
||||||
|
const TICK_DURATION_MS: u64 = 0; // Milliseconds per frame
|
||||||
|
const SKIP_FRAMES: u32 = 1;
|
||||||
|
const PRINT_BOARD: bool = true; // Set to false to disable printing the board
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
let args = std::env::args().collect::<Vec<String>>();
|
||||||
|
let debug_mode = args.contains(&"--debug".to_string());
|
||||||
|
let print_mode = if debug_mode { false } else { PRINT_BOARD };
|
||||||
|
|
||||||
// Initialize the game board.
|
// Initialize the game board.
|
||||||
// This demonstrates `BoolMatrix::from_vec`.
|
// This demonstrates `BoolMatrix::from_vec`.
|
||||||
let mut current_board =
|
let mut current_board =
|
||||||
@ -24,20 +39,12 @@ fn main() {
|
|||||||
let mut print_bool_int = 0;
|
let mut print_bool_int = 0;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
// print!("{}[2J", 27 as char); // Clear screen and move cursor to top-left
|
|
||||||
|
|
||||||
// if print_board_bool {
|
// if print_board_bool {
|
||||||
if print_bool_int % 10 == 0 {
|
if print_bool_int % SKIP_FRAMES == 0 {
|
||||||
print!("{}[2J", 27 as char);
|
print_board(¤t_board, generation_count, print_mode);
|
||||||
println!("Conway's Game of Life - Generation: {}", generation_count);
|
|
||||||
|
|
||||||
print_board(¤t_board);
|
|
||||||
println!("Alive cells: {}", ¤t_board.count());
|
|
||||||
|
|
||||||
// print_board_bool = false;
|
|
||||||
print_bool_int = 0;
|
print_bool_int = 0;
|
||||||
} else {
|
} else {
|
||||||
// print_board_bool = true;
|
|
||||||
print_bool_int += 1;
|
print_bool_int += 1;
|
||||||
}
|
}
|
||||||
// `current_board.count()` demonstrates a method from `BoolOps`.
|
// `current_board.count()` demonstrates a method from `BoolOps`.
|
||||||
@ -71,10 +78,10 @@ fn main() {
|
|||||||
generation_count += 1;
|
generation_count += 1;
|
||||||
thread::sleep(time::Duration::from_millis(TICK_DURATION_MS));
|
thread::sleep(time::Duration::from_millis(TICK_DURATION_MS));
|
||||||
|
|
||||||
// if generation_count > 500 { // Optional limit
|
if (MAX_FRAMES > 0) && (generation_count > MAX_FRAMES) {
|
||||||
// println!("\nReached generation limit.");
|
println!("\nReached generation limit.");
|
||||||
// break;
|
break;
|
||||||
// }
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,7 +89,13 @@ fn main() {
|
|||||||
///
|
///
|
||||||
/// - `board`: A reference to the `BoolMatrix` representing the current game state.
|
/// - `board`: A reference to the `BoolMatrix` representing the current game state.
|
||||||
/// This function demonstrates `board.rows()`, `board.cols()`, and `board[(r, c)]` (Index trait).
|
/// This function demonstrates `board.rows()`, `board.cols()`, and `board[(r, c)]` (Index trait).
|
||||||
fn print_board(board: &BoolMatrix) {
|
fn print_board(board: &BoolMatrix, generation_count: u32, print_mode: bool) {
|
||||||
|
if !print_mode {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
print!("{}[2J", 27 as char);
|
||||||
|
println!("Conway's Game of Life - Generation: {}", generation_count);
|
||||||
let mut print_str = String::new();
|
let mut print_str = String::new();
|
||||||
print_str.push_str("+");
|
print_str.push_str("+");
|
||||||
for _ in 0..board.cols() {
|
for _ in 0..board.cols() {
|
||||||
@ -107,6 +120,8 @@ fn print_board(board: &BoolMatrix) {
|
|||||||
}
|
}
|
||||||
print_str.push_str("+\n\n");
|
print_str.push_str("+\n\n");
|
||||||
print!("{}", print_str);
|
print!("{}", print_str);
|
||||||
|
|
||||||
|
println!("Alive cells: {}", board.count());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper function to create a shifted version of the game board.
|
/// Helper function to create a shifted version of the game board.
|
||||||
|
66
examples/inferential_stats.rs
Normal file
66
examples/inferential_stats.rs
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
use rustframe::compute::stats::{anova, chi2_test, t_test};
|
||||||
|
use rustframe::matrix::Matrix;
|
||||||
|
|
||||||
|
/// Demonstrates simple inferential statistics tests.
|
||||||
|
fn main() {
|
||||||
|
t_test_demo();
|
||||||
|
println!("\n-----\n");
|
||||||
|
chi2_demo();
|
||||||
|
println!("\n-----\n");
|
||||||
|
anova_demo();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn t_test_demo() {
|
||||||
|
println!("Two-sample t-test\n-----------------");
|
||||||
|
let a = Matrix::from_vec(vec![1.0, 2.0, 3.0, 4.0, 5.0], 1, 5);
|
||||||
|
let b = Matrix::from_vec(vec![6.0, 7.0, 8.0, 9.0, 10.0], 1, 5);
|
||||||
|
let (t, p) = t_test(&a, &b);
|
||||||
|
println!("t statistic: {:.2}, p-value: {:.4}", t, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn chi2_demo() {
|
||||||
|
println!("Chi-square test\n---------------");
|
||||||
|
let observed = Matrix::from_vec(vec![12.0, 5.0, 8.0, 10.0], 2, 2);
|
||||||
|
let (chi2, p) = chi2_test(&observed);
|
||||||
|
println!("chi^2: {:.2}, p-value: {:.4}", chi2, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn anova_demo() {
|
||||||
|
println!("One-way ANOVA\n-------------");
|
||||||
|
let g1 = Matrix::from_vec(vec![1.0, 2.0, 3.0], 1, 3);
|
||||||
|
let g2 = Matrix::from_vec(vec![2.0, 3.0, 4.0], 1, 3);
|
||||||
|
let g3 = Matrix::from_vec(vec![3.0, 4.0, 5.0], 1, 3);
|
||||||
|
let (f, p) = anova(vec![&g1, &g2, &g3]);
|
||||||
|
println!("F statistic: {:.2}, p-value: {:.4}", f, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_t_test_demo() {
|
||||||
|
let a = Matrix::from_vec(vec![1.0, 2.0, 3.0, 4.0, 5.0], 1, 5);
|
||||||
|
let b = Matrix::from_vec(vec![6.0, 7.0, 8.0, 9.0, 10.0], 1, 5);
|
||||||
|
let (t, _p) = t_test(&a, &b);
|
||||||
|
assert!((t + 5.0).abs() < 1e-5);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_chi2_demo() {
|
||||||
|
let observed = Matrix::from_vec(vec![12.0, 5.0, 8.0, 10.0], 2, 2);
|
||||||
|
let (chi2, p) = chi2_test(&observed);
|
||||||
|
assert!(chi2 > 0.0);
|
||||||
|
assert!(p > 0.0 && p < 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_anova_demo() {
|
||||||
|
let g1 = Matrix::from_vec(vec![1.0, 2.0, 3.0], 1, 3);
|
||||||
|
let g2 = Matrix::from_vec(vec![2.0, 3.0, 4.0], 1, 3);
|
||||||
|
let g3 = Matrix::from_vec(vec![3.0, 4.0, 5.0], 1, 3);
|
||||||
|
let (f, p) = anova(vec![&g1, &g2, &g3]);
|
||||||
|
assert!(f > 0.0);
|
||||||
|
assert!(p > 0.0 && p < 1.0);
|
||||||
|
}
|
||||||
|
}
|
65
examples/k_means.rs
Normal file
65
examples/k_means.rs
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
use rustframe::compute::models::k_means::KMeans;
|
||||||
|
use rustframe::matrix::Matrix;
|
||||||
|
|
||||||
|
/// Two quick K-Means clustering demos.
|
||||||
|
///
|
||||||
|
/// Example 1 groups store locations on a city map.
|
||||||
|
/// Example 2 segments customers by annual spending habits.
|
||||||
|
fn main() {
|
||||||
|
city_store_example();
|
||||||
|
println!("\n-----\n");
|
||||||
|
customer_spend_example();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn city_store_example() {
|
||||||
|
println!("Example 1: store locations");
|
||||||
|
|
||||||
|
// (x, y) coordinates of stores around a city
|
||||||
|
let raw = vec![
|
||||||
|
1.0, 2.0, 1.5, 1.8, 5.0, 8.0, 8.0, 8.0, 1.0, 0.6, 9.0, 11.0, 8.0, 2.0, 10.0, 2.0, 9.0, 3.0,
|
||||||
|
];
|
||||||
|
let x = Matrix::from_rows_vec(raw, 9, 2);
|
||||||
|
|
||||||
|
// Group stores into two areas
|
||||||
|
let (model, labels) = KMeans::fit(&x, 2, 100, 1e-4);
|
||||||
|
|
||||||
|
println!("Centres: {:?}", model.centroids.data());
|
||||||
|
println!("Labels: {:?}", labels);
|
||||||
|
|
||||||
|
let new_points = Matrix::from_rows_vec(vec![0.0, 0.0, 8.0, 3.0], 2, 2);
|
||||||
|
let pred = model.predict(&new_points);
|
||||||
|
println!("New store assignments: {:?}", pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn customer_spend_example() {
|
||||||
|
println!("Example 2: customer spending");
|
||||||
|
|
||||||
|
// (grocery spend, electronics spend) in dollars
|
||||||
|
let raw = vec![
|
||||||
|
200.0, 150.0, 220.0, 170.0, 250.0, 160.0, 800.0, 750.0, 820.0, 760.0, 790.0, 770.0,
|
||||||
|
];
|
||||||
|
let x = Matrix::from_rows_vec(raw, 6, 2);
|
||||||
|
|
||||||
|
let (model, labels) = KMeans::fit(&x, 2, 100, 1e-4);
|
||||||
|
|
||||||
|
println!("Centres: {:?}", model.centroids.data());
|
||||||
|
println!("Labels: {:?}", labels);
|
||||||
|
|
||||||
|
let new_customers = Matrix::from_rows_vec(vec![230.0, 155.0, 810.0, 760.0], 2, 2);
|
||||||
|
let pred = model.predict(&new_customers);
|
||||||
|
println!("Cluster of new customers: {:?}", pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn k_means_store_locations() {
|
||||||
|
let raw = vec![
|
||||||
|
1.0, 2.0, 1.5, 1.8, 5.0, 8.0, 8.0, 8.0, 1.0, 0.6, 9.0, 11.0, 8.0, 2.0, 10.0, 2.0, 9.0, 3.0,
|
||||||
|
];
|
||||||
|
let x = Matrix::from_rows_vec(raw, 9, 2);
|
||||||
|
let (model, labels) = KMeans::fit(&x, 2, 100, 1e-4);
|
||||||
|
assert_eq!(labels.len(), 9);
|
||||||
|
assert_eq!(model.centroids.rows(), 2);
|
||||||
|
let new_points = Matrix::from_rows_vec(vec![0.0, 0.0, 8.0, 3.0], 2, 2);
|
||||||
|
let pred = model.predict(&new_points);
|
||||||
|
assert_eq!(pred.len(), 2);
|
||||||
|
}
|
118
examples/linear_regression.rs
Normal file
118
examples/linear_regression.rs
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
use rustframe::compute::models::linreg::LinReg;
|
||||||
|
use rustframe::matrix::Matrix;
|
||||||
|
|
||||||
|
/// Two quick linear regression demonstrations.
|
||||||
|
///
|
||||||
|
/// Example 1 fits a model to predict house price from floor area.
|
||||||
|
/// Example 2 adds number of bedrooms as a second feature.
|
||||||
|
fn main() {
|
||||||
|
example_one_feature();
|
||||||
|
println!("\n-----\n");
|
||||||
|
example_two_features();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Price ~ floor area
|
||||||
|
fn example_one_feature() {
|
||||||
|
println!("Example 1: predict price from floor area only");
|
||||||
|
|
||||||
|
// Square meters of floor area for a few houses
|
||||||
|
let sizes = vec![50.0, 60.0, 70.0, 80.0, 90.0, 100.0];
|
||||||
|
// Thousands of dollars in sale price
|
||||||
|
let prices = vec![150.0, 180.0, 210.0, 240.0, 270.0, 300.0];
|
||||||
|
|
||||||
|
// Each row is a sample with one feature
|
||||||
|
let x = Matrix::from_vec(sizes.clone(), sizes.len(), 1);
|
||||||
|
let y = Matrix::from_vec(prices.clone(), prices.len(), 1);
|
||||||
|
|
||||||
|
// Train with a small learning rate
|
||||||
|
let mut model = LinReg::new(1);
|
||||||
|
model.fit(&x, &y, 0.0005, 20000);
|
||||||
|
|
||||||
|
let preds = model.predict(&x);
|
||||||
|
println!("Size (m^2) -> predicted price (k) vs actual");
|
||||||
|
for i in 0..x.rows() {
|
||||||
|
println!(
|
||||||
|
"{:>3} -> {:>6.1} | {:>6.1}",
|
||||||
|
sizes[i],
|
||||||
|
preds[(i, 0)],
|
||||||
|
prices[i]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let new_house = Matrix::from_vec(vec![120.0], 1, 1);
|
||||||
|
let pred = model.predict(&new_house);
|
||||||
|
println!("Predicted price for 120 m^2: {:.1}k", pred[(0, 0)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Price ~ floor area + bedrooms
|
||||||
|
fn example_two_features() {
|
||||||
|
println!("Example 2: price from area and bedrooms");
|
||||||
|
|
||||||
|
// (size m^2, bedrooms) for each house
|
||||||
|
let raw_x = vec![
|
||||||
|
50.0, 2.0, 70.0, 2.0, 90.0, 3.0, 110.0, 3.0, 130.0, 4.0, 150.0, 4.0,
|
||||||
|
];
|
||||||
|
let prices = vec![160.0, 195.0, 250.0, 285.0, 320.0, 350.0];
|
||||||
|
|
||||||
|
let x = Matrix::from_rows_vec(raw_x, 6, 2);
|
||||||
|
let y = Matrix::from_vec(prices.clone(), prices.len(), 1);
|
||||||
|
|
||||||
|
let mut model = LinReg::new(2);
|
||||||
|
model.fit(&x, &y, 0.0001, 50000);
|
||||||
|
|
||||||
|
let preds = model.predict(&x);
|
||||||
|
println!("size, beds -> predicted | actual (k)");
|
||||||
|
for i in 0..x.rows() {
|
||||||
|
let size = x[(i, 0)];
|
||||||
|
let beds = x[(i, 1)];
|
||||||
|
println!(
|
||||||
|
"{:>3} m^2, {:>1} -> {:>6.1} | {:>6.1}",
|
||||||
|
size,
|
||||||
|
beds,
|
||||||
|
preds[(i, 0)],
|
||||||
|
prices[i]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let new_home = Matrix::from_rows_vec(vec![120.0, 3.0], 1, 2);
|
||||||
|
let pred = model.predict(&new_home);
|
||||||
|
println!(
|
||||||
|
"Predicted price for 120 m^2 with 3 bedrooms: {:.1}k",
|
||||||
|
pred[(0, 0)]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_linear_regression_one_feature() {
|
||||||
|
let sizes = vec![50.0, 60.0, 70.0, 80.0, 90.0, 100.0];
|
||||||
|
let prices = vec![150.0, 180.0, 210.0, 240.0, 270.0, 300.0];
|
||||||
|
let scaled: Vec<f64> = sizes.iter().map(|s| s / 100.0).collect();
|
||||||
|
let x = Matrix::from_vec(scaled, sizes.len(), 1);
|
||||||
|
let y = Matrix::from_vec(prices.clone(), prices.len(), 1);
|
||||||
|
let mut model = LinReg::new(1);
|
||||||
|
model.fit(&x, &y, 0.1, 2000);
|
||||||
|
let preds = model.predict(&x);
|
||||||
|
for i in 0..y.rows() {
|
||||||
|
assert!((preds[(i, 0)] - prices[i]).abs() < 1.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_linear_regression_two_features() {
|
||||||
|
let raw_x = vec![
|
||||||
|
50.0, 2.0, 70.0, 2.0, 90.0, 3.0, 110.0, 3.0, 130.0, 4.0, 150.0, 4.0,
|
||||||
|
];
|
||||||
|
let prices = vec![170.0, 210.0, 270.0, 310.0, 370.0, 410.0];
|
||||||
|
let scaled_x: Vec<f64> = raw_x
|
||||||
|
.chunks(2)
|
||||||
|
.flat_map(|pair| vec![pair[0] / 100.0, pair[1]])
|
||||||
|
.collect();
|
||||||
|
let x = Matrix::from_rows_vec(scaled_x, 6, 2);
|
||||||
|
let y = Matrix::from_vec(prices.clone(), prices.len(), 1);
|
||||||
|
let mut model = LinReg::new(2);
|
||||||
|
model.fit(&x, &y, 0.01, 50000);
|
||||||
|
let preds = model.predict(&x);
|
||||||
|
for i in 0..y.rows() {
|
||||||
|
assert!((preds[(i, 0)] - prices[i]).abs() < 1.0);
|
||||||
|
}
|
||||||
|
}
|
101
examples/logistic_regression.rs
Normal file
101
examples/logistic_regression.rs
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
use rustframe::compute::models::logreg::LogReg;
|
||||||
|
use rustframe::matrix::Matrix;
|
||||||
|
|
||||||
|
/// Two binary classification demos using logistic regression.
|
||||||
|
///
|
||||||
|
/// Example 1 predicts exam success from hours studied.
|
||||||
|
/// Example 2 predicts whether an online shopper will make a purchase.
|
||||||
|
fn main() {
|
||||||
|
student_passing_example();
|
||||||
|
println!("\n-----\n");
|
||||||
|
purchase_prediction_example();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn student_passing_example() {
|
||||||
|
println!("Example 1: exam pass prediction");
|
||||||
|
|
||||||
|
// Hours studied for each student
|
||||||
|
let hours = vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0];
|
||||||
|
// 0 = fail, 1 = pass
|
||||||
|
let passed = vec![0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0];
|
||||||
|
|
||||||
|
let x = Matrix::from_vec(hours.clone(), hours.len(), 1);
|
||||||
|
let y = Matrix::from_vec(passed.clone(), passed.len(), 1);
|
||||||
|
|
||||||
|
let mut model = LogReg::new(1);
|
||||||
|
model.fit(&x, &y, 0.1, 10000);
|
||||||
|
|
||||||
|
let preds = model.predict(&x);
|
||||||
|
println!("Hours -> pred | actual");
|
||||||
|
for i in 0..x.rows() {
|
||||||
|
println!(
|
||||||
|
"{:>2} -> {} | {}",
|
||||||
|
hours[i] as i32,
|
||||||
|
preds[(i, 0)] as i32,
|
||||||
|
passed[i] as i32
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Probability estimate for a new student
|
||||||
|
let new_student = Matrix::from_vec(vec![5.5], 1, 1);
|
||||||
|
let p = model.predict_proba(&new_student);
|
||||||
|
println!("Probability of passing with 5.5h study: {:.2}", p[(0, 0)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn purchase_prediction_example() {
|
||||||
|
println!("Example 2: purchase likelihood");
|
||||||
|
|
||||||
|
// minutes on site, pages viewed -> made a purchase?
|
||||||
|
let raw_x = vec![1.0, 2.0, 3.0, 1.0, 2.0, 4.0, 5.0, 5.0, 3.5, 2.0, 6.0, 6.0];
|
||||||
|
let bought = vec![0.0, 0.0, 0.0, 1.0, 0.0, 1.0];
|
||||||
|
|
||||||
|
let x = Matrix::from_rows_vec(raw_x, 6, 2);
|
||||||
|
let y = Matrix::from_vec(bought.clone(), bought.len(), 1);
|
||||||
|
|
||||||
|
let mut model = LogReg::new(2);
|
||||||
|
model.fit(&x, &y, 0.05, 20000);
|
||||||
|
|
||||||
|
let preds = model.predict(&x);
|
||||||
|
println!("time, pages -> pred | actual");
|
||||||
|
for i in 0..x.rows() {
|
||||||
|
println!(
|
||||||
|
"{:>4}m, {:>2} -> {} | {}",
|
||||||
|
x[(i, 0)],
|
||||||
|
x[(i, 1)] as i32,
|
||||||
|
preds[(i, 0)] as i32,
|
||||||
|
bought[i] as i32
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let new_visit = Matrix::from_rows_vec(vec![4.0, 4.0], 1, 2);
|
||||||
|
let p = model.predict_proba(&new_visit);
|
||||||
|
println!("Prob of purchase for 4min/4pages: {:.2}", p[(0, 0)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_student_passing_example() {
|
||||||
|
let hours = vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0];
|
||||||
|
let passed = vec![0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0];
|
||||||
|
let x = Matrix::from_vec(hours.clone(), hours.len(), 1);
|
||||||
|
let y = Matrix::from_vec(passed.clone(), passed.len(), 1);
|
||||||
|
let mut model = LogReg::new(1);
|
||||||
|
model.fit(&x, &y, 0.1, 10000);
|
||||||
|
let preds = model.predict(&x);
|
||||||
|
for i in 0..y.rows() {
|
||||||
|
assert_eq!(preds[(i, 0)], passed[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_purchase_prediction_example() {
|
||||||
|
let raw_x = vec![1.0, 2.0, 3.0, 1.0, 2.0, 4.0, 5.0, 5.0, 3.5, 2.0, 6.0, 6.0];
|
||||||
|
let bought = vec![0.0, 0.0, 0.0, 1.0, 0.0, 1.0];
|
||||||
|
let x = Matrix::from_rows_vec(raw_x, 6, 2);
|
||||||
|
let y = Matrix::from_vec(bought.clone(), bought.len(), 1);
|
||||||
|
let mut model = LogReg::new(2);
|
||||||
|
model.fit(&x, &y, 0.05, 20000);
|
||||||
|
let preds = model.predict(&x);
|
||||||
|
for i in 0..y.rows() {
|
||||||
|
assert_eq!(preds[(i, 0)], bought[i]);
|
||||||
|
}
|
||||||
|
}
|
60
examples/pca.rs
Normal file
60
examples/pca.rs
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
use rustframe::compute::models::pca::PCA;
|
||||||
|
use rustframe::matrix::Matrix;
|
||||||
|
|
||||||
|
/// Two dimensionality reduction examples using PCA.
|
||||||
|
///
|
||||||
|
/// Example 1 reduces 3D sensor readings to two components.
|
||||||
|
/// Example 2 compresses a small four-feature dataset.
|
||||||
|
fn main() {
|
||||||
|
sensor_demo();
|
||||||
|
println!("\n-----\n");
|
||||||
|
finance_demo();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sensor_demo() {
|
||||||
|
println!("Example 1: 3D sensor data");
|
||||||
|
|
||||||
|
// Ten 3D observations from an accelerometer
|
||||||
|
let raw = vec![
|
||||||
|
2.5, 2.4, 0.5, 0.5, 0.7, 1.5, 2.2, 2.9, 0.7, 1.9, 2.2, 1.0, 3.1, 3.0, 0.6, 2.3, 2.7, 0.9,
|
||||||
|
2.0, 1.6, 1.1, 1.0, 1.1, 1.9, 1.5, 1.6, 2.2, 1.1, 0.9, 2.1,
|
||||||
|
];
|
||||||
|
let x = Matrix::from_rows_vec(raw, 10, 3);
|
||||||
|
|
||||||
|
let pca = PCA::fit(&x, 2, 0);
|
||||||
|
let reduced = pca.transform(&x);
|
||||||
|
|
||||||
|
println!("Components: {:?}", pca.components.data());
|
||||||
|
println!("First row -> {:.2?}", [reduced[(0, 0)], reduced[(0, 1)]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn finance_demo() {
|
||||||
|
println!("Example 2: 4D finance data");
|
||||||
|
|
||||||
|
// Four daily percentage returns of different stocks
|
||||||
|
let raw = vec![
|
||||||
|
0.2, 0.1, -0.1, 0.0, 0.3, 0.2, -0.2, 0.1, 0.1, 0.0, -0.1, -0.1, 0.4, 0.3, -0.3, 0.2, 0.0,
|
||||||
|
-0.1, 0.1, -0.1,
|
||||||
|
];
|
||||||
|
let x = Matrix::from_rows_vec(raw, 5, 4);
|
||||||
|
|
||||||
|
// Keep two principal components
|
||||||
|
let pca = PCA::fit(&x, 2, 0);
|
||||||
|
let reduced = pca.transform(&x);
|
||||||
|
|
||||||
|
println!("Reduced shape: {:?}", reduced.shape());
|
||||||
|
println!("First row -> {:.2?}", [reduced[(0, 0)], reduced[(0, 1)]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_sensor_demo() {
|
||||||
|
let raw = vec![
|
||||||
|
2.5, 2.4, 0.5, 0.5, 0.7, 1.5, 2.2, 2.9, 0.7, 1.9, 2.2, 1.0, 3.1, 3.0, 0.6, 2.3, 2.7, 0.9,
|
||||||
|
2.0, 1.6, 1.1, 1.0, 1.1, 1.9, 1.5, 1.6, 2.2, 1.1, 0.9, 2.1,
|
||||||
|
];
|
||||||
|
let x = Matrix::from_rows_vec(raw, 10, 3);
|
||||||
|
let pca = PCA::fit(&x, 2, 0);
|
||||||
|
let reduced = pca.transform(&x);
|
||||||
|
assert_eq!(reduced.rows(), 10);
|
||||||
|
assert_eq!(reduced.cols(), 2);
|
||||||
|
}
|
93
examples/stats_overview.rs
Normal file
93
examples/stats_overview.rs
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
use rustframe::compute::stats::{
|
||||||
|
chi2_test, covariance, covariance_matrix, mean, median, pearson, percentile, stddev, t_test,
|
||||||
|
};
|
||||||
|
use rustframe::matrix::{Axis, Matrix};
|
||||||
|
|
||||||
|
/// Demonstrates some of the statistics utilities in Rustframe.
|
||||||
|
///
|
||||||
|
/// The example is split into three parts:
|
||||||
|
/// 1. Basic descriptive statistics on a small data set.
|
||||||
|
/// 2. Covariance and correlation calculations.
|
||||||
|
/// 3. Simple inferential tests (t-test and chi-square).
|
||||||
|
fn main() {
|
||||||
|
descriptive_demo();
|
||||||
|
println!("\n-----\n");
|
||||||
|
correlation_demo();
|
||||||
|
println!("\n-----\n");
|
||||||
|
inferential_demo();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn descriptive_demo() {
|
||||||
|
println!("Descriptive statistics\n----------------------");
|
||||||
|
let data = Matrix::from_vec(vec![1.0, 2.0, 3.0, 4.0, 5.0], 1, 5);
|
||||||
|
println!("mean : {:.2}", mean(&data));
|
||||||
|
println!("std dev : {:.2}", stddev(&data));
|
||||||
|
println!("median : {:.2}", median(&data));
|
||||||
|
println!("25th percentile: {:.2}", percentile(&data, 25.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn correlation_demo() {
|
||||||
|
println!("Covariance and Correlation\n--------------------------");
|
||||||
|
let x = Matrix::from_vec(vec![1.0, 2.0, 3.0, 4.0], 2, 2);
|
||||||
|
let y = Matrix::from_vec(vec![1.0, 2.0, 3.0, 5.0], 2, 2);
|
||||||
|
let cov = covariance(&x, &y);
|
||||||
|
let cov_mat = covariance_matrix(&x, Axis::Col);
|
||||||
|
let corr = pearson(&x, &y);
|
||||||
|
println!("covariance : {:.2}", cov);
|
||||||
|
println!("cov matrix : {:?}", cov_mat.data());
|
||||||
|
println!("pearson r : {:.2}", corr);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn inferential_demo() {
|
||||||
|
println!("Inferential statistics\n----------------------");
|
||||||
|
let s1 = Matrix::from_vec(vec![1.0, 2.0, 3.0, 4.0, 5.0], 1, 5);
|
||||||
|
let s2 = Matrix::from_vec(vec![6.0, 7.0, 8.0, 9.0, 10.0], 1, 5);
|
||||||
|
let (t_stat, t_p) = t_test(&s1, &s2);
|
||||||
|
println!("t statistic : {:.2}, p-value: {:.4}", t_stat, t_p);
|
||||||
|
|
||||||
|
let observed = Matrix::from_vec(vec![12.0, 5.0, 8.0, 10.0], 2, 2);
|
||||||
|
let (chi2, chi_p) = chi2_test(&observed);
|
||||||
|
println!("chi^2 : {:.2}, p-value: {:.4}", chi2, chi_p);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
const EPS: f64 = 1e-8;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_descriptive_demo() {
|
||||||
|
let data = Matrix::from_vec(vec![1.0, 2.0, 3.0, 4.0, 5.0], 1, 5);
|
||||||
|
assert!((mean(&data) - 3.0).abs() < EPS);
|
||||||
|
assert!((stddev(&data) - 1.4142135623730951).abs() < EPS);
|
||||||
|
assert!((median(&data) - 3.0).abs() < EPS);
|
||||||
|
assert!((percentile(&data, 25.0) - 2.0).abs() < EPS);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_correlation_demo() {
|
||||||
|
let x = Matrix::from_rows_vec(vec![1.0, 2.0, 3.0, 4.0], 2, 2);
|
||||||
|
let y = Matrix::from_rows_vec(vec![1.0, 2.0, 3.0, 5.0], 2, 2);
|
||||||
|
let cov = covariance(&x, &y);
|
||||||
|
assert!((cov - 1.625).abs() < EPS);
|
||||||
|
let cov_mat = covariance_matrix(&x, Axis::Col);
|
||||||
|
assert!((cov_mat.get(0, 0) - 2.0).abs() < EPS);
|
||||||
|
assert!((cov_mat.get(1, 1) - 2.0).abs() < EPS);
|
||||||
|
let corr = pearson(&x, &y);
|
||||||
|
assert!((corr - 0.9827076298239908).abs() < 1e-6);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_inferential_demo() {
|
||||||
|
let s1 = Matrix::from_rows_vec(vec![1.0, 2.0, 3.0, 4.0, 5.0], 1, 5);
|
||||||
|
let s2 = Matrix::from_rows_vec(vec![6.0, 7.0, 8.0, 9.0, 10.0], 1, 5);
|
||||||
|
let (t_stat, p_value) = t_test(&s1, &s2);
|
||||||
|
assert!((t_stat + 5.0).abs() < 1e-5);
|
||||||
|
assert!(p_value > 0.0 && p_value < 1.0);
|
||||||
|
|
||||||
|
let observed = Matrix::from_rows_vec(vec![12.0, 5.0, 8.0, 10.0], 2, 2);
|
||||||
|
let (chi2, p) = chi2_test(&observed);
|
||||||
|
assert!(chi2 > 0.0);
|
||||||
|
assert!(p > 0.0 && p < 1.0);
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user