Compare commits

...

6 Commits

9 changed files with 28 additions and 152 deletions

View File

@ -1,9 +1,5 @@
# rustframe # rustframe
<!-- # <img align="center" alt="Rustframe" src=".github/rustframe_logo.png" height="50px" /> rustframe -->
<!-- though the centre tag doesn't work as it would normally, it achieves the desired effect -->
📚 [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/) 📚 [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/)
<!-- [![Last commit](https://img.shields.io/endpoint?url=https://magnus167.github.io/rustframe/rustframe/last-commit-date.json)](https://github.com/Magnus167/rustframe) --> <!-- [![Last commit](https://img.shields.io/endpoint?url=https://magnus167.github.io/rustframe/rustframe/last-commit-date.json)](https://github.com/Magnus167/rustframe) -->
@ -129,10 +125,6 @@ let mc: Matrix<f64> = Matrix::from_cols(vec![vec![1.0, 2.0], vec![3.0, 4.0]]);
let md: Matrix<f64> = Matrix::from_cols(vec![vec![5.0, 6.0], vec![7.0, 8.0]]); let md: Matrix<f64> = Matrix::from_cols(vec![vec![5.0, 6.0], vec![7.0, 8.0]]);
let mul_result: Matrix<f64> = mc.matrix_mul(&md); let mul_result: Matrix<f64> = mc.matrix_mul(&md);
// Expected: // 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]); assert_eq!(mul_result.data(), &[23.0, 34.0, 31.0, 46.0]);
// Dot product (alias for matrix_mul for FloatMatrix) // Dot product (alias for matrix_mul for FloatMatrix)
@ -141,14 +133,7 @@ assert_eq!(dot_result, mul_result);
// Transpose // Transpose
let original_matrix: Matrix<f64> = Matrix::from_cols(vec![vec![1.0, 2.0, 3.0], vec![4.0, 5.0, 6.0]]); let original_matrix: Matrix<f64> = 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<f64> = original_matrix.transpose(); let transposed_matrix: Matrix<f64> = original_matrix.transpose();
// Transposed:
// 1 2 3
// 4 5 6
assert_eq!(transposed_matrix.rows(), 2); assert_eq!(transposed_matrix.rows(), 2);
assert_eq!(transposed_matrix.cols(), 3); assert_eq!(transposed_matrix.cols(), 3);
assert_eq!(transposed_matrix.data(), &[1.0, 4.0, 2.0, 5.0, 3.0, 6.0]); assert_eq!(transposed_matrix.data(), &[1.0, 4.0, 2.0, 5.0, 3.0, 6.0]);
@ -157,10 +142,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]]); 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 // Map function to double each value
let mapped_matrix = matrix.map(|x| x * 2.0); 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]); assert_eq!(mapped_matrix.data(), &[2.0, 4.0, 6.0, 8.0, 10.0, 12.0]);
// Zip // Zip
@ -168,9 +149,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 let b = Matrix::from_cols(vec![vec![5.0, 6.0], vec![7.0, 8.0]]); // 2x2 matrix
// Zip function to add corresponding elements // Zip function to add corresponding elements
let zipped_matrix = a.zip(&b, |x, y| x + y); 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]); assert_eq!(zipped_matrix.data(), &[6.0, 8.0, 10.0, 12.0]);
``` ```

View File

@ -3,7 +3,7 @@
//! It demonstrates matrix operations like shifting, counting neighbors, and applying game rules. //! 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. //! 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. //! 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::matrix::{BoolMatrix, BoolOps, IntMatrix, Matrix};
use rustframe::random::{rng, Rng}; use rustframe::random::{rng, Rng};
@ -21,8 +21,6 @@ fn main() {
let debug_mode = args.contains(&"--debug".to_string()); let debug_mode = args.contains(&"--debug".to_string());
let print_mode = if debug_mode { false } else { PRINT_BOARD }; let print_mode = if debug_mode { false } else { PRINT_BOARD };
// Initialize the game board.
// This demonstrates `BoolMatrix::from_vec`.
let mut current_board = let mut current_board =
BoolMatrix::from_vec(vec![false; BOARD_SIZE * BOARD_SIZE], BOARD_SIZE, BOARD_SIZE); 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); add_simulated_activity(&mut current_board, BOARD_SIZE);
let mut generation_count: u32 = 0; 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<BoolMatrix> = None; let mut previous_board_state: Option<BoolMatrix> = None;
let mut board_hashes = Vec::new(); let mut board_hashes = Vec::new();
// let mut print_board_bool = true;
let mut print_bool_int = 0; let mut print_bool_int = 0;
loop { loop {
// if print_board_bool {
if print_bool_int % SKIP_FRAMES == 0 { if print_bool_int % SKIP_FRAMES == 0 {
print_board(&current_board, generation_count, print_mode); print_board(&current_board, generation_count, print_mode);
@ -47,7 +41,6 @@ fn main() {
} else { } else {
print_bool_int += 1; print_bool_int += 1;
} }
// `current_board.count()` demonstrates a method from `BoolOps`.
board_hashes.push(hash_board(&current_board, primes.clone())); board_hashes.push(hash_board(&current_board, primes.clone()));
if detect_stable_state(&current_board, &previous_board_state) { if detect_stable_state(&current_board, &previous_board_state) {
println!( println!(
@ -68,10 +61,8 @@ fn main() {
add_simulated_activity(&mut current_board, BOARD_SIZE); add_simulated_activity(&mut current_board, BOARD_SIZE);
} }
// `current_board.clone()` demonstrates `Clone` for `Matrix`.
previous_board_state = Some(current_board.clone()); previous_board_state = Some(current_board.clone());
// This is the core call to your game logic.
let next_board = game_of_life_next_frame(&current_board); let next_board = game_of_life_next_frame(&current_board);
current_board = next_board; current_board = next_board;
@ -106,7 +97,6 @@ fn print_board(board: &BoolMatrix, generation_count: u32, print_mode: bool) {
print_str.push_str("| "); print_str.push_str("| ");
for c in 0..board.cols() { for c in 0..board.cols() {
if board[(r, c)] { if board[(r, c)] {
// Using Index trait for Matrix<bool>
print_str.push_str("██"); print_str.push_str("██");
} else { } else {
print_str.push_str(" "); print_str.push_str(" ");
@ -188,74 +178,38 @@ pub fn game_of_life_next_frame(current_game: &BoolMatrix) -> BoolMatrix {
if rows == 0 && cols == 0 { if rows == 0 && cols == 0 {
return BoolMatrix::from_vec(vec![], 0, 0); // Return an empty BoolMatrix 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) // Define the 8 neighbor offsets (row_delta, col_delta)
let neighbor_offsets: [(isize, isize); 8] = [ let neighbor_offsets: [(isize, isize); 8] = [
(-1, -1), (-1, -1),
(-1, 0), (-1, 0),
(-1, 1), // Top row (NW, N, NE) (-1, 1),
(0, -1), (0, -1),
(0, 1), // Middle row (W, E) (0, 1),
(1, -1), (1, -1),
(1, 0), (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 (first_dr, first_dc) = neighbor_offsets[0];
let mut neighbor_counts = get_shifted_neighbor_layer(current_game, first_dr, first_dc); 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() { for i in 1..neighbor_offsets.len() {
let (dr, dc) = neighbor_offsets[i]; let (dr, dc) = neighbor_offsets[i];
let next_neighbor_layer = get_shifted_neighbor_layer(current_game, dr, dc); 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; 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_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`: let has_2_or_3_neighbors = has_2_neighbors | has_3_neighbors.clone();
// Demonstrates element-wise OR (`Matrix<bool> | Matrix<bool>`).
// 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
// `current_game & &has_2_or_3_neighbors`:
// `current_game` is `&BoolMatrix`. `has_2_or_3_neighbors` is owned.
// Demonstrates element-wise AND (`&Matrix<bool> & &Matrix<bool>`).
// Borrows both operands, returns an owned `BoolMatrix`.
let survives = current_game & &has_2_or_3_neighbors; let survives = current_game & &has_2_or_3_neighbors;
// `!current_game`:
// Demonstrates element-wise NOT (`!&Matrix<bool>`).
// Borrows operand, returns an owned `BoolMatrix`.
let is_dead = !current_game; let is_dead = !current_game;
// `is_dead & &has_3_neighbors`:
// `is_dead` is owned. `has_3_neighbors` is owned.
// Demonstrates element-wise AND (`Matrix<bool> & &Matrix<bool>`).
// Consumes `is_dead`, borrows `has_3_neighbors`, returns an owned `BoolMatrix`.
let births = is_dead & &has_3_neighbors; let births = is_dead & &has_3_neighbors;
// `survives | births`:
// Demonstrates element-wise OR (`Matrix<bool> | Matrix<bool>`).
// Consumes both operands, returns an owned `BoolMatrix`.
let next_frame_game = survives | births; let next_frame_game = survives | births;
next_frame_game next_frame_game

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)