commit 9496db0255d743fe978a744c59b53929689f3edb Author: Anthony Scemama Date: Thu Oct 19 18:42:05 2023 +0200 Iterators diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..ae869a8 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "submatrix" +version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..128fd24 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "submatrix" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..c8ff5f8 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,41 @@ +mod matrix; +use matrix::Matrix; + +fn main() { + let mut mat = Matrix::<_>::new(4,3, 0.0f64); + println!("nrows : {}", mat.nrows()); + println!("ncols : {}", mat.ncols()); + let mut k=0; + for x in mat.iter_1d_col_mut() { + *x = k as f64; + k += 1; + } + + println!("{:#?}", mat); + for i in mat.iter_1d_col() { + print!("{} ", *i); + } + println!(""); + + println!(""); + for r in 0..mat.nrows() { + for i in mat.iter_row(r) { + print!("{} ", *i); + } + println!(""); + } + + println!(""); + for r in 0..mat.ncols() { + for i in mat.iter_col(r) { + print!("{} ", *i); + } + println!(""); + } + println!(""); + + for i in mat.iter_1d_row() { + print!("{} ", *i); + } + println!(""); +} diff --git a/src/matrix.rs b/src/matrix.rs new file mode 100644 index 0000000..f85274d --- /dev/null +++ b/src/matrix.rs @@ -0,0 +1,259 @@ +#[derive(Debug)] +pub struct Matrix { + nrows: usize, + ncols: usize, + data: Vec, +} + + +impl Matrix +where + T: Clone, +{ + + pub fn new(nrows:usize, ncols:usize, init:T) -> Self { + Matrix { + nrows, ncols, + data: vec![ init ; nrows*ncols ] + } + } + + pub fn nrows(&self) -> usize { + self.nrows + } + + pub fn ncols(&self) -> usize { + self.ncols + } + + pub fn as_slice(&self) -> &[T] { + self.data.as_slice() + } + + pub fn as_mut_slice(&mut self) -> &mut [T] { + self.data.as_mut_slice() + } + +} + + +// One-dimensional iterators + +pub struct MatrixIter1DCol<'a, T> { + iter: std::slice::Iter<'a, T>, +} + +impl<'a, T> Iterator for MatrixIter1DCol<'a, T> { + type Item = &'a T; + + fn next(&mut self) -> Option { + self.iter.next() + } +} + + +pub struct MatrixIter1DColMut<'a, T> { + iter: std::slice::IterMut<'a, T>, +} + + +impl<'a, T> Iterator for MatrixIter1DColMut<'a, T> { + type Item = &'a mut T; + + fn next(&mut self) -> Option { + self.iter.next() + } +} + +impl Matrix { + pub fn iter_1d_col(&self) -> MatrixIter1DCol<'_, T> { + MatrixIter1DCol { + iter: self.data.iter(), + } + } + + pub fn iter_1d_col_mut(&mut self) -> MatrixIter1DColMut<'_, T> { + MatrixIter1DColMut { + iter: self.data.iter_mut(), + } + } +} + + + +// Row iterators + +pub struct MatrixIterRow<'a, T> { + iter: std::iter::StepBy>, +} + +impl<'a, T> Iterator for MatrixIterRow<'a, T> { + type Item = &'a T; + + fn next(&mut self) -> Option { + self.iter.next() + } +} + + +pub struct MatrixIterRowMut<'a, T> { + iter: std::iter::StepBy>, +} + + +impl<'a, T> Iterator for MatrixIterRowMut<'a, T> { + type Item = &'a mut T; + + fn next(&mut self) -> Option { + self.iter.next() + } +} + + +impl Matrix { + pub fn iter_row(&self, row: usize) -> MatrixIterRow<'_, T> { + MatrixIterRow { + iter: self.data[row..].iter().step_by(self.nrows), + } + } + + pub fn iter_row_mut(&mut self, row: usize) -> MatrixIterRowMut<'_, T> { + MatrixIterRowMut { + iter: self.data[row..].iter_mut().step_by(self.nrows), + } + } +} + + +// Column iterators + +pub struct MatrixIterCol<'a, T> { + iter: std::slice::Iter<'a, T>, +} + +impl<'a, T> Iterator for MatrixIterCol<'a, T> { + type Item = &'a T; + + fn next(&mut self) -> Option { + self.iter.next() + } +} + + +pub struct MatrixIterColMut<'a, T> { + iter: std::slice::IterMut<'a, T>, +} + + +impl<'a, T> Iterator for MatrixIterColMut<'a, T> { + type Item = &'a mut T; + + fn next(&mut self) -> Option { + self.iter.next() + } +} + + +impl Matrix { + pub fn iter_col(&self, col: usize) -> MatrixIterCol<'_, T> { + let nrows = self.nrows; + let start = col*nrows; + let end = start+nrows; + MatrixIterCol { + iter: self.data[start..end].iter(), + } + } + + pub fn iter_col_mut(&mut self, col: usize) -> MatrixIterColMut<'_, T> { + let nrows = self.nrows; + let start = col*nrows; + let end = start+nrows; + MatrixIterColMut { + iter: self.data[start..end].iter_mut(), + } + } +} + + + +// One-dimensional iterator by row + +pub struct MatrixIter1DRow<'a, T> { + mat: &'a Matrix, + iter: MatrixIterRow<'a, T>, + row: std::ops::Range , +} + +impl<'a, T> Iterator for MatrixIter1DRow<'a, T> { + type Item = &'a T; + + fn next(&mut self) -> Option { + let v = self.iter.next(); + match v { + Some(_) => v, + None => { + let new_row = self.row.next(); + match new_row { + None => None, + Some(i) => { + self.iter = self.mat.iter_row(i); + self.iter.next() + } + } + } + } + } +} + +pub struct MatrixIter1DRowMut<'a, T> { + mat: &'a mut Matrix, + iter: MatrixIterRowMut<'a, T>, + row: std::ops::Range , +} + + +/* +impl<'a, T> Iterator for MatrixIter1DRowMut<'a, T> { + type Item = &'a mut T; + + fn next(&mut self) -> Option { + let v = self.iter.next(); + match v { + Some(_) => v, + None => { + let new_row = self.row.next(); + match new_row { + None => None, + Some(i) => { + self.iter = self.mat.iter_row_mut(i); + self.iter.next() + } + } + } + } + } +} +*/ + +impl Matrix { + pub fn iter_1d_row(&self) -> MatrixIter1DRow<'_, T> { + MatrixIter1DRow { + mat: self, + iter: self.iter_row(0), + row: 1..self.nrows, + } + } + + /* + pub fn iter_1d_row_mut(&mut self) -> MatrixIter1DRowMut<'_, T> { + MatrixIter1DRowMut { + mat: self, + iter: self.iter_row_mut(0), + row: 1..self.nrows, + } + } + */ +} + + +