Improve comments for clarity in logistic regression, stats overview, PCA, correlation, descriptive statistics, and matrix tests

This commit is contained in:
Palash Tyagi 2025-08-02 21:59:22 +01:00
parent 5509416d5f
commit 7720312354
7 changed files with 22 additions and 78 deletions

View File

@ -16,7 +16,7 @@ fn student_passing_example() {
// Hours studied for each student // 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]; 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 // Label: 0 denotes failure and 1 denotes success
let passed = vec![0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.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 x = Matrix::from_vec(hours.clone(), hours.len(), 1);

View File

@ -6,9 +6,9 @@ use rustframe::matrix::{Axis, Matrix};
/// Demonstrates some of the statistics utilities in Rustframe. /// Demonstrates some of the statistics utilities in Rustframe.
/// ///
/// The example is split into three parts: /// The example is split into three parts:
/// 1. Basic descriptive statistics on a small data set. /// - Basic descriptive statistics on a small data set
/// 2. Covariance and correlation calculations. /// - Covariance and correlation calculations
/// 3. Simple inferential tests (t-test and chi-square). /// - Simple inferential tests (t-test and chi-square)
fn main() { fn main() {
descriptive_demo(); descriptive_demo();
println!("\n-----\n"); println!("\n-----\n");

View File

@ -44,11 +44,7 @@ mod tests {
#[test] #[test]
fn test_pca_basic() { fn test_pca_basic() {
// Simple 2D data, points along y=x line // Simple 2D data with points along the y = x line
// Data:
// 1.0, 1.0
// 2.0, 2.0
// 3.0, 3.0
let data = Matrix::from_rows_vec(vec![1.0, 1.0, 2.0, 2.0, 3.0, 3.0], 3, 2); let data = Matrix::from_rows_vec(vec![1.0, 1.0, 2.0, 2.0, 3.0, 3.0], 3, 2);
let (_n_samples, _n_features) = data.shape(); let (_n_samples, _n_features) = data.shape();
@ -71,15 +67,7 @@ mod tests {
assert!((pca.components.get(0, 0) - 1.0).abs() < EPSILON); assert!((pca.components.get(0, 0) - 1.0).abs() < EPSILON);
assert!((pca.components.get(0, 1) - 1.0).abs() < EPSILON); assert!((pca.components.get(0, 1) - 1.0).abs() < EPSILON);
// Test transform // Test transform: centered data projects to [-2.0, 0.0, 2.0]
// Centered data:
// -1.0, -1.0
// 0.0, 0.0
// 1.0, 1.0
// Projected: (centered_data * components.transpose())
// (-1.0 * 1.0 + -1.0 * 1.0) = -2.0
// ( 0.0 * 1.0 + 0.0 * 1.0) = 0.0
// ( 1.0 * 1.0 + 1.0 * 1.0) = 2.0
let transformed_data = pca.transform(&data); let transformed_data = pca.transform(&data);
assert_eq!(transformed_data.rows(), 3); assert_eq!(transformed_data.rows(), 3);
assert_eq!(transformed_data.cols(), 1); assert_eq!(transformed_data.cols(), 1);

View File

@ -137,10 +137,7 @@ mod tests {
#[test] #[test]
fn test_covariance_scalar_same_matrix() { fn test_covariance_scalar_same_matrix() {
// M = // Matrix with rows [1, 2] and [3, 4]; mean is 2.5
// 1,2
// 3,4
// mean = 2.5
let data = vec![1.0, 2.0, 3.0, 4.0]; let data = vec![1.0, 2.0, 3.0, 4.0];
let m = Matrix::from_vec(data.clone(), 2, 2); let m = Matrix::from_vec(data.clone(), 2, 2);
@ -152,10 +149,7 @@ mod tests {
#[test] #[test]
fn test_covariance_scalar_diff_matrix() { fn test_covariance_scalar_diff_matrix() {
// x = // Matrix x has rows [1, 2] and [3, 4]; y is two times x
// 1,2
// 3,4
// y = 2*x
let x = Matrix::from_vec(vec![1.0, 2.0, 3.0, 4.0], 2, 2); let x = Matrix::from_vec(vec![1.0, 2.0, 3.0, 4.0], 2, 2);
let y = Matrix::from_vec(vec![2.0, 4.0, 6.0, 8.0], 2, 2); let y = Matrix::from_vec(vec![2.0, 4.0, 6.0, 8.0], 2, 2);
@ -167,10 +161,7 @@ mod tests {
#[test] #[test]
fn test_covariance_vertical() { fn test_covariance_vertical() {
// M = // Matrix with rows [1, 2] and [3, 4]; columns are [1,3] and [2,4], each var=1, cov=1
// 1,2
// 3,4
// cols are [1,3] and [2,4], each var=1, cov=1
let m = Matrix::from_rows_vec(vec![1.0, 2.0, 3.0, 4.0], 2, 2); let m = Matrix::from_rows_vec(vec![1.0, 2.0, 3.0, 4.0], 2, 2);
let cov_mat = covariance_vertical(&m); let cov_mat = covariance_vertical(&m);
@ -184,10 +175,7 @@ mod tests {
#[test] #[test]
fn test_covariance_horizontal() { fn test_covariance_horizontal() {
// M = // Matrix with rows [1,2] and [3,4], each var=0.25, cov=0.25
// 1,2
// 3,4
// rows are [1,2] and [3,4], each var=0.25, cov=0.25
let m = Matrix::from_rows_vec(vec![1.0, 2.0, 3.0, 4.0], 2, 2); let m = Matrix::from_rows_vec(vec![1.0, 2.0, 3.0, 4.0], 2, 2);
let cov_mat = covariance_horizontal(&m); let cov_mat = covariance_horizontal(&m);
@ -201,10 +189,7 @@ mod tests {
#[test] #[test]
fn test_covariance_matrix_vertical() { fn test_covariance_matrix_vertical() {
// Test with a simple 2x2 matrix // Test with a simple 2x2 matrix with rows [1, 2] and [3, 4]
// M =
// 1, 2
// 3, 4
// Expected covariance matrix (vertical, i.e., between columns): // Expected covariance matrix (vertical, i.e., between columns):
// Col1: [1, 3], mean = 2 // Col1: [1, 3], mean = 2
// Col2: [2, 4], mean = 3 // Col2: [2, 4], mean = 3
@ -212,9 +197,7 @@ mod tests {
// Cov(Col2, Col2) = ((2-3)^2 + (4-3)^2) / (2-1) = (1+1)/1 = 2 // Cov(Col2, Col2) = ((2-3)^2 + (4-3)^2) / (2-1) = (1+1)/1 = 2
// Cov(Col1, Col2) = ((1-2)*(2-3) + (3-2)*(4-3)) / (2-1) = ((-1)*(-1) + (1)*(1))/1 = (1+1)/1 = 2 // Cov(Col1, Col2) = ((1-2)*(2-3) + (3-2)*(4-3)) / (2-1) = ((-1)*(-1) + (1)*(1))/1 = (1+1)/1 = 2
// Cov(Col2, Col1) = 2 // Cov(Col2, Col1) = 2
// Expected: // Expected matrix filled with 2
// 2, 2
// 2, 2
let m = Matrix::from_rows_vec(vec![1.0, 2.0, 3.0, 4.0], 2, 2); let m = Matrix::from_rows_vec(vec![1.0, 2.0, 3.0, 4.0], 2, 2);
let cov_mat = covariance_matrix(&m, Axis::Col); let cov_mat = covariance_matrix(&m, Axis::Col);
@ -226,10 +209,7 @@ mod tests {
#[test] #[test]
fn test_covariance_matrix_horizontal() { fn test_covariance_matrix_horizontal() {
// Test with a simple 2x2 matrix // Test with a simple 2x2 matrix with rows [1, 2] and [3, 4]
// M =
// 1, 2
// 3, 4
// Expected covariance matrix (horizontal, i.e., between rows): // Expected covariance matrix (horizontal, i.e., between rows):
// Row1: [1, 2], mean = 1.5 // Row1: [1, 2], mean = 1.5
// Row2: [3, 4], mean = 3.5 // Row2: [3, 4], mean = 3.5
@ -237,9 +217,7 @@ mod tests {
// Cov(Row2, Row2) = ((3-3.5)^2 + (4-3.5)^2) / (2-1) = (0.25+0.25)/1 = 0.5 // Cov(Row2, Row2) = ((3-3.5)^2 + (4-3.5)^2) / (2-1) = (0.25+0.25)/1 = 0.5
// Cov(Row1, Row2) = ((1-1.5)*(3-3.5) + (2-1.5)*(4-3.5)) / (2-1) = ((-0.5)*(-0.5) + (0.5)*(0.5))/1 = (0.25+0.25)/1 = 0.5 // Cov(Row1, Row2) = ((1-1.5)*(3-3.5) + (2-1.5)*(4-3.5)) / (2-1) = ((-0.5)*(-0.5) + (0.5)*(0.5))/1 = (0.25+0.25)/1 = 0.5
// Cov(Row2, Row1) = 0.5 // Cov(Row2, Row1) = 0.5
// Expected: // Expected matrix: [[0.5, -0.5], [-0.5, 0.5]]
// 0.5, -0.5
// -0.5, 0.5
let m = Matrix::from_rows_vec(vec![1.0, 2.0, 3.0, 4.0], 2, 2); let m = Matrix::from_rows_vec(vec![1.0, 2.0, 3.0, 4.0], 2, 2);
let cov_mat = covariance_matrix(&m, Axis::Row); let cov_mat = covariance_matrix(&m, Axis::Row);

View File

@ -350,11 +350,7 @@ mod tests {
let data: Vec<f64> = (1..=24).map(|x| x as f64).collect(); let data: Vec<f64> = (1..=24).map(|x| x as f64).collect();
let x = Matrix::from_vec(data, 4, 6); let x = Matrix::from_vec(data, 4, 6);
// columns: // columns contain sequences increasing by four starting at 1 through 4
// 1, 5, 9, 13, 17, 21
// 2, 6, 10, 14, 18, 22
// 3, 7, 11, 15, 19, 23
// 4, 8, 12, 16, 20, 24
let er0 = vec![1., 5., 9., 13., 17., 21.]; let er0 = vec![1., 5., 9., 13., 17., 21.];
let er50 = vec![3., 7., 11., 15., 19., 23.]; let er50 = vec![3., 7., 11., 15., 19., 23.];

View File

@ -1028,9 +1028,7 @@ mod tests {
#[test] #[test]
fn test_from_rows_vec() { fn test_from_rows_vec() {
// Representing: // Matrix with rows [1, 2, 3] and [4, 5, 6]
// 1 2 3
// 4 5 6
let rows_data = vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0]; let rows_data = vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0];
let matrix = Matrix::from_rows_vec(rows_data, 2, 3); let matrix = Matrix::from_rows_vec(rows_data, 2, 3);
@ -1042,19 +1040,14 @@ mod tests {
// Helper function to create a basic Matrix for testing // Helper function to create a basic Matrix for testing
fn static_test_matrix() -> Matrix<i32> { fn static_test_matrix() -> Matrix<i32> {
// Column-major data: // Column-major data representing a 3x3 matrix of sequential integers
// 1 4 7
// 2 5 8
// 3 6 9
let data = vec![1, 2, 3, 4, 5, 6, 7, 8, 9]; let data = vec![1, 2, 3, 4, 5, 6, 7, 8, 9];
Matrix::from_vec(data, 3, 3) Matrix::from_vec(data, 3, 3)
} }
// Another helper for a different size // Another helper for a different size
fn static_test_matrix_2x4() -> Matrix<i32> { fn static_test_matrix_2x4() -> Matrix<i32> {
// Column-major data: // Column-major data representing a 2x4 matrix of sequential integers
// 1 3 5 7
// 2 4 6 8
let data = vec![1, 2, 3, 4, 5, 6, 7, 8]; let data = vec![1, 2, 3, 4, 5, 6, 7, 8];
Matrix::from_vec(data, 2, 4) Matrix::from_vec(data, 2, 4)
} }
@ -1132,10 +1125,7 @@ mod tests {
#[test] #[test]
fn test_from_cols_basic() { fn test_from_cols_basic() {
// Representing: // Matrix with columns forming a 3x3 sequence
// 1 4 7
// 2 5 8
// 3 6 9
let cols_data = vec![vec![1, 2, 3], vec![4, 5, 6], vec![7, 8, 9]]; let cols_data = vec![vec![1, 2, 3], vec![4, 5, 6], vec![7, 8, 9]];
let matrix = Matrix::from_cols(cols_data); let matrix = Matrix::from_cols(cols_data);
@ -1512,8 +1502,7 @@ mod tests {
// Delete the first row // Delete the first row
matrix.delete_row(0); matrix.delete_row(0);
// Should be: // Resulting data should be [3, 6, 9]
// 3 6 9
assert_eq!(matrix.rows(), 1); assert_eq!(matrix.rows(), 1);
assert_eq!(matrix.cols(), 3); assert_eq!(matrix.cols(), 3);
assert_eq!(matrix.data(), &[3, 6, 9]); assert_eq!(matrix.data(), &[3, 6, 9]);

View File

@ -215,20 +215,13 @@ mod tests {
// Helper function to create a FloatMatrix for SeriesOps testing // Helper function to create a FloatMatrix for SeriesOps testing
fn create_float_test_matrix() -> FloatMatrix { fn create_float_test_matrix() -> FloatMatrix {
// 3x3 matrix (column-major) with some NaNs // 3x3 column-major matrix containing a few NaN values
// 1.0 4.0 7.0
// 2.0 NaN 8.0
// 3.0 6.0 NaN
let data = vec![1.0, 2.0, 3.0, 4.0, f64::NAN, 6.0, 7.0, 8.0, f64::NAN]; let data = vec![1.0, 2.0, 3.0, 4.0, f64::NAN, 6.0, 7.0, 8.0, f64::NAN];
FloatMatrix::from_vec(data, 3, 3) FloatMatrix::from_vec(data, 3, 3)
} }
fn create_float_test_matrix_4x4() -> FloatMatrix { fn create_float_test_matrix_4x4() -> FloatMatrix {
// 4x4 matrix (column-major) with some NaNs // 4x4 column-major matrix with NaNs inserted at positions where index % 5 == 0
// 1.0 5.0 9.0 13.0
// 2.0 NaN 10.0 NaN
// 3.0 6.0 NaN 14.0
// NaN 7.0 11.0 NaN
// first make array with 16 elements // first make array with 16 elements
FloatMatrix::from_vec( FloatMatrix::from_vec(
(0..16) (0..16)