mirror of
https://github.com/Magnus167/rustframe.git
synced 2025-08-20 04:30:01 +00:00
Compare commits
6 Commits
cdfc3adbf8
...
ebf0fff5c6
Author | SHA1 | Date | |
---|---|---|---|
![]() |
ebf0fff5c6 | ||
d851c500af | |||
![]() |
d741c7f472 | ||
![]() |
7720312354 | ||
![]() |
5509416d5f | ||
![]() |
a451ba8cc7 |
22
README.md
22
README.md
@ -1,9 +1,5 @@
|
||||
# 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/)
|
||||
|
||||
<!-- [](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 mul_result: Matrix<f64> = 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)
|
||||
@ -141,14 +133,7 @@ assert_eq!(dot_result, mul_result);
|
||||
|
||||
// Transpose
|
||||
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();
|
||||
// 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]);
|
||||
@ -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]]);
|
||||
// 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
|
||||
@ -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
|
||||
// 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]);
|
||||
```
|
||||
|
||||
|
@ -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<BoolMatrix> = 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<bool>
|
||||
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<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
|
||||
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<bool> & &Matrix<bool>`).
|
||||
// Borrows both operands, returns an owned `BoolMatrix`.
|
||||
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;
|
||||
|
||||
// `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;
|
||||
|
||||
// `survives | births`:
|
||||
// Demonstrates element-wise OR (`Matrix<bool> | Matrix<bool>`).
|
||||
// Consumes both operands, returns an owned `BoolMatrix`.
|
||||
let next_frame_game = survives | births;
|
||||
|
||||
next_frame_game
|
||||
|
@ -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);
|
||||
|
@ -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");
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -350,11 +350,7 @@ mod tests {
|
||||
let data: Vec<f64> = (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.];
|
||||
|
@ -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<i32> {
|
||||
// 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<i32> {
|
||||
// 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]);
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user