--- a/src/iterate.rs Thu Mar 19 18:21:40 2026 -0500 +++ b/src/iterate.rs Wed Apr 22 23:41:59 2026 -0500 @@ -56,40 +56,54 @@ ``` */ -use colored::{Colorize, ColoredString}; +use crate::logger::*; +use crate::types::*; +use colored::{ColoredString, Colorize}; use core::fmt::Debug; -use serde::{Serialize, Deserialize}; use cpu_time::ProcessTime; +use serde::{Deserialize, Serialize}; +use std::cell::RefCell; +use std::error::Error; use std::marker::PhantomData; +use std::rc::Rc; use std::time::Duration; -use std::error::Error; -use std::cell::RefCell; -use std::rc::Rc; -use crate::types::*; -use crate::logger::*; /// Create the displayed presentation for log items. -pub trait LogRepr : Debug { - fn logrepr(&self) -> ColoredString { format!("« {self:?} »").as_str().into() } +pub trait LogRepr: Debug { + fn logrepr(&self) -> ColoredString { + format!("« {self:?} »").as_str().into() + } } impl LogRepr for str { - fn logrepr(&self) -> ColoredString { self.into() } + fn logrepr(&self) -> ColoredString { + self.into() + } } impl LogRepr for String { - fn logrepr(&self) -> ColoredString { self.as_str().into() } + fn logrepr(&self) -> ColoredString { + self.as_str().into() + } } -impl<T> LogRepr for T where T : Num { - fn logrepr(&self) -> ColoredString { format!("J={self}").as_str().into() } +impl<T> LogRepr for T +where + T: Num, +{ + fn logrepr(&self) -> ColoredString { + format!("J={self}").as_str().into() + } } -impl<V> LogRepr for Option<V> where V : LogRepr { +impl<V> LogRepr for Option<V> +where + V: LogRepr, +{ fn logrepr(&self) -> ColoredString { match self { - None => { "===missing value===".red() } - Some(v) => { v.logrepr() } + None => "===missing value===".red(), + Some(v) => v.logrepr(), } } } @@ -97,29 +111,33 @@ /// Helper struct for returning results annotated with an additional string to /// [`if_verbose`][AlgIteratorState::if_verbose]. The [`LogRepr`] implementation will /// display that string when so decided by the specific [`AlgIterator`] in use. -#[derive(Debug,Clone)] +#[derive(Debug, Clone)] pub struct Annotated<F>(pub F, pub String); -impl<V> LogRepr for Annotated<V> where V : LogRepr { +impl<V> LogRepr for Annotated<V> +where + V: LogRepr, +{ fn logrepr(&self) -> ColoredString { - format!("{}\t| {}", self.0.logrepr(), self.1).as_str().into() + format!("{}\t| {}", self.0.logrepr(), self.1) + .as_str() + .into() } } - /// Basic log item. #[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)] pub struct LogItem<V> { - pub iter : usize, + pub iter: usize, // This causes [`csv`] to crash. //#[serde(flatten)] - pub data : V + pub data: V, } impl<V> LogItem<V> { /// Creates a new log item - fn new(iter : usize, data : V) -> Self { - LogItem{ iter, data } + fn new(iter: usize, data: V) -> Self { + LogItem { iter, data } } } @@ -127,7 +145,7 @@ /// /// This is the parameter obtained by the closure passed to [`AlgIterator::iterate`] or /// [`AlgIteratorFactory::iterate`]. -pub trait AlgIteratorState : Sized { +pub trait AlgIteratorState: Sized { /// Call `call_objective` if this is a verbose iteration. /// /// Verbosity depends on the [`AlgIterator`] that produced this state. @@ -135,7 +153,7 @@ /// The closure `calc_objective` should return an arbitrary value of type `V`, to be inserted /// into the log, or whatever is deemed by the [`AlgIterator`]. For usage instructions see the /// [module documentation][self]. - fn if_verbose<V, E : Error>(self, calc_objective : impl FnOnce() -> V) -> Step<V, Self, E>; + fn if_verbose<V, E: Error>(self, calc_objective: impl FnOnce() -> V) -> Step<V, Self, E>; /// Returns the current iteration count. fn iteration(&self) -> usize; @@ -146,7 +164,7 @@ /// Result of a step of an [`AlgIterator`] #[derive(Debug, Serialize)] -pub enum Step<V, S, Fail : Error = std::convert::Infallible> { +pub enum Step<V, S, Fail: Error = std::convert::Infallible> { /// Iteration should be terminated Terminated, /// Iteration should be terminated due to failure @@ -157,19 +175,19 @@ Result(V, S), } -impl<V, S, E : Error> Step<V, S, E> { +impl<V, S, E: Error> Step<V, S, E> { /// Maps the value contained within the `Step`, if any, by the closure `f`. - pub fn map<U>(self, mut f : impl FnMut(V) -> U) -> Step<U, S, E> { + pub fn map<U>(self, mut f: impl FnMut(V) -> U) -> Step<U, S, E> { match self { - Step::Result(v, s) => Step::Result(f(v), s), + Step::Result(v, s) => Step::Result(f(v), s), Step::Failure(e) => Step::Failure(e), - Step::Quiet => Step::Quiet, + Step::Quiet => Step::Quiet, Step::Terminated => Step::Terminated, } } } -impl<V, S, E : Error> Default for Step<V, S, E> { +impl<V, S, E: Error> Default for Step<V, S, E> { fn default() -> Self { Step::Quiet } @@ -179,29 +197,34 @@ /// /// Typically not accessed directly, but transparently produced by an [`AlgIteratorFactory`]. /// Every [`AlgIteratorFactory`] has to implement a corresponding `AlgIterator`. -pub trait AlgIterator : Sized { +pub trait AlgIterator: Sized { /// The state type - type State : AlgIteratorState; + type State: AlgIteratorState; /// The output type for [`Self::poststep`] and [`Self::step`]. type Output; /// The input type for [`Self::poststep`]. type Input; /// Advance the iterator, performing `step_fn` with the state - fn step<F, E>(&mut self, step_fn : &mut F) -> Step<Self::Output, Self::State, E> - where F : FnMut(Self::State) -> Step<Self::Input, Self::State, E>, - E : Error { - self.prestep().map_or(Step::Terminated, - |state| self.poststep(step_fn(state))) + fn step<F, E>(&mut self, step_fn: &mut F) -> Step<Self::Output, Self::State, E> + where + F: FnMut(Self::State) -> Step<Self::Input, Self::State, E>, + E: Error, + { + self.prestep() + .map_or(Step::Terminated, |state| self.poststep(step_fn(state))) } /// Initial stage of advancing the iterator, before the actual step fn prestep(&mut self) -> Option<Self::State>; /// Handle step result - fn poststep<E>(&mut self, result : Step<Self::Input, Self::State, E>) - -> Step<Self::Output, Self::State, E> - where E : Error; + fn poststep<E>( + &mut self, + result: Step<Self::Input, Self::State, E>, + ) -> Step<Self::Output, Self::State, E> + where + E: Error; /// Return current iteration count. fn iteration(&self) -> usize { @@ -213,16 +236,18 @@ /// Iterate the `AlgIterator` until termination, erforming `step_fn` on each step. /// - /// Returns either `()` or an error if the step closure terminated in [`Step::Failure´]. + /// Returns either `()` or an error if the step closure terminated in [`Step::Failure`]. #[inline] - fn iterate<F, E>(&mut self, mut step_fn : F) -> Result<(), E> - where F : FnMut(Self::State) -> Step<Self::Input, Self::State, E>, - E : Error { + fn iterate<F, E>(&mut self, mut step_fn: F) -> Result<(), E> + where + F: FnMut(Self::State) -> Step<Self::Input, Self::State, E>, + E: Error, + { loop { match self.step(&mut step_fn) { Step::Terminated => return Ok(()), Step::Failure(e) => return Err(e), - _ => {}, + _ => {} } } } @@ -231,12 +256,12 @@ /// A factory for producing an [`AlgIterator`]. /// /// For usage instructions see the [module documentation][self]. -pub trait AlgIteratorFactory<V> : Sized { - type Iter : AlgIterator<State = Self::State, Input = V, Output = Self::Output>; +pub trait AlgIteratorFactory<V>: Sized { + type Iter: AlgIterator<State = Self::State, Input = V, Output = Self::Output>; /// The state type of the corresponding [`AlgIterator`]. /// A reference to this is passed to the closures passed to methods such as [`Self::iterate`]. - type State : AlgIteratorState; + type State: AlgIteratorState; /// The output type of the corresponding [`AlgIterator`]. /// This is the output of the closures passed to methods such as [`Self::iterate`] after /// mappings performed by each [`AlgIterator`] implementation. @@ -254,9 +279,11 @@ /// /// This method is equivalent to [`Self::prepare`] followed by [`AlgIterator::iterate`]. #[inline] - fn iterate_fallible<F, E>(self, step : F) -> Result<(), E> - where F : FnMut(Self::State) -> Step<V, Self::State, E>, - E : Error { + fn iterate_fallible<F, E>(self, step: F) -> Result<(), E> + where + F: FnMut(Self::State) -> Step<V, Self::State, E>, + E: Error, + { self.prepare().iterate(step) } @@ -271,8 +298,10 @@ /// This method is equivalent to [`Self::prepare`] followed by [`AlgIterator::iterate`] /// with the error type `E=`[`std::convert::Infallible`]. #[inline] - fn iterate<F>(self, step : F) - where F : FnMut(Self::State) -> Step<V, Self::State> { + fn iterate<F>(self, step: F) + where + F: FnMut(Self::State) -> Step<V, Self::State>, + { self.iterate_fallible(step).unwrap_or_default() } @@ -288,13 +317,16 @@ /// /// For usage instructions see the [module documentation][self]. #[inline] - fn iterate_data_fallible<F, D, I, E>(self, mut datasource : I, mut step : F) - -> Result<(), E> - where F : FnMut(Self::State, D) -> Step<V, Self::State, E>, - I : Iterator<Item = D>, - E : Error { + fn iterate_data_fallible<F, D, I, E>(self, mut datasource: I, mut step: F) -> Result<(), E> + where + F: FnMut(Self::State, D) -> Step<V, Self::State, E>, + I: Iterator<Item = D>, + E: Error, + { self.prepare().iterate(move |state| { - datasource.next().map_or(Step::Terminated, |d| step(state, d)) + datasource + .next() + .map_or(Step::Terminated, |d| step(state, d)) }) } @@ -309,10 +341,13 @@ /// /// For usage instructions see the [module documentation][self]. #[inline] - fn iterate_data<F, D, I>(self, datasource : I, step : F) - where F : FnMut(Self::State, D) -> Step<V, Self::State>, - I : Iterator<Item = D> { - self.iterate_data_fallible(datasource, step).unwrap_or_default() + fn iterate_data<F, D, I>(self, datasource: I, step: F) + where + F: FnMut(Self::State, D) -> Step<V, Self::State>, + I: Iterator<Item = D>, + { + self.iterate_data_fallible(datasource, step) + .unwrap_or_default() } // fn make_iterate<'own>(self) @@ -345,79 +380,87 @@ /// }) /// }) /// ``` - fn into_log<'log>(self, logger : &'log mut Logger<Self::Output>) - -> LoggingIteratorFactory<'log, Self::Output, Self> - where Self : Sized { - LoggingIteratorFactory { - base_options : self, - logger, - } + fn into_log<'log>( + self, + logger: &'log mut Logger<Self::Output>, + ) -> LoggingIteratorFactory<'log, Self::Output, Self> + where + Self: Sized, + { + LoggingIteratorFactory { base_options: self, logger } } /// Map the output of the iterator produced by the factory. /// /// Returns a new factory. - fn mapped<U, G>(self, map : G) - -> MappingIteratorFactory<G, Self> - where Self : Sized, - G : Fn(usize, Self::Output) -> U { - MappingIteratorFactory { - base_options : self, - map - } + fn mapped<U, G>(self, map: G) -> MappingIteratorFactory<G, Self> + where + Self: Sized, + G: Fn(usize, Self::Output) -> U, + { + MappingIteratorFactory { base_options: self, map } } /// Adds iteration number to the output. /// /// Returns a new factory. /// Typically followed by [`Self::into_log`]. - fn with_iteration_number(self) - -> MappingIteratorFactory<fn(usize, Self::Output) -> LogItem<Self::Output>, Self> - where Self : Sized { + fn with_iteration_number( + self, + ) -> MappingIteratorFactory<fn(usize, Self::Output) -> LogItem<Self::Output>, Self> + where + Self: Sized, + { self.mapped(LogItem::new) } /// Add timing to the iterator produced by the factory. fn timed(self) -> TimingIteratorFactory<Self> - where Self : Sized { + where + Self: Sized, + { TimingIteratorFactory(self) } /// Add value stopping threshold to the iterator produce by the factory - fn stop_target(self, target : Self::Output) -> ValueIteratorFactory<Self::Output, Self> - where Self : Sized, - Self::Output : Num { - ValueIteratorFactory { base_options : self, target : target } + fn stop_target(self, target: Self::Output) -> ValueIteratorFactory<Self::Output, Self> + where + Self: Sized, + Self::Output: Num, + { + ValueIteratorFactory { base_options: self, target: target } } /// Add stall stopping to the iterator produce by the factory - fn stop_stall(self, stall : Self::Output) -> StallIteratorFactory<Self::Output, Self> - where Self : Sized, - Self::Output : Num { - StallIteratorFactory { base_options : self, stall : stall } + fn stop_stall(self, stall: Self::Output) -> StallIteratorFactory<Self::Output, Self> + where + Self: Sized, + Self::Output: Num, + { + StallIteratorFactory { base_options: self, stall: stall } } /// Is the iterator quiet, i.e., on-verbose? - fn is_quiet(&self) -> bool { false } + fn is_quiet(&self) -> bool { + false + } /// Returns an an [`std::iter::Iterator`] that can be used in a `for`-loop. fn iter(self) -> AlgIteratorIterator<Self::Iter> { - AlgIteratorIterator { - algi : Rc::new(RefCell::new(self.prepare())), - } + AlgIteratorIterator { algi: Rc::new(RefCell::new(self.prepare())) } } /// Returns an an [`std::iter::Iterator`] that can be used in a `for`-loop, /// also inputting an initial iteration status calculated by `f` if needed. - fn iter_init(self, f : impl FnOnce() -> <Self::Iter as AlgIterator>::Input) - -> AlgIteratorIterator<Self::Iter> { + fn iter_init( + self, + f: impl FnOnce() -> <Self::Iter as AlgIterator>::Input, + ) -> AlgIteratorIterator<Self::Iter> { let mut i = self.prepare(); let st = i.state(); - let step : Step<<Self::Iter as AlgIterator>::Input, Self::State> = st.if_verbose(f); + let step: Step<<Self::Iter as AlgIterator>::Input, Self::State> = st.if_verbose(f); i.poststep(step); - AlgIteratorIterator { - algi : Rc::new(RefCell::new(i)), - } + AlgIteratorIterator { algi: Rc::new(RefCell::new(i)) } } } @@ -431,12 +474,12 @@ #[derive(Clone, Copy, Debug, Serialize, Deserialize, Eq, PartialEq)] pub struct AlgIteratorOptions { /// Maximum number of iterations - pub max_iter : usize, + pub max_iter: usize, /// Number of iterations between verbose iterations that display state. - pub verbose_iter : Verbose, + pub verbose_iter: Verbose, /// Whether verbose iterations are displayed, or just passed onwards to a containing /// `AlgIterator`. - pub quiet : bool, + pub quiet: bool, } #[derive(Clone, Copy, Debug, Serialize, Deserialize, Eq, PartialEq)] @@ -444,7 +487,7 @@ /// Be verbose every $n$ iterations. Every(usize), /// Be verbose every $n$ iterations and initial $m$ iterations. - EveryAndInitial{ every : usize, initial : usize }, + EveryAndInitial { every: usize, initial: usize }, /// Be verbose if iteration number $n$ divides by $b^{\text{floor}(\log_b(n))}$, where /// $b$ is indicated logarithmic base. So, with $b=10$, /// * every iteration for first 10 iterations, @@ -455,24 +498,22 @@ /// is the given `cap`. For example, with `base=10` and `cap=2`, the first ten iterations /// will be output, then every tenth iteration, and after 100 iterations, every 100th iteration, /// without further logarithmic progression. - LogarithmicCap{ base : usize, cap : u32 }, + LogarithmicCap { base: usize, cap: u32 }, } impl Verbose { /// Indicates whether given iteration number is verbose - pub fn is_verbose(&self, iter : usize) -> bool { + pub fn is_verbose(&self, iter: usize) -> bool { match self { - &Verbose::Every(every) => { - every != 0 && iter % every == 0 - }, - &Verbose::EveryAndInitial{ every, initial } => { + &Verbose::Every(every) => every != 0 && iter % every == 0, + &Verbose::EveryAndInitial { every, initial } => { iter <= initial || (every != 0 && iter % every == 0) - }, + } &Verbose::Logarithmic(base) => { let every = base.pow((iter as float).log(base as float).floor() as u32); iter % every == 0 } - &Verbose::LogarithmicCap{base, cap} => { + &Verbose::LogarithmicCap { base, cap } => { let every = base.pow(((iter as float).log(base as float).floor() as u32).min(cap)); iter % every == 0 } @@ -482,41 +523,41 @@ impl Default for AlgIteratorOptions { fn default() -> AlgIteratorOptions { - AlgIteratorOptions{ - max_iter : 1000, - verbose_iter : Verbose::EveryAndInitial { every : 100, initial : 10 }, - quiet : false + AlgIteratorOptions { + max_iter: 1000, + verbose_iter: Verbose::EveryAndInitial { every: 100, initial: 10 }, + quiet: false, } } } /// State of a `BasicAlgIterator` -#[derive(Clone,Copy,Debug,Serialize,Eq,PartialEq)] +#[derive(Clone, Copy, Debug, Serialize, Eq, PartialEq)] pub struct BasicState { /// Current iteration - iter : usize, + iter: usize, /// Whether the iteration is verbose, i.e., results should be displayed. /// Requires `calc` to be `true`. - verbose : bool, + verbose: bool, /// Whether results should be calculated. - calc : bool, + calc: bool, /// Indicates whether the iteration is quiet - quiet : bool, + quiet: bool, } /// [`AlgIteratorFactory`] for [`BasicAlgIterator`] -#[derive(Clone,Debug)] +#[derive(Clone, Debug)] pub struct BasicAlgIteratorFactory<V> { - options : AlgIteratorOptions, - _phantoms : PhantomData<V>, + options: AlgIteratorOptions, + _phantoms: PhantomData<V>, } /// The simplest [`AlgIterator`], created by [`BasicAlgIteratorFactory`] -#[derive(Clone,Debug)] +#[derive(Clone, Debug)] pub struct BasicAlgIterator<V> { - options : AlgIteratorOptions, - iter : usize, - _phantoms : PhantomData<V>, + options: AlgIteratorOptions, + iter: usize, + _phantoms: PhantomData<V>, } impl AlgIteratorOptions { @@ -524,25 +565,20 @@ /// however, due to type inference issues, it may become convenient to instantiate /// it to a specific return type for the inner step function. This method does that. pub fn instantiate<V>(&self) -> BasicAlgIteratorFactory<V> { - BasicAlgIteratorFactory { - options : self.clone(), - _phantoms : PhantomData - } + BasicAlgIteratorFactory { options: self.clone(), _phantoms: PhantomData } } } impl<V> AlgIteratorFactory<V> for AlgIteratorOptions -where V : LogRepr { +where + V: LogRepr, +{ type State = BasicState; type Iter = BasicAlgIterator<V>; type Output = V; fn prepare(self) -> Self::Iter { - BasicAlgIterator{ - options : self, - iter : 0, - _phantoms : PhantomData, - } + BasicAlgIterator { options: self, iter: 0, _phantoms: PhantomData } } #[inline] @@ -552,17 +588,15 @@ } impl<V> AlgIteratorFactory<V> for BasicAlgIteratorFactory<V> -where V : LogRepr { +where + V: LogRepr, +{ type State = BasicState; type Iter = BasicAlgIterator<V>; type Output = V; fn prepare(self) -> Self::Iter { - BasicAlgIterator { - options : self.options, - iter : 0, - _phantoms : PhantomData - } + BasicAlgIterator { options: self.options, iter: 0, _phantoms: PhantomData } } #[inline] @@ -572,7 +606,9 @@ } impl<V> AlgIterator for BasicAlgIterator<V> -where V : LogRepr { +where + V: LogRepr, +{ type State = BasicState; type Output = V; type Input = V; @@ -587,14 +623,17 @@ } } - fn poststep<E : Error>(&mut self, res : Step<V, Self::State, E>) -> Step<V, Self::State, E> { + fn poststep<E: Error>(&mut self, res: Step<V, Self::State, E>) -> Step<V, Self::State, E> { if let Step::Result(ref val, ref state) = res { if state.verbose && !self.options.quiet { - println!("{}{}/{} {}{}", "".dimmed(), - state.iter, - self.options.max_iter, - val.logrepr(), - "".clear()); + println!( + "{}{}/{} {}{}", + "".dimmed(), + state.iter, + self.options.max_iter, + val.logrepr(), + "".clear() + ); } } res @@ -609,18 +648,13 @@ fn state(&self) -> BasicState { let iter = self.iter; let verbose = self.options.verbose_iter.is_verbose(iter); - BasicState { - iter : iter, - verbose : verbose, - calc : verbose, - quiet : self.options.quiet - } + BasicState { iter: iter, verbose: verbose, calc: verbose, quiet: self.options.quiet } } } impl AlgIteratorState for BasicState { #[inline] - fn if_verbose<V, E : Error>(self, calc_objective : impl FnOnce() -> V) -> Step<V, Self, E> { + fn if_verbose<V, E: Error>(self, calc_objective: impl FnOnce() -> V) -> Step<V, Self, E> { if self.calc { Step::Result(calc_objective(), self) } else { @@ -647,34 +681,35 @@ /// /// We define stall as $(v_{k+n}-v_k)/v_k ≤ θ$, where $n$ the distance between /// [`Step::Result`] iterations, and $θ$ is the provided `stall` parameter. -#[derive(Clone,Copy,Debug,Serialize,Eq,PartialEq)] -pub struct StallIteratorFactory<U : Num, BaseFactory> { +#[derive(Clone, Copy, Debug, Serialize, Eq, PartialEq)] +pub struct StallIteratorFactory<U: Num, BaseFactory> { /// An [`AlgIteratorFactory`] on which to build on - pub base_options : BaseFactory, + pub base_options: BaseFactory, /// Stalling threshold $θ$. - pub stall : U, + pub stall: U, } /// Iterator produced by [`StallIteratorFactory`]. -pub struct StallIterator<U : Num, BaseIterator> { - base_iterator : BaseIterator, - stall : U, - previous_value : Option<U>, +pub struct StallIterator<U: Num, BaseIterator> { + base_iterator: BaseIterator, + stall: U, + previous_value: Option<U>, } -impl<V, U, BaseFactory> AlgIteratorFactory<V> -for StallIteratorFactory<U, BaseFactory> -where BaseFactory : AlgIteratorFactory<V, Output=U>, - U : SignedNum + PartialOrd { +impl<V, U, BaseFactory> AlgIteratorFactory<V> for StallIteratorFactory<U, BaseFactory> +where + BaseFactory: AlgIteratorFactory<V, Output = U>, + U: SignedNum + PartialOrd, +{ type Iter = StallIterator<U, BaseFactory::Iter>; type State = BaseFactory::State; type Output = BaseFactory::Output; fn prepare(self) -> Self::Iter { StallIterator { - base_iterator : self.base_options.prepare(), - stall : self.stall, - previous_value : None, + base_iterator: self.base_options.prepare(), + stall: self.stall, + previous_value: None, } } @@ -683,10 +718,11 @@ } } -impl<U, BaseIterator> AlgIterator -for StallIterator<U, BaseIterator> -where BaseIterator : AlgIterator<Output=U>, - U : SignedNum + PartialOrd { +impl<U, BaseIterator> AlgIterator for StallIterator<U, BaseIterator> +where + BaseIterator: AlgIterator<Output = U>, + U: SignedNum + PartialOrd, +{ type State = BaseIterator::State; type Output = U; type Input = BaseIterator::Input; @@ -697,8 +733,10 @@ } #[inline] - fn poststep<E>(&mut self, res : Step<Self::Input, Self::State, E>) -> Step<U, Self::State, E> - where E : Error { + fn poststep<E>(&mut self, res: Step<Self::Input, Self::State, E>) -> Step<U, Self::State, E> + where + E: Error, + { match self.base_iterator.poststep(res) { Step::Result(nv, state) => { let previous_v = self.previous_value; @@ -707,7 +745,7 @@ Some(pv) if (nv - pv).abs() <= self.stall * pv.abs() => Step::Terminated, _ => Step::Result(nv, state), } - }, + } val => val, } } @@ -725,33 +763,31 @@ /// An [`AlgIteratorFactory`] for an [`AlgIterator`] that detect whether step function /// return value is less than `target`, and terminates if it is. -#[derive(Clone,Copy,Debug,Serialize,Eq,PartialEq)] -pub struct ValueIteratorFactory<U : Num, BaseFactory> { +#[derive(Clone, Copy, Debug, Serialize, Eq, PartialEq)] +pub struct ValueIteratorFactory<U: Num, BaseFactory> { /// An [`AlgIteratorFactory`] on which to build on - pub base_options : BaseFactory, + pub base_options: BaseFactory, /// Target value - pub target : U, + pub target: U, } /// Iterator produced by [`ValueIteratorFactory`]. -pub struct ValueIterator<U : Num, BaseIterator> { - base_iterator : BaseIterator, - target : U, +pub struct ValueIterator<U: Num, BaseIterator> { + base_iterator: BaseIterator, + target: U, } -impl<V, U, BaseFactory> AlgIteratorFactory<V> -for ValueIteratorFactory<U, BaseFactory> -where BaseFactory : AlgIteratorFactory<V, Output=U>, - U : SignedNum + PartialOrd { +impl<V, U, BaseFactory> AlgIteratorFactory<V> for ValueIteratorFactory<U, BaseFactory> +where + BaseFactory: AlgIteratorFactory<V, Output = U>, + U: SignedNum + PartialOrd, +{ type Iter = ValueIterator<U, BaseFactory::Iter>; type State = BaseFactory::State; type Output = BaseFactory::Output; fn prepare(self) -> Self::Iter { - ValueIterator { - base_iterator : self.base_options.prepare(), - target : self.target - } + ValueIterator { base_iterator: self.base_options.prepare(), target: self.target } } fn is_quiet(&self) -> bool { @@ -759,10 +795,11 @@ } } -impl<U, BaseIterator> AlgIterator -for ValueIterator<U, BaseIterator> -where BaseIterator : AlgIterator<Output=U>, - U : SignedNum + PartialOrd { +impl<U, BaseIterator> AlgIterator for ValueIterator<U, BaseIterator> +where + BaseIterator: AlgIterator<Output = U>, + U: SignedNum + PartialOrd, +{ type State = BaseIterator::State; type Output = U; type Input = BaseIterator::Input; @@ -773,15 +810,18 @@ } #[inline] - fn poststep<E>(&mut self, res : Step<Self::Input, Self::State, E>) -> Step<U, Self::State, E> where E : Error{ + fn poststep<E>(&mut self, res: Step<Self::Input, Self::State, E>) -> Step<U, Self::State, E> + where + E: Error, + { match self.base_iterator.poststep(res) { Step::Result(v, state) => { - if v <= self.target { + if v <= self.target { Step::Terminated - } else { + } else { Step::Result(v, state) - } - }, + } + } val => val, } } @@ -808,31 +848,29 @@ #[derive(Debug)] pub struct LoggingIteratorFactory<'log, U, BaseFactory> { /// Base [`AlgIteratorFactory`] on which to build - base_options : BaseFactory, + base_options: BaseFactory, /// The `Logger` to use. - logger : &'log mut Logger<U>, + logger: &'log mut Logger<U>, } /// Iterator produced by `LoggingIteratorFactory`. pub struct LoggingIterator<'log, U, BaseIterator> { - base_iterator : BaseIterator, - logger : &'log mut Logger<U>, + base_iterator: BaseIterator, + logger: &'log mut Logger<U>, } - impl<'log, V, BaseFactory> AlgIteratorFactory<V> -for LoggingIteratorFactory<'log, BaseFactory::Output, BaseFactory> -where BaseFactory : AlgIteratorFactory<V>, - BaseFactory::Output : 'log { + for LoggingIteratorFactory<'log, BaseFactory::Output, BaseFactory> +where + BaseFactory: AlgIteratorFactory<V>, + BaseFactory::Output: 'log, +{ type State = BaseFactory::State; type Iter = LoggingIterator<'log, BaseFactory::Output, BaseFactory::Iter>; type Output = (); fn prepare(self) -> Self::Iter { - LoggingIterator { - base_iterator : self.base_options.prepare(), - logger : self.logger, - } + LoggingIterator { base_iterator: self.base_options.prepare(), logger: self.logger } } #[inline] @@ -841,10 +879,11 @@ } } -impl<'log, BaseIterator> AlgIterator -for LoggingIterator<'log, BaseIterator::Output, BaseIterator> -where BaseIterator : AlgIterator, - BaseIterator::Output : 'log { +impl<'log, BaseIterator> AlgIterator for LoggingIterator<'log, BaseIterator::Output, BaseIterator> +where + BaseIterator: AlgIterator, + BaseIterator::Output: 'log, +{ type State = BaseIterator::State; type Output = (); type Input = BaseIterator::Input; @@ -855,12 +894,15 @@ } #[inline] - fn poststep<E>(&mut self, res : Step<Self::Input, Self::State, E>) -> Step<(), Self::State, E> where E : Error { + fn poststep<E>(&mut self, res: Step<Self::Input, Self::State, E>) -> Step<(), Self::State, E> + where + E: Error, + { match self.base_iterator.poststep(res) { Step::Result(v, _) => { self.logger.log(v); Step::Quiet - }, + } Step::Quiet => Step::Quiet, Step::Terminated => Step::Terminated, Step::Failure(e) => Step::Failure(e), @@ -884,32 +926,29 @@ #[derive(Debug)] pub struct MappingIteratorFactory<G, BaseFactory> { /// Base [`AlgIteratorFactory`] on which to build - base_options : BaseFactory, + base_options: BaseFactory, /// A closure `G : Fn(usize, BaseFactory::Output) -> U` that gets the current iteration /// and the output of the base factory as input, and produces a new output. - map : G, + map: G, } /// [`AlgIterator`] produced by [`MappingIteratorFactory`]. pub struct MappingIterator<G, BaseIterator> { - base_iterator : BaseIterator, - map : G, + base_iterator: BaseIterator, + map: G, } - -impl<V, U, G, BaseFactory> AlgIteratorFactory<V> -for MappingIteratorFactory<G, BaseFactory> -where BaseFactory : AlgIteratorFactory<V>, - G : Fn(usize, BaseFactory::Output) -> U { +impl<V, U, G, BaseFactory> AlgIteratorFactory<V> for MappingIteratorFactory<G, BaseFactory> +where + BaseFactory: AlgIteratorFactory<V>, + G: Fn(usize, BaseFactory::Output) -> U, +{ type State = BaseFactory::State; type Iter = MappingIterator<G, BaseFactory::Iter>; type Output = U; fn prepare(self) -> Self::Iter { - MappingIterator { - base_iterator : self.base_options.prepare(), - map : self.map - } + MappingIterator { base_iterator: self.base_options.prepare(), map: self.map } } #[inline] @@ -918,10 +957,11 @@ } } -impl<U, G, BaseIterator> AlgIterator -for MappingIterator<G, BaseIterator> -where BaseIterator : AlgIterator, - G : Fn(usize, BaseIterator::Output) -> U { +impl<U, G, BaseIterator> AlgIterator for MappingIterator<G, BaseIterator> +where + BaseIterator: AlgIterator, + G: Fn(usize, BaseIterator::Output) -> U, +{ type State = BaseIterator::State; type Output = U; type Input = BaseIterator::Input; @@ -932,7 +972,13 @@ } #[inline] - fn poststep<E>(&mut self, res : Step<Self::Input, Self::State, E>) -> Step<Self::Output, Self::State, E> where E : Error { + fn poststep<E>( + &mut self, + res: Step<Self::Input, Self::State, E>, + ) -> Step<Self::Output, Self::State, E> + where + E: Error, + { match self.base_iterator.poststep(res) { Step::Result(v, state) => Step::Result((self.map)(self.iteration(), v), state), Step::Quiet => Step::Quiet, @@ -963,41 +1009,47 @@ /// Iterator produced by [`TimingIteratorFactory`] #[derive(Debug)] pub struct TimingIterator<BaseIterator> { - base_iterator : BaseIterator, - start_time : ProcessTime, + base_iterator: BaseIterator, + start_time: ProcessTime, } /// Data `U` with production time attached #[derive(Copy, Clone, Debug, Serialize)] pub struct Timed<U> { /// CPU time taken - pub cpu_time : Duration, + pub cpu_time: Duration, /// Iteration number - pub iter : usize, + pub iter: usize, /// User data //#[serde(flatten)] - pub data : U + pub data: U, } -impl<T> LogRepr for Timed<T> where T : LogRepr { +impl<T> LogRepr for Timed<T> +where + T: LogRepr, +{ fn logrepr(&self) -> ColoredString { - format!("[{:.3}s] {}", self.cpu_time.as_secs_f64(), self.data.logrepr()).as_str().into() + format!( + "[{:.3}s] {}", + self.cpu_time.as_secs_f64(), + self.data.logrepr() + ) + .as_str() + .into() } } - -impl<V, BaseFactory> AlgIteratorFactory<V> -for TimingIteratorFactory<BaseFactory> -where BaseFactory : AlgIteratorFactory<V> { +impl<V, BaseFactory> AlgIteratorFactory<V> for TimingIteratorFactory<BaseFactory> +where + BaseFactory: AlgIteratorFactory<V>, +{ type State = BaseFactory::State; type Iter = TimingIterator<BaseFactory::Iter>; type Output = Timed<BaseFactory::Output>; fn prepare(self) -> Self::Iter { - TimingIterator { - base_iterator : self.0.prepare(), - start_time : ProcessTime::now() - } + TimingIterator { base_iterator: self.0.prepare(), start_time: ProcessTime::now() } } #[inline] @@ -1006,9 +1058,10 @@ } } -impl<BaseIterator> AlgIterator -for TimingIterator<BaseIterator> -where BaseIterator : AlgIterator { +impl<BaseIterator> AlgIterator for TimingIterator<BaseIterator> +where + BaseIterator: AlgIterator, +{ type State = BaseIterator::State; type Output = Timed<BaseIterator::Output>; type Input = BaseIterator::Input; @@ -1019,15 +1072,18 @@ } #[inline] - fn poststep<E>(&mut self, res : Step<Self::Input, Self::State, E>) -> Step<Self::Output, Self::State, E> where E : Error { + fn poststep<E>( + &mut self, + res: Step<Self::Input, Self::State, E>, + ) -> Step<Self::Output, Self::State, E> + where + E: Error, + { match self.base_iterator.poststep(res) { - Step::Result(data, state) => { - Step::Result(Timed{ - cpu_time : self.start_time.elapsed(), - iter : self.iteration(), - data - }, state) - }, + Step::Result(data, state) => Step::Result( + Timed { cpu_time: self.start_time.elapsed(), iter: self.iteration(), data }, + state, + ), Step::Quiet => Step::Quiet, Step::Terminated => Step::Terminated, Step::Failure(e) => Step::Failure(e), @@ -1049,35 +1105,34 @@ // New for-loop interface // -pub struct AlgIteratorIterator<I : AlgIterator> { - algi : Rc<RefCell<I>>, +pub struct AlgIteratorIterator<I: AlgIterator> { + algi: Rc<RefCell<I>>, } -pub struct AlgIteratorIteration<I : AlgIterator> { - state : I::State, - algi : Rc<RefCell<I>>, +pub struct AlgIteratorIteration<I: AlgIterator> { + state: I::State, + algi: Rc<RefCell<I>>, } -impl<I : AlgIterator> std::iter::Iterator for AlgIteratorIterator<I> { +impl<I: AlgIterator> std::iter::Iterator for AlgIteratorIterator<I> { type Item = AlgIteratorIteration<I>; fn next(&mut self) -> Option<Self::Item> { let algi = self.algi.clone(); - RefCell::borrow_mut(&self.algi).prestep().map(|state| AlgIteratorIteration { - state, - algi, - }) + RefCell::borrow_mut(&self.algi) + .prestep() + .map(|state| AlgIteratorIteration { state, algi }) } } /// Types of errors that may occur -#[derive(Debug,PartialEq,Eq)] +#[derive(Debug, PartialEq, Eq)] pub enum IterationError { /// [`AlgIteratorIteration::if_verbose_check`] is not called in iteration order. - ReportingOrderingError + ReportingOrderingError, } -impl<I : AlgIterator> AlgIteratorIteration<I> { +impl<I: AlgIterator> AlgIteratorIteration<I> { /// Call `call_objective` if this is a verbose iteration. /// /// Verbosity depends on the [`AlgIterator`] that produced this state. @@ -1089,22 +1144,24 @@ /// This function may panic if result reporting is not ordered correctly (an unlikely mistake /// if using this facility correctly). For a version that propagates errors, see /// [`Self::if_verbose_check`]. - pub fn if_verbose(self, calc_objective : impl FnOnce() -> I::Input) { + pub fn if_verbose(self, calc_objective: impl FnOnce() -> I::Input) { self.if_verbose_check(calc_objective).unwrap() } /// Version of [`Self::if_verbose`] that propagates errors instead of panicking. - pub fn if_verbose_check(self, calc_objective : impl FnOnce() -> I::Input) - -> Result<(), IterationError> { + pub fn if_verbose_check( + self, + calc_objective: impl FnOnce() -> I::Input, + ) -> Result<(), IterationError> { let mut algi = match RefCell::try_borrow_mut(&self.algi) { Err(_) => return Err(IterationError::ReportingOrderingError), - Ok(algi) => algi + Ok(algi) => algi, }; if self.state.iteration() != algi.iteration() { Err(IterationError::ReportingOrderingError) } else { - let res : Step<I::Input, I::State, std::convert::Infallible> - = self.state.if_verbose(calc_objective); + let res: Step<I::Input, I::State, std::convert::Infallible> = + self.state.if_verbose(calc_objective); algi.poststep(res); Ok(()) } @@ -1131,10 +1188,10 @@ use crate::logger::Logger; #[test] fn iteration() { - let options = AlgIteratorOptions{ - max_iter : 10, - verbose_iter : Verbose::Every(3), - .. Default::default() + let options = AlgIteratorOptions { + max_iter: 10, + verbose_iter: Verbose::Every(3), + ..Default::default() }; { @@ -1149,31 +1206,35 @@ { let mut start = 1 as int; let mut log = Logger::new(); - let factory = options.instantiate() - .with_iteration_number() - .into_log(&mut log); + let factory = options + .instantiate() + .with_iteration_number() + .into_log(&mut log); factory.iterate(|state| { start = start * 2; state.if_verbose(|| start) }); assert_eq!(start, (2 as int).pow(10)); - assert_eq!(log.data() - .iter() - .map(|LogItem{ data : v, iter : _ }| v.clone()) - .collect::<Vec<int>>(), - (1..10).map(|i| (2 as int).pow(i)) - .skip(2) - .step_by(3) - .collect::<Vec<int>>()) + assert_eq!( + log.data() + .iter() + .map(|LogItem { data: v, iter: _ }| v.clone()) + .collect::<Vec<int>>(), + (1..10) + .map(|i| (2 as int).pow(i)) + .skip(2) + .step_by(3) + .collect::<Vec<int>>() + ) } } #[test] fn iteration_for_loop() { - let options = AlgIteratorOptions{ - max_iter : 10, - verbose_iter : Verbose::Every(3), - .. Default::default() + let options = AlgIteratorOptions { + max_iter: 10, + verbose_iter: Verbose::Every(3), + ..Default::default() }; { @@ -1188,23 +1249,26 @@ { let mut start = 1 as int; let mut log = Logger::new(); - let factory = options.instantiate() - .with_iteration_number() - .into_log(&mut log); + let factory = options + .instantiate() + .with_iteration_number() + .into_log(&mut log); for state in factory.iter() { start = start * 2; state.if_verbose(|| start) } assert_eq!(start, (2 as int).pow(10)); - assert_eq!(log.data() - .iter() - .map(|LogItem{ data : v, iter : _ }| v.clone()) - .collect::<Vec<int>>(), - (1..10).map(|i| (2 as int).pow(i)) - .skip(2) - .step_by(3) - .collect::<Vec<int>>()) + assert_eq!( + log.data() + .iter() + .map(|LogItem { data: v, iter: _ }| v.clone()) + .collect::<Vec<int>>(), + (1..10) + .map(|i| (2 as int).pow(i)) + .skip(2) + .step_by(3) + .collect::<Vec<int>>() + ) } } - }