Iterators

This commit is contained in:
Anthony Scemama 2023-10-19 18:42:05 +02:00
commit 9496db0255
5 changed files with 316 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/target

7
Cargo.lock generated Normal file
View File

@ -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"

8
Cargo.toml Normal file
View File

@ -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]

41
src/main.rs Normal file
View File

@ -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!("");
}

259
src/matrix.rs Normal file
View File

@ -0,0 +1,259 @@
#[derive(Debug)]
pub struct Matrix<T> {
nrows: usize,
ncols: usize,
data: Vec<T>,
}
impl<T> Matrix<T>
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::Item> {
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::Item> {
self.iter.next()
}
}
impl<T> Matrix<T> {
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<std::slice::Iter<'a, T>>,
}
impl<'a, T> Iterator for MatrixIterRow<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> {
self.iter.next()
}
}
pub struct MatrixIterRowMut<'a, T> {
iter: std::iter::StepBy<std::slice::IterMut<'a, T>>,
}
impl<'a, T> Iterator for MatrixIterRowMut<'a, T> {
type Item = &'a mut T;
fn next(&mut self) -> Option<Self::Item> {
self.iter.next()
}
}
impl<T> Matrix<T> {
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::Item> {
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::Item> {
self.iter.next()
}
}
impl<T> Matrix<T> {
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<T>,
iter: MatrixIterRow<'a, T>,
row: std::ops::Range <usize>,
}
impl<'a, T> Iterator for MatrixIter1DRow<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> {
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<T>,
iter: MatrixIterRowMut<'a, T>,
row: std::ops::Range <usize>,
}
/*
impl<'a, T> Iterator for MatrixIter1DRowMut<'a, T> {
type Item = &'a mut T;
fn next(&mut self) -> Option<Self::Item> {
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<T> Matrix<T> {
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,
}
}
*/
}