From a451ba8cc78f0efeb9a64fb073fc5115dd505288 Mon Sep 17 00:00:00 2001 From: Palash Tyagi <23239946+Magnus167@users.noreply.github.com> Date: Sat, 2 Aug 2025 21:21:09 +0100 Subject: [PATCH 1/4] Clean up comments and formatting in Game of Life example --- examples/game_of_life.rs | 58 +++++----------------------------------- 1 file changed, 6 insertions(+), 52 deletions(-) diff --git a/examples/game_of_life.rs b/examples/game_of_life.rs index e596cda..5110092 100644 --- a/examples/game_of_life.rs +++ b/examples/game_of_life.rs @@ -3,7 +3,7 @@ //! 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 rustframe::matrix::{BoolMatrix, BoolOps, IntMatrix, Matrix}; use rustframe::random::{rng, Rng}; @@ -21,8 +21,6 @@ fn main() { let debug_mode = args.contains(&"--debug".to_string()); let print_mode = if debug_mode { false } else { PRINT_BOARD }; - // Initialize the game board. - // This demonstrates `BoolMatrix::from_vec`. let mut current_board = BoolMatrix::from_vec(vec![false; BOARD_SIZE * BOARD_SIZE], BOARD_SIZE, BOARD_SIZE); @@ -31,15 +29,11 @@ fn main() { add_simulated_activity(&mut current_board, BOARD_SIZE); let mut generation_count: u32 = 0; - // `previous_board_state` will store a clone of the board. - // This demonstrates `Matrix::clone()` and later `PartialEq` for `Matrix`. let mut previous_board_state: Option = None; let mut board_hashes = Vec::new(); - // let mut print_board_bool = true; let mut print_bool_int = 0; loop { - // if print_board_bool { if print_bool_int % SKIP_FRAMES == 0 { print_board(¤t_board, generation_count, print_mode); @@ -47,7 +41,6 @@ fn main() { } else { print_bool_int += 1; } - // `current_board.count()` demonstrates a method from `BoolOps`. board_hashes.push(hash_board(¤t_board, primes.clone())); if detect_stable_state(¤t_board, &previous_board_state) { println!( @@ -68,10 +61,8 @@ fn main() { add_simulated_activity(&mut current_board, BOARD_SIZE); } - // `current_board.clone()` demonstrates `Clone` for `Matrix`. previous_board_state = Some(current_board.clone()); - // This is the core call to your game logic. let next_board = game_of_life_next_frame(¤t_board); current_board = next_board; @@ -106,7 +97,6 @@ fn print_board(board: &BoolMatrix, generation_count: u32, print_mode: bool) { print_str.push_str("| "); for c in 0..board.cols() { if board[(r, c)] { - // Using Index trait for Matrix print_str.push_str("██"); } else { print_str.push_str(" "); @@ -188,74 +178,38 @@ pub fn game_of_life_next_frame(current_game: &BoolMatrix) -> BoolMatrix { if rows == 0 && cols == 0 { return BoolMatrix::from_vec(vec![], 0, 0); // Return an empty BoolMatrix } - // Assuming valid non-empty dimensions (e.g., 25x25) as per typical GOL. - // Your Matrix::from_vec would panic for other invalid 0-dim cases. - // Define the 8 neighbor offsets (row_delta, col_delta) let neighbor_offsets: [(isize, isize); 8] = [ (-1, -1), (-1, 0), - (-1, 1), // Top row (NW, N, NE) + (-1, 1), (0, -1), - (0, 1), // Middle row (W, E) + (0, 1), (1, -1), (1, 0), - (1, 1), // Bottom row (SW, S, SE) + (1, 1), ]; - // 1. Initialize `neighbor_counts` with the first shifted layer. - // This demonstrates creating an IntMatrix from a function and using it as a base. let (first_dr, first_dc) = neighbor_offsets[0]; let mut neighbor_counts = get_shifted_neighbor_layer(current_game, first_dr, first_dc); - // 2. Add the remaining 7 neighbor layers. - // This demonstrates element-wise addition of matrices (`Matrix + Matrix`). for i in 1..neighbor_offsets.len() { let (dr, dc) = neighbor_offsets[i]; let next_neighbor_layer = get_shifted_neighbor_layer(current_game, dr, dc); - // `neighbor_counts` (owned IntMatrix) + `next_neighbor_layer` (owned IntMatrix) - // uses `impl Add for Matrix`, consumes both, returns new owned `IntMatrix`. neighbor_counts = neighbor_counts + next_neighbor_layer; } - // 3. Apply Game of Life rules using element-wise operations. - - // Rule: Survival or Birth based on neighbor counts. - // A cell is alive in the next generation if: - // (it's currently alive AND has 2 or 3 neighbors) OR - // (it's currently dead AND has exactly 3 neighbors) - - // `neighbor_counts.eq_elem(scalar)`: - // Demonstrates element-wise comparison of a Matrix with a scalar (broadcast). - // Returns an owned `BoolMatrix`. let has_2_neighbors = neighbor_counts.eq_elem(2); - let has_3_neighbors = neighbor_counts.eq_elem(3); // This will be reused + let has_3_neighbors = neighbor_counts.eq_elem(3); - // `has_2_neighbors | has_3_neighbors`: - // Demonstrates element-wise OR (`Matrix | Matrix`). - // Consumes both operands, returns an owned `BoolMatrix`. - let has_2_or_3_neighbors = has_2_neighbors | has_3_neighbors.clone(); // Clone has_3_neighbors as it's used again + let has_2_or_3_neighbors = has_2_neighbors | has_3_neighbors.clone(); - // `current_game & &has_2_or_3_neighbors`: - // `current_game` is `&BoolMatrix`. `has_2_or_3_neighbors` is owned. - // Demonstrates element-wise AND (`&Matrix & &Matrix`). - // Borrows both operands, returns an owned `BoolMatrix`. let survives = current_game & &has_2_or_3_neighbors; - // `!current_game`: - // Demonstrates element-wise NOT (`!&Matrix`). - // Borrows operand, returns an owned `BoolMatrix`. let is_dead = !current_game; - // `is_dead & &has_3_neighbors`: - // `is_dead` is owned. `has_3_neighbors` is owned. - // Demonstrates element-wise AND (`Matrix & &Matrix`). - // Consumes `is_dead`, borrows `has_3_neighbors`, returns an owned `BoolMatrix`. let births = is_dead & &has_3_neighbors; - // `survives | births`: - // Demonstrates element-wise OR (`Matrix | Matrix`). - // Consumes both operands, returns an owned `BoolMatrix`. let next_frame_game = survives | births; next_frame_game From 5509416d5f9c648b251f8db9a07c8bcb3ad216c9 Mon Sep 17 00:00:00 2001 From: Palash Tyagi <23239946+Magnus167@users.noreply.github.com> Date: Sat, 2 Aug 2025 21:22:01 +0100 Subject: [PATCH 2/4] Remove unused logo comment from README.md --- README.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/README.md b/README.md index 8d0b05b..c162e99 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,5 @@ # rustframe - - - - 📚 [Docs](https://magnus167.github.io/rustframe/) | 🐙 [GitHub](https://github.com/Magnus167/rustframe) | 🌐 [Gitea mirror](https://gitea.nulltech.uk/Magnus167/rustframe) | 🦀 [Crates.io](https://crates.io/crates/rustframe) | 🔖 [docs.rs](https://docs.rs/rustframe/latest/rustframe/) From 77203123544faa2765e2e9a841176c8fb7cc476d Mon Sep 17 00:00:00 2001 From: Palash Tyagi <23239946+Magnus167@users.noreply.github.com> Date: Sat, 2 Aug 2025 21:59:22 +0100 Subject: [PATCH 3/4] Improve comments for clarity in logistic regression, stats overview, PCA, correlation, descriptive statistics, and matrix tests --- examples/logistic_regression.rs | 2 +- examples/stats_overview.rs | 6 ++--- src/compute/models/pca.rs | 16 ++------------ src/compute/stats/correlation.rs | 38 +++++++------------------------- src/compute/stats/descriptive.rs | 6 +---- src/matrix/mat.rs | 21 +++++------------- src/matrix/seriesops.rs | 11 ++------- 7 files changed, 22 insertions(+), 78 deletions(-) diff --git a/examples/logistic_regression.rs b/examples/logistic_regression.rs index 652f811..0d20e42 100644 --- a/examples/logistic_regression.rs +++ b/examples/logistic_regression.rs @@ -16,7 +16,7 @@ fn student_passing_example() { // 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 + // 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 x = Matrix::from_vec(hours.clone(), hours.len(), 1); diff --git a/examples/stats_overview.rs b/examples/stats_overview.rs index fe25ba7..c25f619 100644 --- a/examples/stats_overview.rs +++ b/examples/stats_overview.rs @@ -6,9 +6,9 @@ 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). +/// - Basic descriptive statistics on a small data set +/// - Covariance and correlation calculations +/// - Simple inferential tests (t-test and chi-square) fn main() { descriptive_demo(); println!("\n-----\n"); diff --git a/src/compute/models/pca.rs b/src/compute/models/pca.rs index f75231d..a517bd7 100644 --- a/src/compute/models/pca.rs +++ b/src/compute/models/pca.rs @@ -44,11 +44,7 @@ mod tests { #[test] fn test_pca_basic() { - // Simple 2D data, points along y=x line - // Data: - // 1.0, 1.0 - // 2.0, 2.0 - // 3.0, 3.0 + // Simple 2D data with points along the y = x line 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(); @@ -71,15 +67,7 @@ mod tests { assert!((pca.components.get(0, 0) - 1.0).abs() < EPSILON); assert!((pca.components.get(0, 1) - 1.0).abs() < EPSILON); - // Test transform - // 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 + // Test transform: centered data projects to [-2.0, 0.0, 2.0] let transformed_data = pca.transform(&data); assert_eq!(transformed_data.rows(), 3); assert_eq!(transformed_data.cols(), 1); diff --git a/src/compute/stats/correlation.rs b/src/compute/stats/correlation.rs index 22667f9..ac9ee19 100644 --- a/src/compute/stats/correlation.rs +++ b/src/compute/stats/correlation.rs @@ -137,10 +137,7 @@ mod tests { #[test] fn test_covariance_scalar_same_matrix() { - // M = - // 1,2 - // 3,4 - // mean = 2.5 + // Matrix with rows [1, 2] and [3, 4]; mean is 2.5 let data = vec![1.0, 2.0, 3.0, 4.0]; let m = Matrix::from_vec(data.clone(), 2, 2); @@ -152,10 +149,7 @@ mod tests { #[test] fn test_covariance_scalar_diff_matrix() { - // x = - // 1,2 - // 3,4 - // y = 2*x + // Matrix x has rows [1, 2] and [3, 4]; y is two times x 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); @@ -167,10 +161,7 @@ mod tests { #[test] fn test_covariance_vertical() { - // M = - // 1,2 - // 3,4 - // cols are [1,3] and [2,4], each var=1, cov=1 + // Matrix with rows [1, 2] and [3, 4]; columns 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 cov_mat = covariance_vertical(&m); @@ -184,10 +175,7 @@ mod tests { #[test] fn test_covariance_horizontal() { - // M = - // 1,2 - // 3,4 - // rows are [1,2] and [3,4], each var=0.25, cov=0.25 + // Matrix with rows [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 cov_mat = covariance_horizontal(&m); @@ -201,10 +189,7 @@ mod tests { #[test] fn test_covariance_matrix_vertical() { - // Test with a simple 2x2 matrix - // M = - // 1, 2 - // 3, 4 + // Test with a simple 2x2 matrix with rows [1, 2] and [3, 4] // Expected covariance matrix (vertical, i.e., between columns): // Col1: [1, 3], mean = 2 // 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(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 - // Expected: - // 2, 2 - // 2, 2 + // Expected matrix filled with 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); @@ -226,10 +209,7 @@ mod tests { #[test] fn test_covariance_matrix_horizontal() { - // Test with a simple 2x2 matrix - // M = - // 1, 2 - // 3, 4 + // Test with a simple 2x2 matrix with rows [1, 2] and [3, 4] // Expected covariance matrix (horizontal, i.e., between rows): // Row1: [1, 2], mean = 1.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(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 - // Expected: - // 0.5, -0.5 - // -0.5, 0.5 + // Expected matrix: [[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 cov_mat = covariance_matrix(&m, Axis::Row); diff --git a/src/compute/stats/descriptive.rs b/src/compute/stats/descriptive.rs index 126904e..71510ff 100644 --- a/src/compute/stats/descriptive.rs +++ b/src/compute/stats/descriptive.rs @@ -350,11 +350,7 @@ mod tests { let data: Vec = (1..=24).map(|x| x as f64).collect(); let x = Matrix::from_vec(data, 4, 6); - // columns: - // 1, 5, 9, 13, 17, 21 - // 2, 6, 10, 14, 18, 22 - // 3, 7, 11, 15, 19, 23 - // 4, 8, 12, 16, 20, 24 + // columns contain sequences increasing by four starting at 1 through 4 let er0 = vec![1., 5., 9., 13., 17., 21.]; let er50 = vec![3., 7., 11., 15., 19., 23.]; diff --git a/src/matrix/mat.rs b/src/matrix/mat.rs index 6709f07..79e344b 100644 --- a/src/matrix/mat.rs +++ b/src/matrix/mat.rs @@ -1028,9 +1028,7 @@ mod tests { #[test] fn test_from_rows_vec() { - // Representing: - // 1 2 3 - // 4 5 6 + // Matrix with rows [1, 2, 3] and [4, 5, 6] 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); @@ -1042,19 +1040,14 @@ mod tests { // Helper function to create a basic Matrix for testing fn static_test_matrix() -> Matrix { - // Column-major data: - // 1 4 7 - // 2 5 8 - // 3 6 9 + // Column-major data representing a 3x3 matrix of sequential integers let data = vec![1, 2, 3, 4, 5, 6, 7, 8, 9]; Matrix::from_vec(data, 3, 3) } // Another helper for a different size fn static_test_matrix_2x4() -> Matrix { - // Column-major data: - // 1 3 5 7 - // 2 4 6 8 + // Column-major data representing a 2x4 matrix of sequential integers let data = vec![1, 2, 3, 4, 5, 6, 7, 8]; Matrix::from_vec(data, 2, 4) } @@ -1132,10 +1125,7 @@ mod tests { #[test] fn test_from_cols_basic() { - // Representing: - // 1 4 7 - // 2 5 8 - // 3 6 9 + // Matrix with columns forming a 3x3 sequence let cols_data = vec![vec![1, 2, 3], vec![4, 5, 6], vec![7, 8, 9]]; let matrix = Matrix::from_cols(cols_data); @@ -1512,8 +1502,7 @@ mod tests { // Delete the first row matrix.delete_row(0); - // Should be: - // 3 6 9 + // Resulting data should be [3, 6, 9] assert_eq!(matrix.rows(), 1); assert_eq!(matrix.cols(), 3); assert_eq!(matrix.data(), &[3, 6, 9]); diff --git a/src/matrix/seriesops.rs b/src/matrix/seriesops.rs index 7072130..99f89d3 100644 --- a/src/matrix/seriesops.rs +++ b/src/matrix/seriesops.rs @@ -215,20 +215,13 @@ mod tests { // Helper function to create a FloatMatrix for SeriesOps testing fn create_float_test_matrix() -> FloatMatrix { - // 3x3 matrix (column-major) with some NaNs - // 1.0 4.0 7.0 - // 2.0 NaN 8.0 - // 3.0 6.0 NaN + // 3x3 column-major matrix containing a few NaN values 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) } fn create_float_test_matrix_4x4() -> FloatMatrix { - // 4x4 matrix (column-major) with some NaNs - // 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 + // 4x4 column-major matrix with NaNs inserted at positions where index % 5 == 0 // first make array with 16 elements FloatMatrix::from_vec( (0..16) From d741c7f472c853d5f82bf11abb0323d1787f08f4 Mon Sep 17 00:00:00 2001 From: Palash Tyagi <23239946+Magnus167@users.noreply.github.com> Date: Sat, 2 Aug 2025 21:59:42 +0100 Subject: [PATCH 4/4] Remove expected output comments from matrix operations examples in README.md --- README.md | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/README.md b/README.md index c162e99..5dcf88a 100644 --- a/README.md +++ b/README.md @@ -127,10 +127,6 @@ let mc: Matrix = Matrix::from_cols(vec![vec![1.0, 2.0], vec![3.0, 4.0]]); let md: Matrix = Matrix::from_cols(vec![vec![5.0, 6.0], vec![7.0, 8.0]]); let mul_result: Matrix = mc.matrix_mul(&md); // Expected: -// 1*5 + 3*6 = 5 + 18 = 23 -// 2*5 + 4*6 = 10 + 24 = 34 -// 1*7 + 3*8 = 7 + 24 = 31 -// 2*7 + 4*8 = 14 + 32 = 46 assert_eq!(mul_result.data(), &[23.0, 34.0, 31.0, 46.0]); // Dot product (alias for matrix_mul for FloatMatrix) @@ -139,14 +135,7 @@ assert_eq!(dot_result, mul_result); // Transpose let original_matrix: Matrix = Matrix::from_cols(vec![vec![1.0, 2.0, 3.0], vec![4.0, 5.0, 6.0]]); -// Original: -// 1 4 -// 2 5 -// 3 6 let transposed_matrix: Matrix = original_matrix.transpose(); -// Transposed: -// 1 2 3 -// 4 5 6 assert_eq!(transposed_matrix.rows(), 2); assert_eq!(transposed_matrix.cols(), 3); assert_eq!(transposed_matrix.data(), &[1.0, 4.0, 2.0, 5.0, 3.0, 6.0]); @@ -155,10 +144,6 @@ assert_eq!(transposed_matrix.data(), &[1.0, 4.0, 2.0, 5.0, 3.0, 6.0]); let matrix = Matrix::from_cols(vec![vec![1.0, 2.0, 3.0], vec![4.0, 5.0, 6.0]]); // Map function to double each value let mapped_matrix = matrix.map(|x| x * 2.0); -// Expected data after mapping -// 2 8 -// 4 10 -// 6 12 assert_eq!(mapped_matrix.data(), &[2.0, 4.0, 6.0, 8.0, 10.0, 12.0]); // Zip @@ -166,9 +151,6 @@ let a = Matrix::from_cols(vec![vec![1.0, 2.0], vec![3.0, 4.0]]); // 2x2 matrix let b = Matrix::from_cols(vec![vec![5.0, 6.0], vec![7.0, 8.0]]); // 2x2 matrix // Zip function to add corresponding elements let zipped_matrix = a.zip(&b, |x, y| x + y); -// Expected data after zipping -// 6 10 -// 8 12 assert_eq!(zipped_matrix.data(), &[6.0, 8.0, 10.0, 12.0]); ```