diff -r 495448cca603 -r 6aa955ad8122 src/lingrid.rs --- a/src/lingrid.rs Thu May 01 08:40:33 2025 -0500 +++ b/src/lingrid.rs Thu May 01 13:06:58 2025 -0500 @@ -15,46 +15,54 @@ iteration over the grid. Additional utility functions are in the [`Grid`] trait. */ -use crate::types::*; +use crate::iter::{RestartableIterator, StatefulIterator}; use crate::loc::Loc; +use crate::maputil::{map2, map4}; use crate::sets::Cube; -use crate::iter::{RestartableIterator, StatefulIterator}; -use crate::maputil::{map2, map4}; -use serde::{Serialize, Deserialize}; +use crate::types::*; +use serde::{Deserialize, Serialize}; // TODO: rewrite this using crate::sets::Cube. /// An abstraction of possibly multi-dimensional linear grids. /// /// `U` is typically a `F` for a `Float` `F` for one-dimensional grids created by `linspace`, -/// or [`Loc`]`` for multi-dimensional grids created by `lingrid`. +/// or [`Loc`]`` for multi-dimensional grids created by `lingrid`. /// In the first case `count` of nodes is `usize`, and in the second case `[usize; N]`. #[derive(Clone, Copy, Debug, Serialize, Deserialize, Eq, PartialEq)] pub struct LinSpace { - pub start : U, - pub end : U, - pub count : I, + pub start: U, + pub end: U, + pub count: I, } /// A `N`-dimensional interval divided into an indicated number of equally-spaced nodes along /// each dimension. #[allow(type_alias_bounds)] // Need it to access F::CompatibleSize. -pub type LinGrid = LinSpace, [usize; N]>; +pub type LinGrid = LinSpace, [usize; N]>; /// Creates a [`LinSpace`] on the real line. -pub fn linspace(start : F, end : F, count : usize) -> LinSpace { - LinSpace{ start : start, end : end, count : count } +pub fn linspace(start: F, end: F, count: usize) -> LinSpace { + LinSpace { + start: start, + end: end, + count: count, + } } /// Creates a multi-dimensional linear grid. /// /// The first and last point in each dimension are the boundaries of the corresponding /// dimensions of `cube`, and there are `count` nodes along each dimension. -pub fn lingrid( - cube : &Cube, - count : &[usize; N] -) -> LinSpace, [usize; N]> { - LinSpace{ start : cube.span_start(), end : cube.span_end(), count : *count } +pub fn lingrid( + cube: &Cube, + count: &[usize; N], +) -> LinSpace, [usize; N]> { + LinSpace { + start: cube.span_start(), + end: cube.span_end(), + count: *count, + } } /// Create a multi-dimensional linear grid with centered nodes. @@ -63,30 +71,33 @@ /// inside `cube`. Thus, if $w\_i$ is the width of the cube along dimension $i$, and $n_i$ the number /// of nodes, the width of the subcube along this dimension is $h_i = w\_i/(n\_i+1)$, and the first /// and last nodes are at a distance $h\_i/2$ from the closest boundary. -pub fn lingrid_centered( - cube : &Cube, - count : &[usize; N] -) -> LinSpace, [usize; N]> { +pub fn lingrid_centered( + cube: &Cube, + count: &[usize; N], +) -> LinSpace, [usize; N]> { let h_div_2 = map2(cube.width(), count, |w, &n| w / F::cast_from(2 * (n + 1))); let span_start = map2(cube.span_start(), &h_div_2, |a, &t| a + t).into(); - let span_end = map2(cube.span_end(), &h_div_2, |b, &t| b - t).into(); - LinSpace{ start : span_start, end : span_end, count : *count } + let span_end = map2(cube.span_end(), &h_div_2, |b, &t| b - t).into(); + LinSpace { + start: span_start, + end: span_end, + count: *count, + } } - /// Iterator over a `LinSpace`. #[derive(Clone, Debug)] pub struct LinSpaceIterator { - lingrid : LinSpace, - current : Option, + lingrid: LinSpace, + current: Option, } /// Abstraction of a linear grid over space `U` with multi-dimensional index set `I`. pub trait Grid { /// Converts a linear index `i` into a grid point. - fn entry_linear_unchecked(&self, i : usize) -> U; + fn entry_linear_unchecked(&self, i: usize) -> U; // Converts a multi-dimensional index `i` into a grid point. - fn entry_unchecked(&self, i : &I) -> U; + fn entry_unchecked(&self, i: &I) -> U; // fn entry(&self, i : I) -> Option } @@ -97,7 +108,7 @@ fn next_index(&mut self) -> Option; } -impl, I : Unsigned> Grid for LinSpace { +impl, I: Unsigned> Grid for LinSpace { /*fn entry(&self, i : I) -> Option { if i < self.count { Some(self.entry_unchecked(i)) @@ -107,37 +118,40 @@ }*/ #[inline] - fn entry_linear_unchecked(&self, i : usize) -> F { + fn entry_linear_unchecked(&self, i: usize) -> F { self.entry_unchecked(&I::cast_from(i)) } #[inline] - fn entry_unchecked(&self, i : &I) -> F { + fn entry_unchecked(&self, i: &I) -> F { let idx = F::cast_from(*i); - let scale = F::cast_from(self.count-I::ONE); - self.start + (self.end-self.start)*idx/scale + let scale = F::cast_from(self.count - I::ONE); + self.start + (self.end - self.start) * idx / scale } } -impl, I : Unsigned> GridIteration -for LinSpaceIterator { +impl, I: Unsigned> GridIteration for LinSpaceIterator { #[inline] fn next_index(&mut self) -> Option { match self.current { - None if I::ZERO < self.lingrid.count - => { self.current = Some(I::ZERO); self.current } - Some(v) if v+I::ONE < self.lingrid.count - => { self.current = Some(v+I::ONE); self.current } - _ - => { None } + None if I::ZERO < self.lingrid.count => { + self.current = Some(I::ZERO); + self.current + } + Some(v) if v + I::ONE < self.lingrid.count => { + self.current = Some(v + I::ONE); + self.current + } + _ => None, } } } -impl, I : Unsigned, const N : usize> Grid, [I; N]> -for LinSpace, [I; N]> { +impl, I: Unsigned, const N: usize> Grid, [I; N]> + for LinSpace, [I; N]> +{ #[inline] - fn entry_linear_unchecked(&self, i_ : usize) -> Loc { + fn entry_linear_unchecked(&self, i_: usize) -> Loc { let mut i = I::cast_from(i_); let mut tmp = [I::ZERO; N]; for k in 0..N { @@ -148,58 +162,66 @@ } #[inline] - fn entry_unchecked(&self, i : &[I; N]) -> Loc { - let LinSpace{ start, end, count } = self; + fn entry_unchecked(&self, i: &[I; N]) -> Loc { + let LinSpace { start, end, count } = self; map4(i, start, end, count, |&ik, &sk, &ek, &ck| { let idx = F::cast_from(ik); - let scale = F::cast_from(ck-I::ONE); + let scale = F::cast_from(ck - I::ONE); sk + (ek - sk) * idx / scale - }).into() + }) + .into() } } -impl, I : Unsigned, const N : usize> GridIteration, [I; N]> -for LinSpaceIterator, [I; N]> { - +impl, I: Unsigned, const N: usize> GridIteration, [I; N]> + for LinSpaceIterator, [I; N]> +{ #[inline] fn next_index(&mut self) -> Option<[I; N]> { match self.current { - None if self.lingrid.count.iter().all(|v| I::ZERO < *v) => { + None if self.lingrid.count.iter().all(|v| I::ZERO < *v) => { self.current = Some([I::ZERO; N]); self.current - }, + } Some(ref mut v) => { for k in 0..N { let a = v[k] + I::ONE; if a < self.lingrid.count[k] { v[k] = a; - return self.current + return self.current; } else { v[k] = I::ZERO; } } None - }, - _ => None + } + _ => None, } } } -impl IntoIterator for LinSpace -where LinSpace : Grid, - LinSpaceIterator : GridIteration { +impl IntoIterator for LinSpace +where + LinSpace: Grid, + LinSpaceIterator: GridIteration, +{ type Item = F; - type IntoIter = LinSpaceIterator; + type IntoIter = LinSpaceIterator; #[inline] fn into_iter(self) -> Self::IntoIter { - LinSpaceIterator { lingrid : self, current : None } + LinSpaceIterator { + lingrid: self, + current: None, + } } } -impl Iterator for LinSpaceIterator -where LinSpace : Grid, - LinSpaceIterator : GridIteration { +impl Iterator for LinSpaceIterator +where + LinSpace: Grid, + LinSpaceIterator: GridIteration, +{ type Item = F; #[inline] fn next(&mut self) -> Option { @@ -207,19 +229,24 @@ } } -impl StatefulIterator for LinSpaceIterator -where LinSpace : Grid, - LinSpaceIterator : GridIteration { +impl StatefulIterator for LinSpaceIterator +where + LinSpace: Grid, + LinSpaceIterator: GridIteration, +{ #[inline] fn current(&self) -> Option { - self.current.as_ref().map(|c| self.lingrid.entry_unchecked(c)) + self.current + .as_ref() + .map(|c| self.lingrid.entry_unchecked(c)) } } - -impl RestartableIterator for LinSpaceIterator -where LinSpace : Grid, - LinSpaceIterator : GridIteration { +impl RestartableIterator for LinSpaceIterator +where + LinSpace: Grid, + LinSpaceIterator: GridIteration, +{ #[inline] fn restart(&mut self) -> Option { self.current = None;