| 25:d14c877e14b7 | 90:b3c35d16affe |
|---|---|
| 17 max_iter : 100, | 17 max_iter : 100, |
| 18 verbose_iter : Verbose::Every(10), | 18 verbose_iter : Verbose::Every(10), |
| 19 .. Default::default() | 19 .. Default::default() |
| 20 }; | 20 }; |
| 21 let mut x = 1 as float; | 21 let mut x = 1 as float; |
| 22 # let mut iter_clone = iter.clone(); | |
| 22 iter.iterate(|state|{ | 23 iter.iterate(|state|{ |
| 23 // This is our computational step | 24 // This is our computational step |
| 24 x = x + x.sqrt(); | 25 x = x + x.sqrt(); |
| 25 state.if_verbose(||{ | 26 state.if_verbose(||{ |
| 26 // return current value when requested | 27 // return current value when requested |
| 27 return x | 28 return x |
| 28 }) | 29 }) |
| 29 }) | 30 }); |
| 31 // or alternatively (avoiding problems with moves) | |
| 32 # iter = iter_clone; | |
| 33 for state in iter.iter() { | |
| 34 // This is our computational step | |
| 35 x = x + x.sqrt(); | |
| 36 state.if_verbose(||{ | |
| 37 // return current value when requested | |
| 38 return x | |
| 39 }) | |
| 40 } | |
| 30 ``` | 41 ``` |
| 31 There is no colon after `state.if_verbose`, because we need to return its value. If you do something after the step, you need to store the result in a variable and return it from the main computational step afterwards. | 42 There is no colon after `state.if_verbose`, because we need to return its value. If you do something after the step, you need to store the result in a variable and return it from the main computational step afterwards. |
| 32 | 43 |
| 33 This will print out | 44 This will print out |
| 34 ```output | 45 ```output |
| 50 use serde::{Serialize, Deserialize}; | 61 use serde::{Serialize, Deserialize}; |
| 51 use cpu_time::ProcessTime; | 62 use cpu_time::ProcessTime; |
| 52 use std::marker::PhantomData; | 63 use std::marker::PhantomData; |
| 53 use std::time::Duration; | 64 use std::time::Duration; |
| 54 use std::error::Error; | 65 use std::error::Error; |
| 66 use std::cell::RefCell; | |
| 67 use std::rc::Rc; | |
| 55 use crate::types::*; | 68 use crate::types::*; |
| 56 use crate::logger::*; | 69 use crate::logger::*; |
| 57 | 70 |
| 58 /// Create the displayed presentation for log items. | 71 /// Create the displayed presentation for log items. |
| 59 pub trait LogRepr : Debug { | 72 pub trait LogRepr : Debug { |
| 112 | 125 |
| 113 /// State of an [`AlgIterator`]. | 126 /// State of an [`AlgIterator`]. |
| 114 /// | 127 /// |
| 115 /// This is the parameter obtained by the closure passed to [`AlgIterator::iterate`] or | 128 /// This is the parameter obtained by the closure passed to [`AlgIterator::iterate`] or |
| 116 /// [`AlgIteratorFactory::iterate`]. | 129 /// [`AlgIteratorFactory::iterate`]. |
| 117 pub trait AlgIteratorState { | 130 pub trait AlgIteratorState : Sized { |
| 118 /// Call `call_objective` if this is a verbose iteration. | 131 /// Call `call_objective` if this is a verbose iteration. |
| 119 /// | 132 /// |
| 120 /// Verbosity depends on the [`AlgIterator`] that produced this state. | 133 /// Verbosity depends on the [`AlgIterator`] that produced this state. |
| 121 /// | 134 /// |
| 122 /// The closure `calc_objective` should return an arbitrary value of type `V`, to be inserted | 135 /// The closure `calc_objective` should return an arbitrary value of type `V`, to be inserted |
| 123 /// into the log, or whatever is deemed by the [`AlgIterator`]. For usage instructions see the | 136 /// into the log, or whatever is deemed by the [`AlgIterator`]. For usage instructions see the |
| 124 /// [module documentation][self]. | 137 /// [module documentation][self]. |
| 125 fn if_verbose<V, E : Error>(&self, calc_objective : impl FnMut() -> V) -> Step<V, E>; | 138 fn if_verbose<V, E : Error>(self, calc_objective : impl FnOnce() -> V) -> Step<V, Self, E>; |
| 126 | 139 |
| 127 /// Returns the current iteration count. | 140 /// Returns the current iteration count. |
| 128 fn iteration(&self) -> usize; | 141 fn iteration(&self) -> usize; |
| 142 | |
| 143 /// Indicates whether the iterator is quiet | |
| 144 fn is_quiet(&self) -> bool; | |
| 129 } | 145 } |
| 130 | 146 |
| 131 /// Result of a step of an [`AlgIterator`] | 147 /// Result of a step of an [`AlgIterator`] |
| 132 #[derive(Debug, Serialize)] | 148 #[derive(Debug, Serialize)] |
| 133 pub enum Step<V, Fail : Error = std::convert::Infallible> { | 149 pub enum Step<V, S, Fail : Error = std::convert::Infallible> { |
| 134 /// Iteration should be terminated | 150 /// Iteration should be terminated |
| 135 Terminated, | 151 Terminated, |
| 136 /// Iteration should be terminated due to failure | 152 /// Iteration should be terminated due to failure |
| 137 Failure(Fail), | 153 Failure(Fail), |
| 138 /// No result this iteration (due to verbosity settings) | 154 /// No result this iteration (due to verbosity settings) |
| 139 Quiet, | 155 Quiet, |
| 140 /// Result of this iteration (due to verbosity settings) | 156 /// Result of this iteration (due to verbosity settings) |
| 141 Result(V), | 157 Result(V, S), |
| 142 } | 158 } |
| 143 | 159 |
| 144 impl<V, E : Error> Step<V, E> { | 160 impl<V, S, E : Error> Step<V, S, E> { |
| 145 /// Maps the value contained within the `Step`, if any, by the closure `f`. | 161 /// Maps the value contained within the `Step`, if any, by the closure `f`. |
| 146 pub fn map<U>(self, mut f : impl FnMut(V) -> U) -> Step<U, E> { | 162 pub fn map<U>(self, mut f : impl FnMut(V) -> U) -> Step<U, S, E> { |
| 147 match self { | 163 match self { |
| 148 Step::Result(v) => Step::Result(f(v)), | 164 Step::Result(v, s) => Step::Result(f(v), s), |
| 149 Step::Failure(e) => Step::Failure(e), | 165 Step::Failure(e) => Step::Failure(e), |
| 150 Step::Quiet => Step::Quiet, | 166 Step::Quiet => Step::Quiet, |
| 151 Step::Terminated => Step::Terminated, | 167 Step::Terminated => Step::Terminated, |
| 152 } | 168 } |
| 169 } | |
| 170 } | |
| 171 | |
| 172 impl<V, S, E : Error> Default for Step<V, S, E> { | |
| 173 fn default() -> Self { | |
| 174 Step::Quiet | |
| 153 } | 175 } |
| 154 } | 176 } |
| 155 | 177 |
| 156 /// An iterator for algorithms, produced by [`AlgIteratorFactory::prepare`]. | 178 /// An iterator for algorithms, produced by [`AlgIteratorFactory::prepare`]. |
| 157 /// | 179 /// |
| 158 /// Typically not accessed directly, but transparently produced by an [`AlgIteratorFactory`]. | 180 /// Typically not accessed directly, but transparently produced by an [`AlgIteratorFactory`]. |
| 159 /// Every [`AlgIteratorFactory`] has to implement a corresponding `AlgIterator`. | 181 /// Every [`AlgIteratorFactory`] has to implement a corresponding `AlgIterator`. |
| 160 pub trait AlgIterator : Sized { | 182 pub trait AlgIterator : Sized { |
| 161 /// The state type | 183 /// The state type |
| 162 type State : AlgIteratorState; | 184 type State : AlgIteratorState; |
| 163 /// The output type for [`Self::step`]. | 185 /// The output type for [`Self::poststep`] and [`Self::step`]. |
| 164 type Output; | 186 type Output; |
| 165 /// The error type for [`Self::step`] and [`Self::iterate`]. | 187 /// The input type for [`Self::poststep`]. |
| 166 type Err : Error; | 188 type Input; |
| 167 | 189 |
| 168 /// Advance the iterator. | 190 /// Advance the iterator, performing `step_fn` with the state |
| 169 fn step(&mut self) -> Step<Self::Output, Self::Err>; | 191 fn step<F, E>(&mut self, step_fn : &mut F) -> Step<Self::Output, Self::State, E> |
| 192 where F : FnMut(Self::State) -> Step<Self::Input, Self::State, E>, | |
| 193 E : Error { | |
| 194 self.prestep().map_or(Step::Terminated, | |
| 195 |state| self.poststep(step_fn(state))) | |
| 196 } | |
| 197 | |
| 198 /// Initial stage of advancing the iterator, before the actual step | |
| 199 fn prestep(&mut self) -> Option<Self::State>; | |
| 200 | |
| 201 /// Handle step result | |
| 202 fn poststep<E>(&mut self, result : Step<Self::Input, Self::State, E>) | |
| 203 -> Step<Self::Output, Self::State, E> | |
| 204 where E : Error; | |
| 170 | 205 |
| 171 /// Return current iteration count. | 206 /// Return current iteration count. |
| 172 fn iteration(&self) -> usize { | 207 fn iteration(&self) -> usize { |
| 173 self.state().iteration() | 208 self.state().iteration() |
| 174 } | 209 } |
| 175 | 210 |
| 176 /// Return current state. | 211 /// Return current state. |
| 177 fn state(&self) -> Self::State; | 212 fn state(&self) -> Self::State; |
| 178 | 213 |
| 179 /// Iterate the `AlgIterator` until termination. | 214 /// Iterate the `AlgIterator` until termination, erforming `step_fn` on each step. |
| 180 /// | 215 /// |
| 181 /// Returns either `()` or an error if the step closure terminated in [`Step::Failure“]. | 216 /// Returns either `()` or an error if the step closure terminated in [`Step::Failure“]. |
| 182 #[inline] | 217 #[inline] |
| 183 fn iterate(&mut self) -> Result<(), Self::Err> { | 218 fn iterate<F, E>(&mut self, mut step_fn : F) -> Result<(), E> |
| 219 where F : FnMut(Self::State) -> Step<Self::Input, Self::State, E>, | |
| 220 E : Error { | |
| 184 loop { | 221 loop { |
| 185 match self.step() { | 222 match self.step(&mut step_fn) { |
| 186 Step::Terminated => return Ok(()), | 223 Step::Terminated => return Ok(()), |
| 187 Step::Failure(e) => return Err(e), | 224 Step::Failure(e) => return Err(e), |
| 188 _ => {}, | 225 _ => {}, |
| 189 } | 226 } |
| 190 } | 227 } |
| 191 } | 228 } |
| 192 | |
| 193 /// Converts the `AlgIterator` into a plain [`Iterator`]. | |
| 194 /// | |
| 195 /// [`Step::Quiet`] results are discarded, and [`Step::Failure`] results **panic**. | |
| 196 fn downcast(self) -> AlgIteratorI<Self> { | |
| 197 AlgIteratorI(self) | |
| 198 } | |
| 199 } | |
| 200 | |
| 201 /// Conversion of an `AlgIterator` into a plain [`Iterator`]. | |
| 202 /// | |
| 203 /// The conversion discards [`Step::Quiet`] and **panics** on [`Step::Failure`]. | |
| 204 pub struct AlgIteratorI<A>(A); | |
| 205 | |
| 206 impl<A> Iterator for AlgIteratorI<A> | |
| 207 where A : AlgIterator { | |
| 208 type Item = A::Output; | |
| 209 | |
| 210 fn next(&mut self) -> Option<A::Output> { | |
| 211 loop { | |
| 212 match self.0.step() { | |
| 213 Step::Result(v) => return Some(v), | |
| 214 Step::Failure(e) => panic!("{e:?}"), | |
| 215 Step::Terminated => return None, | |
| 216 Step::Quiet => continue, | |
| 217 } | |
| 218 } | |
| 219 } | |
| 220 } | 229 } |
| 221 | 230 |
| 222 /// A factory for producing an [`AlgIterator`]. | 231 /// A factory for producing an [`AlgIterator`]. |
| 223 /// | 232 /// |
| 224 /// For usage instructions see the [module documentation][self]. | 233 /// For usage instructions see the [module documentation][self]. |
| 225 pub trait AlgIteratorFactory<V> : Sized { | 234 pub trait AlgIteratorFactory<V> : Sized { |
| 226 type Iter<F, E> : AlgIterator<State = Self::State, Output = Self::Output, Err = E> | 235 type Iter : AlgIterator<State = Self::State, Input = V, Output = Self::Output>; |
| 227 where F : FnMut(&Self::State) -> Step<V, E>, | 236 |
| 228 E : Error; | |
| 229 /// The state type of the corresponding [`AlgIterator`]. | 237 /// The state type of the corresponding [`AlgIterator`]. |
| 230 /// A reference to this is passed to the closures passed to methods such as [`Self::iterate`]. | 238 /// A reference to this is passed to the closures passed to methods such as [`Self::iterate`]. |
| 231 type State : AlgIteratorState; | 239 type State : AlgIteratorState; |
| 232 /// The output type of the corresponding [`AlgIterator`]. | 240 /// The output type of the corresponding [`AlgIterator`]. |
| 233 /// This is the output of the closures passed to methods such as [`Self::iterate`] after | 241 /// This is the output of the closures passed to methods such as [`Self::iterate`] after |
| 234 /// mappings performed by each [`AlgIterator`] implementation. | 242 /// mappings performed by each [`AlgIterator`] implementation. |
| 235 type Output; | 243 type Output; |
| 236 | 244 |
| 237 /// Prepare an [`AlgIterator`], consuming the factory. | 245 /// Prepare an [`AlgIterator`], consuming the factory. |
| 238 /// | 246 fn prepare(self) -> Self::Iter; |
| 239 /// The function `step_fn` should accept a `state` ([`AlgIteratorState`] parameter, and return | |
| 240 /// a [`Step`]. | |
| 241 fn prepare<F, E>(self, step_fn : F) -> Self::Iter<F, E> | |
| 242 where F : FnMut(&Self::State) -> Step<V, E>, | |
| 243 E : Error; | |
| 244 | 247 |
| 245 /// Iterate the the closure `step`. | 248 /// Iterate the the closure `step`. |
| 246 /// | 249 /// |
| 247 /// The closure should accept a `state` parameter (satisfying the trait [`AlgIteratorState`]). | 250 /// The closure should accept a `state` parameter (satisfying the trait [`AlgIteratorState`]). |
| 248 /// It should return the output of | 251 /// It should return the output of |
| 250 /// completion for other reason, or [`Step::Failure`] for termination for failure. | 253 /// completion for other reason, or [`Step::Failure`] for termination for failure. |
| 251 /// | 254 /// |
| 252 /// This method is equivalent to [`Self::prepare`] followed by [`AlgIterator::iterate`]. | 255 /// This method is equivalent to [`Self::prepare`] followed by [`AlgIterator::iterate`]. |
| 253 #[inline] | 256 #[inline] |
| 254 fn iterate_fallible<F, E>(self, step : F) -> Result<(), E> | 257 fn iterate_fallible<F, E>(self, step : F) -> Result<(), E> |
| 255 where F : FnMut(&Self::State) -> Step<V, E>, | 258 where F : FnMut(Self::State) -> Step<V, Self::State, E>, |
| 256 E : Error { | 259 E : Error { |
| 257 self.prepare(step).iterate() | 260 self.prepare().iterate(step) |
| 258 } | 261 } |
| 259 | 262 |
| 260 /// Iterate the the closure `step`. | 263 /// Iterate the closure `step`. |
| 261 /// | 264 /// |
| 262 /// The closure should accept a `state` parameter (satisfying the trait [`AlgIteratorState`]), | 265 /// The closure should accept a `state` parameter (satisfying the trait [`AlgIteratorState`]), |
| 263 /// It should return the output of | 266 /// It should return the output of |
| 264 /// `state.`[`if_verbose`][AlgIteratorState::if_verbose]. | 267 /// `state.`[`if_verbose`][AlgIteratorState::if_verbose]. |
| 265 /// | 268 /// |
| 267 /// | 270 /// |
| 268 /// This method is equivalent to [`Self::prepare`] followed by [`AlgIterator::iterate`] | 271 /// This method is equivalent to [`Self::prepare`] followed by [`AlgIterator::iterate`] |
| 269 /// with the error type `E=`[`std::convert::Infallible`]. | 272 /// with the error type `E=`[`std::convert::Infallible`]. |
| 270 #[inline] | 273 #[inline] |
| 271 fn iterate<F>(self, step : F) | 274 fn iterate<F>(self, step : F) |
| 272 where F : FnMut(&Self::State) -> Step<V> { | 275 where F : FnMut(Self::State) -> Step<V, Self::State> { |
| 273 self.iterate_fallible(step).unwrap_or_default() | 276 self.iterate_fallible(step).unwrap_or_default() |
| 274 } | 277 } |
| 275 | 278 |
| 276 /// Iterate the closure `step` with data produced by `datasource`. | 279 /// Iterate the closure `step` with data produced by `datasource`. |
| 277 /// | 280 /// |
| 283 /// If the `datasource` runs out of data, the iterator is considered having terminated | 286 /// If the `datasource` runs out of data, the iterator is considered having terminated |
| 284 /// successsfully. | 287 /// successsfully. |
| 285 /// | 288 /// |
| 286 /// For usage instructions see the [module documentation][self]. | 289 /// For usage instructions see the [module documentation][self]. |
| 287 #[inline] | 290 #[inline] |
| 288 fn iterate_data_fallible<F, D, I, E>(self, mut datasource : I, mut step : F) -> Result<(), E> | 291 fn iterate_data_fallible<F, D, I, E>(self, mut datasource : I, mut step : F) |
| 289 where F : FnMut(&Self::State, D) -> Step<V, E>, | 292 -> Result<(), E> |
| 293 where F : FnMut(Self::State, D) -> Step<V, Self::State, E>, | |
| 290 I : Iterator<Item = D>, | 294 I : Iterator<Item = D>, |
| 291 E : Error { | 295 E : Error { |
| 292 self.prepare(move |state| { | 296 self.prepare().iterate(move |state| { |
| 293 datasource.next().map_or(Step::Terminated, |d| step(state, d)) | 297 datasource.next().map_or(Step::Terminated, |d| step(state, d)) |
| 294 }).iterate() | 298 }) |
| 295 } | 299 } |
| 296 | 300 |
| 297 /// Iterate the closure `step` with data produced by `datasource`. | 301 /// Iterate the closure `step` with data produced by `datasource`. |
| 298 /// | 302 /// |
| 299 /// The closure should accept a `state` parameter (satisfying the trait [`AlgIteratorState`]), | 303 /// The closure should accept a `state` parameter (satisfying the trait [`AlgIteratorState`]), |
| 304 /// successsfully. | 308 /// successsfully. |
| 305 /// | 309 /// |
| 306 /// For usage instructions see the [module documentation][self]. | 310 /// For usage instructions see the [module documentation][self]. |
| 307 #[inline] | 311 #[inline] |
| 308 fn iterate_data<F, D, I>(self, datasource : I, step : F) | 312 fn iterate_data<F, D, I>(self, datasource : I, step : F) |
| 309 where F : FnMut(&Self::State, D) -> Step<V>, | 313 where F : FnMut(Self::State, D) -> Step<V, Self::State>, |
| 310 I : Iterator<Item = D> { | 314 I : Iterator<Item = D> { |
| 311 self.iterate_data_fallible(datasource, step).unwrap_or_default() | 315 self.iterate_data_fallible(datasource, step).unwrap_or_default() |
| 312 } | 316 } |
| 313 | 317 |
| 314 // fn make_iterate<'own>(self) | 318 // fn make_iterate<'own>(self) |
| 393 StallIteratorFactory { base_options : self, stall : stall } | 397 StallIteratorFactory { base_options : self, stall : stall } |
| 394 } | 398 } |
| 395 | 399 |
| 396 /// Is the iterator quiet, i.e., on-verbose? | 400 /// Is the iterator quiet, i.e., on-verbose? |
| 397 fn is_quiet(&self) -> bool { false } | 401 fn is_quiet(&self) -> bool { false } |
| 402 | |
| 403 /// Returns an an [`std::iter::Iterator`] that can be used in a `for`-loop. | |
| 404 fn iter(self) -> AlgIteratorIterator<Self::Iter> { | |
| 405 AlgIteratorIterator { | |
| 406 algi : Rc::new(RefCell::new(self.prepare())), | |
| 407 } | |
| 408 } | |
| 409 | |
| 410 /// Returns an an [`std::iter::Iterator`] that can be used in a `for`-loop, | |
| 411 /// also inputting an initial iteration status calculated by `f` if needed. | |
| 412 fn iter_init(self, f : impl FnOnce() -> <Self::Iter as AlgIterator>::Input) | |
| 413 -> AlgIteratorIterator<Self::Iter> { | |
| 414 let mut i = self.prepare(); | |
| 415 let st = i.state(); | |
| 416 let step : Step<<Self::Iter as AlgIterator>::Input, Self::State> = st.if_verbose(f); | |
| 417 i.poststep(step); | |
| 418 AlgIteratorIterator { | |
| 419 algi : Rc::new(RefCell::new(i)), | |
| 420 } | |
| 421 } | |
| 398 } | 422 } |
| 399 | 423 |
| 400 /// Options for [`BasicAlgIteratorFactory`]. | 424 /// Options for [`BasicAlgIteratorFactory`]. |
| 401 /// | 425 /// |
| 402 /// Use as: | 426 /// Use as: |
| 425 /// $b$ is indicated logarithmic base. So, with $b=10$, | 449 /// $b$ is indicated logarithmic base. So, with $b=10$, |
| 426 /// * every iteration for first 10 iterations, | 450 /// * every iteration for first 10 iterations, |
| 427 /// * every 10 iterations from there on until 100 iterations, | 451 /// * every 10 iterations from there on until 100 iterations, |
| 428 /// * every 100 iteartinos frmo there on until 1000 iterations, etc. | 452 /// * every 100 iteartinos frmo there on until 1000 iterations, etc. |
| 429 Logarithmic(usize), | 453 Logarithmic(usize), |
| 454 /// Same as `Logarithmic`, but $\log_b(n)$ is replaced by $min\{c, \log_b(n)\}$ where $c$ | |
| 455 /// is the given `cap`. For example, with `base=10` and `cap=2`, the first ten iterations | |
| 456 /// will be output, then every tenth iteration, and after 100 iterations, every 100th iteration, | |
| 457 /// without further logarithmic progression. | |
| 458 LogarithmicCap{ base : usize, cap : u32 }, | |
| 430 } | 459 } |
| 431 | 460 |
| 432 impl Verbose { | 461 impl Verbose { |
| 433 /// Indicates whether given iteration number is verbose | 462 /// Indicates whether given iteration number is verbose |
| 434 pub fn is_verbose(&self, iter : usize) -> bool { | 463 pub fn is_verbose(&self, iter : usize) -> bool { |
| 441 }, | 470 }, |
| 442 &Verbose::Logarithmic(base) => { | 471 &Verbose::Logarithmic(base) => { |
| 443 let every = base.pow((iter as float).log(base as float).floor() as u32); | 472 let every = base.pow((iter as float).log(base as float).floor() as u32); |
| 444 iter % every == 0 | 473 iter % every == 0 |
| 445 } | 474 } |
| 475 &Verbose::LogarithmicCap{base, cap} => { | |
| 476 let every = base.pow(((iter as float).log(base as float).floor() as u32).min(cap)); | |
| 477 iter % every == 0 | |
| 478 } | |
| 446 } | 479 } |
| 447 } | 480 } |
| 448 } | 481 } |
| 449 | 482 |
| 450 impl Default for AlgIteratorOptions { | 483 impl Default for AlgIteratorOptions { |
| 465 /// Whether the iteration is verbose, i.e., results should be displayed. | 498 /// Whether the iteration is verbose, i.e., results should be displayed. |
| 466 /// Requires `calc` to be `true`. | 499 /// Requires `calc` to be `true`. |
| 467 verbose : bool, | 500 verbose : bool, |
| 468 /// Whether results should be calculated. | 501 /// Whether results should be calculated. |
| 469 calc : bool, | 502 calc : bool, |
| 503 /// Indicates whether the iteration is quiet | |
| 504 quiet : bool, | |
| 470 } | 505 } |
| 471 | 506 |
| 472 /// [`AlgIteratorFactory`] for [`BasicAlgIterator`] | 507 /// [`AlgIteratorFactory`] for [`BasicAlgIterator`] |
| 473 #[derive(Clone,Debug)] | 508 #[derive(Clone,Debug)] |
| 474 pub struct BasicAlgIteratorFactory<V> { | 509 pub struct BasicAlgIteratorFactory<V> { |
| 476 _phantoms : PhantomData<V>, | 511 _phantoms : PhantomData<V>, |
| 477 } | 512 } |
| 478 | 513 |
| 479 /// The simplest [`AlgIterator`], created by [`BasicAlgIteratorFactory`] | 514 /// The simplest [`AlgIterator`], created by [`BasicAlgIteratorFactory`] |
| 480 #[derive(Clone,Debug)] | 515 #[derive(Clone,Debug)] |
| 481 pub struct BasicAlgIterator<F, V, E : Error> { | 516 pub struct BasicAlgIterator<V> { |
| 482 options : AlgIteratorOptions, | 517 options : AlgIteratorOptions, |
| 483 iter : usize, | 518 iter : usize, |
| 484 step_fn : F, | 519 _phantoms : PhantomData<V>, |
| 485 _phantoms : PhantomData<(V, E)>, | |
| 486 } | 520 } |
| 487 | 521 |
| 488 impl AlgIteratorOptions { | 522 impl AlgIteratorOptions { |
| 489 /// [`AlgIteratorOptions`] is directly a factory for [`BasicAlgIterator`], | 523 /// [`AlgIteratorOptions`] is directly a factory for [`BasicAlgIterator`], |
| 490 /// however, due to type inference issues, it may become convenient to instantiate | 524 /// however, due to type inference issues, it may become convenient to instantiate |
| 498 } | 532 } |
| 499 | 533 |
| 500 impl<V> AlgIteratorFactory<V> for AlgIteratorOptions | 534 impl<V> AlgIteratorFactory<V> for AlgIteratorOptions |
| 501 where V : LogRepr { | 535 where V : LogRepr { |
| 502 type State = BasicState; | 536 type State = BasicState; |
| 503 type Iter<F, E> = BasicAlgIterator<F, V, E> | 537 type Iter = BasicAlgIterator<V>; |
| 504 where F : FnMut(&Self::State) -> Step<V, E>, | |
| 505 E : Error; | |
| 506 type Output = V; | 538 type Output = V; |
| 507 | 539 |
| 508 fn prepare<F, E>(self, step_fn : F) -> Self::Iter<F, E> | 540 fn prepare(self) -> Self::Iter { |
| 509 where F : FnMut(&Self::State) -> Step<V, E>, | |
| 510 E : Error { | |
| 511 BasicAlgIterator{ | 541 BasicAlgIterator{ |
| 512 options : self, | 542 options : self, |
| 513 iter : 0, | 543 iter : 0, |
| 514 step_fn, | |
| 515 _phantoms : PhantomData, | 544 _phantoms : PhantomData, |
| 516 } | 545 } |
| 517 } | 546 } |
| 518 | 547 |
| 519 #[inline] | 548 #[inline] |
| 523 } | 552 } |
| 524 | 553 |
| 525 impl<V> AlgIteratorFactory<V> for BasicAlgIteratorFactory<V> | 554 impl<V> AlgIteratorFactory<V> for BasicAlgIteratorFactory<V> |
| 526 where V : LogRepr { | 555 where V : LogRepr { |
| 527 type State = BasicState; | 556 type State = BasicState; |
| 528 type Iter<F, E> = BasicAlgIterator<F, V, E> | 557 type Iter = BasicAlgIterator<V>; |
| 529 where F : FnMut(&Self::State) -> Step<V, E>, | |
| 530 E : Error; | |
| 531 type Output = V; | 558 type Output = V; |
| 532 | 559 |
| 533 fn prepare<F, E>(self, step_fn : F) -> Self::Iter<F, E> | 560 fn prepare(self) -> Self::Iter { |
| 534 where F : FnMut(&Self::State) -> Step<V, E>, | |
| 535 E : Error { | |
| 536 BasicAlgIterator { | 561 BasicAlgIterator { |
| 537 options : self.options, | 562 options : self.options, |
| 538 iter : 0, | 563 iter : 0, |
| 539 step_fn, | |
| 540 _phantoms : PhantomData | 564 _phantoms : PhantomData |
| 541 } | 565 } |
| 542 } | 566 } |
| 543 | 567 |
| 544 #[inline] | 568 #[inline] |
| 545 fn is_quiet(&self) -> bool { | 569 fn is_quiet(&self) -> bool { |
| 546 self.options.quiet | 570 self.options.quiet |
| 547 } | 571 } |
| 548 } | 572 } |
| 549 | 573 |
| 550 impl<F, V, E> AlgIterator for BasicAlgIterator<F, V, E> | 574 impl<V> AlgIterator for BasicAlgIterator<V> |
| 551 where V : LogRepr, | 575 where V : LogRepr { |
| 552 E : Error, | |
| 553 F : FnMut(&BasicState) -> Step<V, E> { | |
| 554 type State = BasicState; | 576 type State = BasicState; |
| 555 type Output = V; | 577 type Output = V; |
| 556 type Err = E; | 578 type Input = V; |
| 557 | 579 |
| 558 #[inline] | 580 #[inline] |
| 559 fn step(&mut self) -> Step<V, E> { | 581 fn prestep(&mut self) -> Option<Self::State> { |
| 560 if self.iter >= self.options.max_iter { | 582 if self.iter >= self.options.max_iter { |
| 561 Step::Terminated | 583 None |
| 562 } else { | 584 } else { |
| 563 self.iter += 1; | 585 self.iter += 1; |
| 564 let state = self.state(); | 586 Some(self.state()) |
| 565 let res = (self.step_fn)(&state); | 587 } |
| 566 if let Step::Result(ref val) = res { | 588 } |
| 567 if state.verbose && !self.options.quiet { | 589 |
| 568 println!("{}{}/{} {}{}", "".dimmed(), | 590 fn poststep<E : Error>(&mut self, res : Step<V, Self::State, E>) -> Step<V, Self::State, E> { |
| 569 state.iter, | 591 if let Step::Result(ref val, ref state) = res { |
| 570 self.options.max_iter, | 592 if state.verbose && !self.options.quiet { |
| 571 val.logrepr(), | 593 println!("{}{}/{} {}{}", "".dimmed(), |
| 572 "".clear()); | 594 state.iter, |
| 573 } | 595 self.options.max_iter, |
| 596 val.logrepr(), | |
| 597 "".clear()); | |
| 574 } | 598 } |
| 575 res | 599 } |
| 576 } | 600 res |
| 577 } | 601 } |
| 578 | 602 |
| 579 #[inline] | 603 #[inline] |
| 580 fn iteration(&self) -> usize { | 604 fn iteration(&self) -> usize { |
| 581 self.iter | 605 self.iter |
| 583 | 607 |
| 584 #[inline] | 608 #[inline] |
| 585 fn state(&self) -> BasicState { | 609 fn state(&self) -> BasicState { |
| 586 let iter = self.iter; | 610 let iter = self.iter; |
| 587 let verbose = self.options.verbose_iter.is_verbose(iter); | 611 let verbose = self.options.verbose_iter.is_verbose(iter); |
| 588 BasicState{ | 612 BasicState { |
| 589 iter : iter, | 613 iter : iter, |
| 590 verbose : verbose, | 614 verbose : verbose, |
| 591 calc : verbose, | 615 calc : verbose, |
| 616 quiet : self.options.quiet | |
| 592 } | 617 } |
| 593 } | 618 } |
| 594 } | 619 } |
| 595 | 620 |
| 596 impl AlgIteratorState for BasicState { | 621 impl AlgIteratorState for BasicState { |
| 597 #[inline] | 622 #[inline] |
| 598 fn if_verbose<V, E : Error>(&self, mut calc_objective : impl FnMut() -> V) -> Step<V, E> { | 623 fn if_verbose<V, E : Error>(self, calc_objective : impl FnOnce() -> V) -> Step<V, Self, E> { |
| 599 if self.calc { | 624 if self.calc { |
| 600 Step::Result(calc_objective()) | 625 Step::Result(calc_objective(), self) |
| 601 } else { | 626 } else { |
| 602 Step::Quiet | 627 Step::Quiet |
| 603 } | 628 } |
| 604 } | 629 } |
| 605 | 630 |
| 606 #[inline] | 631 #[inline] |
| 607 fn iteration(&self) -> usize { | 632 fn iteration(&self) -> usize { |
| 608 return self.iter; | 633 self.iter |
| 634 } | |
| 635 | |
| 636 #[inline] | |
| 637 fn is_quiet(&self) -> bool { | |
| 638 self.quiet | |
| 609 } | 639 } |
| 610 } | 640 } |
| 611 | 641 |
| 612 // | 642 // |
| 613 // Stall detecting iteration function. | 643 // Stall detecting iteration function. |
| 634 | 664 |
| 635 impl<V, U, BaseFactory> AlgIteratorFactory<V> | 665 impl<V, U, BaseFactory> AlgIteratorFactory<V> |
| 636 for StallIteratorFactory<U, BaseFactory> | 666 for StallIteratorFactory<U, BaseFactory> |
| 637 where BaseFactory : AlgIteratorFactory<V, Output=U>, | 667 where BaseFactory : AlgIteratorFactory<V, Output=U>, |
| 638 U : SignedNum + PartialOrd { | 668 U : SignedNum + PartialOrd { |
| 639 type Iter<F, E> = StallIterator<U, BaseFactory::Iter<F, E>> | 669 type Iter = StallIterator<U, BaseFactory::Iter>; |
| 640 where F : FnMut(&Self::State) -> Step<V, E>, | |
| 641 E : Error; | |
| 642 type State = BaseFactory::State; | 670 type State = BaseFactory::State; |
| 643 type Output = BaseFactory::Output; | 671 type Output = BaseFactory::Output; |
| 644 | 672 |
| 645 fn prepare<F, E>(self, step_fn : F) -> Self::Iter<F, E> | 673 fn prepare(self) -> Self::Iter { |
| 646 where F : FnMut(&Self::State) -> Step<V, E>, | |
| 647 E : Error { | |
| 648 StallIterator { | 674 StallIterator { |
| 649 base_iterator : self.base_options.prepare(step_fn), | 675 base_iterator : self.base_options.prepare(), |
| 650 stall : self.stall, | 676 stall : self.stall, |
| 651 previous_value : None, | 677 previous_value : None, |
| 652 } | 678 } |
| 653 } | 679 } |
| 654 | 680 |
| 660 impl<U, BaseIterator> AlgIterator | 686 impl<U, BaseIterator> AlgIterator |
| 661 for StallIterator<U, BaseIterator> | 687 for StallIterator<U, BaseIterator> |
| 662 where BaseIterator : AlgIterator<Output=U>, | 688 where BaseIterator : AlgIterator<Output=U>, |
| 663 U : SignedNum + PartialOrd { | 689 U : SignedNum + PartialOrd { |
| 664 type State = BaseIterator::State; | 690 type State = BaseIterator::State; |
| 665 type Output = BaseIterator::Output; | 691 type Output = U; |
| 666 type Err = BaseIterator::Err; | 692 type Input = BaseIterator::Input; |
| 667 | 693 |
| 668 #[inline] | 694 #[inline] |
| 669 fn step(&mut self) -> Step<U, Self::Err> { | 695 fn prestep(&mut self) -> Option<Self::State> { |
| 670 match self.base_iterator.step() { | 696 self.base_iterator.prestep() |
| 671 Step::Result(nv) => { | 697 } |
| 698 | |
| 699 #[inline] | |
| 700 fn poststep<E>(&mut self, res : Step<Self::Input, Self::State, E>) -> Step<U, Self::State, E> | |
| 701 where E : Error { | |
| 702 match self.base_iterator.poststep(res) { | |
| 703 Step::Result(nv, state) => { | |
| 672 let previous_v = self.previous_value; | 704 let previous_v = self.previous_value; |
| 673 self.previous_value = Some(nv); | 705 self.previous_value = Some(nv); |
| 674 match previous_v { | 706 match previous_v { |
| 675 Some(pv) if (nv - pv).abs() <= self.stall * pv.abs() => Step::Terminated, | 707 Some(pv) if (nv - pv).abs() <= self.stall * pv.abs() => Step::Terminated, |
| 676 _ => Step::Result(nv), | 708 _ => Step::Result(nv, state), |
| 677 } | 709 } |
| 678 }, | 710 }, |
| 679 val => val, | 711 val => val, |
| 680 } | 712 } |
| 681 } | 713 } |
| 709 | 741 |
| 710 impl<V, U, BaseFactory> AlgIteratorFactory<V> | 742 impl<V, U, BaseFactory> AlgIteratorFactory<V> |
| 711 for ValueIteratorFactory<U, BaseFactory> | 743 for ValueIteratorFactory<U, BaseFactory> |
| 712 where BaseFactory : AlgIteratorFactory<V, Output=U>, | 744 where BaseFactory : AlgIteratorFactory<V, Output=U>, |
| 713 U : SignedNum + PartialOrd { | 745 U : SignedNum + PartialOrd { |
| 714 type Iter<F, E> = ValueIterator<U, BaseFactory::Iter<F, E>> | 746 type Iter = ValueIterator<U, BaseFactory::Iter>; |
| 715 where F : FnMut(&Self::State) -> Step<V, E>, | |
| 716 E : Error; | |
| 717 type State = BaseFactory::State; | 747 type State = BaseFactory::State; |
| 718 type Output = BaseFactory::Output; | 748 type Output = BaseFactory::Output; |
| 719 | 749 |
| 720 fn prepare<F, E>(self, step_fn : F) -> Self::Iter<F, E> | 750 fn prepare(self) -> Self::Iter { |
| 721 where F : FnMut(&Self::State) -> Step<V, E>, | |
| 722 E : Error { | |
| 723 ValueIterator { | 751 ValueIterator { |
| 724 base_iterator : self.base_options.prepare(step_fn), | 752 base_iterator : self.base_options.prepare(), |
| 725 target : self.target | 753 target : self.target |
| 726 } | 754 } |
| 727 } | 755 } |
| 728 | 756 |
| 729 fn is_quiet(&self) -> bool { | 757 fn is_quiet(&self) -> bool { |
| 734 impl<U, BaseIterator> AlgIterator | 762 impl<U, BaseIterator> AlgIterator |
| 735 for ValueIterator<U, BaseIterator> | 763 for ValueIterator<U, BaseIterator> |
| 736 where BaseIterator : AlgIterator<Output=U>, | 764 where BaseIterator : AlgIterator<Output=U>, |
| 737 U : SignedNum + PartialOrd { | 765 U : SignedNum + PartialOrd { |
| 738 type State = BaseIterator::State; | 766 type State = BaseIterator::State; |
| 739 type Output = BaseIterator::Output; | 767 type Output = U; |
| 740 type Err = BaseIterator::Err; | 768 type Input = BaseIterator::Input; |
| 741 | 769 |
| 742 #[inline] | 770 #[inline] |
| 743 fn step(&mut self) -> Step<U, Self::Err> { | 771 fn prestep(&mut self) -> Option<Self::State> { |
| 744 match self.base_iterator.step() { | 772 self.base_iterator.prestep() |
| 745 Step::Result(v) => { | 773 } |
| 774 | |
| 775 #[inline] | |
| 776 fn poststep<E>(&mut self, res : Step<Self::Input, Self::State, E>) -> Step<U, Self::State, E> where E : Error{ | |
| 777 match self.base_iterator.poststep(res) { | |
| 778 Step::Result(v, state) => { | |
| 746 if v <= self.target { | 779 if v <= self.target { |
| 747 Step::Terminated | 780 Step::Terminated |
| 748 } else { | 781 } else { |
| 749 Step::Result(v) | 782 Step::Result(v, state) |
| 750 } | 783 } |
| 751 }, | 784 }, |
| 752 val => val, | 785 val => val, |
| 753 } | 786 } |
| 754 } | 787 } |
| 790 impl<'log, V, BaseFactory> AlgIteratorFactory<V> | 823 impl<'log, V, BaseFactory> AlgIteratorFactory<V> |
| 791 for LoggingIteratorFactory<'log, BaseFactory::Output, BaseFactory> | 824 for LoggingIteratorFactory<'log, BaseFactory::Output, BaseFactory> |
| 792 where BaseFactory : AlgIteratorFactory<V>, | 825 where BaseFactory : AlgIteratorFactory<V>, |
| 793 BaseFactory::Output : 'log { | 826 BaseFactory::Output : 'log { |
| 794 type State = BaseFactory::State; | 827 type State = BaseFactory::State; |
| 795 type Iter<F, E> = LoggingIterator<'log, BaseFactory::Output, BaseFactory::Iter<F, E>> | 828 type Iter = LoggingIterator<'log, BaseFactory::Output, BaseFactory::Iter>; |
| 796 where F : FnMut(&Self::State) -> Step<V, E>, | |
| 797 E : Error; | |
| 798 type Output = (); | 829 type Output = (); |
| 799 | 830 |
| 800 fn prepare<F, E>(self, step_fn : F) -> Self::Iter<F, E> | 831 fn prepare(self) -> Self::Iter { |
| 801 where F : FnMut(&Self::State) -> Step<V, E>, | |
| 802 E : Error { | |
| 803 LoggingIterator { | 832 LoggingIterator { |
| 804 base_iterator : self.base_options.prepare(step_fn), | 833 base_iterator : self.base_options.prepare(), |
| 805 logger : self.logger, | 834 logger : self.logger, |
| 806 } | 835 } |
| 807 } | 836 } |
| 808 | 837 |
| 809 #[inline] | 838 #[inline] |
| 816 for LoggingIterator<'log, BaseIterator::Output, BaseIterator> | 845 for LoggingIterator<'log, BaseIterator::Output, BaseIterator> |
| 817 where BaseIterator : AlgIterator, | 846 where BaseIterator : AlgIterator, |
| 818 BaseIterator::Output : 'log { | 847 BaseIterator::Output : 'log { |
| 819 type State = BaseIterator::State; | 848 type State = BaseIterator::State; |
| 820 type Output = (); | 849 type Output = (); |
| 821 type Err = BaseIterator::Err; | 850 type Input = BaseIterator::Input; |
| 822 | 851 |
| 823 #[inline] | 852 #[inline] |
| 824 fn step(&mut self) -> Step<Self::Output, Self::Err> { | 853 fn prestep(&mut self) -> Option<Self::State> { |
| 825 match self.base_iterator.step() { | 854 self.base_iterator.prestep() |
| 826 Step::Result(v) => { | 855 } |
| 856 | |
| 857 #[inline] | |
| 858 fn poststep<E>(&mut self, res : Step<Self::Input, Self::State, E>) -> Step<(), Self::State, E> where E : Error { | |
| 859 match self.base_iterator.poststep(res) { | |
| 860 Step::Result(v, _) => { | |
| 827 self.logger.log(v); | 861 self.logger.log(v); |
| 828 Step::Quiet | 862 Step::Quiet |
| 829 }, | 863 }, |
| 830 Step::Quiet => Step::Quiet, | 864 Step::Quiet => Step::Quiet, |
| 831 Step::Terminated => Step::Terminated, | 865 Step::Terminated => Step::Terminated, |
| 843 self.base_iterator.state() | 877 self.base_iterator.state() |
| 844 } | 878 } |
| 845 } | 879 } |
| 846 | 880 |
| 847 /// This [`AlgIteratorFactory`] allows output mapping. | 881 /// This [`AlgIteratorFactory`] allows output mapping. |
| 848 /// | 882 /// |
| 849 /// Typically produced with [`AlgIteratorFactory::mapped`]. | 883 /// Typically produced with [`AlgIteratorFactory::mapped`]. |
| 850 #[derive(Debug)] | 884 #[derive(Debug)] |
| 851 pub struct MappingIteratorFactory<G, BaseFactory> { | 885 pub struct MappingIteratorFactory<G, BaseFactory> { |
| 852 /// Base [`AlgIteratorFactory`] on which to build | 886 /// Base [`AlgIteratorFactory`] on which to build |
| 853 base_options : BaseFactory, | 887 base_options : BaseFactory, |
| 866 impl<V, U, G, BaseFactory> AlgIteratorFactory<V> | 900 impl<V, U, G, BaseFactory> AlgIteratorFactory<V> |
| 867 for MappingIteratorFactory<G, BaseFactory> | 901 for MappingIteratorFactory<G, BaseFactory> |
| 868 where BaseFactory : AlgIteratorFactory<V>, | 902 where BaseFactory : AlgIteratorFactory<V>, |
| 869 G : Fn(usize, BaseFactory::Output) -> U { | 903 G : Fn(usize, BaseFactory::Output) -> U { |
| 870 type State = BaseFactory::State; | 904 type State = BaseFactory::State; |
| 871 type Iter<F, E> = MappingIterator<G, BaseFactory::Iter<F, E>> | 905 type Iter = MappingIterator<G, BaseFactory::Iter>; |
| 872 where F : FnMut(&Self::State) -> Step<V, E>, | |
| 873 E : Error; | |
| 874 type Output = U; | 906 type Output = U; |
| 875 | 907 |
| 876 fn prepare<F, E>(self, step_fn : F) -> Self::Iter<F, E> | 908 fn prepare(self) -> Self::Iter { |
| 877 where F : FnMut(&Self::State) -> Step<V, E>, | |
| 878 E : Error { | |
| 879 MappingIterator { | 909 MappingIterator { |
| 880 base_iterator : self.base_options.prepare(step_fn), | 910 base_iterator : self.base_options.prepare(), |
| 881 map : self.map | 911 map : self.map |
| 882 } | 912 } |
| 883 } | 913 } |
| 884 | 914 |
| 885 #[inline] | 915 #[inline] |
| 892 for MappingIterator<G, BaseIterator> | 922 for MappingIterator<G, BaseIterator> |
| 893 where BaseIterator : AlgIterator, | 923 where BaseIterator : AlgIterator, |
| 894 G : Fn(usize, BaseIterator::Output) -> U { | 924 G : Fn(usize, BaseIterator::Output) -> U { |
| 895 type State = BaseIterator::State; | 925 type State = BaseIterator::State; |
| 896 type Output = U; | 926 type Output = U; |
| 897 type Err = BaseIterator::Err; | 927 type Input = BaseIterator::Input; |
| 898 | 928 |
| 899 #[inline] | 929 #[inline] |
| 900 fn step(&mut self) -> Step<Self::Output, Self::Err> { | 930 fn prestep(&mut self) -> Option<Self::State> { |
| 901 match self.base_iterator.step() { | 931 self.base_iterator.prestep() |
| 902 Step::Result(v) => Step::Result((self.map)(self.iteration(), v)), | 932 } |
| 933 | |
| 934 #[inline] | |
| 935 fn poststep<E>(&mut self, res : Step<Self::Input, Self::State, E>) -> Step<Self::Output, Self::State, E> where E : Error { | |
| 936 match self.base_iterator.poststep(res) { | |
| 937 Step::Result(v, state) => Step::Result((self.map)(self.iteration(), v), state), | |
| 903 Step::Quiet => Step::Quiet, | 938 Step::Quiet => Step::Quiet, |
| 904 Step::Terminated => Step::Terminated, | 939 Step::Terminated => Step::Terminated, |
| 905 Step::Failure(e) => Step::Failure(e), | 940 Step::Failure(e) => Step::Failure(e), |
| 906 } | 941 } |
| 907 } | 942 } |
| 933 } | 968 } |
| 934 | 969 |
| 935 /// Data `U` with production time attached | 970 /// Data `U` with production time attached |
| 936 #[derive(Copy, Clone, Debug, Serialize)] | 971 #[derive(Copy, Clone, Debug, Serialize)] |
| 937 pub struct Timed<U> { | 972 pub struct Timed<U> { |
| 973 /// CPU time taken | |
| 938 pub cpu_time : Duration, | 974 pub cpu_time : Duration, |
| 975 /// Iteration number | |
| 976 pub iter : usize, | |
| 977 /// User data | |
| 939 //#[serde(flatten)] | 978 //#[serde(flatten)] |
| 940 pub data : U | 979 pub data : U |
| 941 } | 980 } |
| 942 | 981 |
| 943 impl<T> LogRepr for Timed<T> where T : LogRepr { | 982 impl<T> LogRepr for Timed<T> where T : LogRepr { |
| 949 | 988 |
| 950 impl<V, BaseFactory> AlgIteratorFactory<V> | 989 impl<V, BaseFactory> AlgIteratorFactory<V> |
| 951 for TimingIteratorFactory<BaseFactory> | 990 for TimingIteratorFactory<BaseFactory> |
| 952 where BaseFactory : AlgIteratorFactory<V> { | 991 where BaseFactory : AlgIteratorFactory<V> { |
| 953 type State = BaseFactory::State; | 992 type State = BaseFactory::State; |
| 954 type Iter<F, E> = TimingIterator<BaseFactory::Iter<F, E>> | 993 type Iter = TimingIterator<BaseFactory::Iter>; |
| 955 where F : FnMut(&Self::State) -> Step<V, E>, | |
| 956 E : Error; | |
| 957 type Output = Timed<BaseFactory::Output>; | 994 type Output = Timed<BaseFactory::Output>; |
| 958 | 995 |
| 959 fn prepare<F, E>(self, step_fn : F) -> Self::Iter<F, E> | 996 fn prepare(self) -> Self::Iter { |
| 960 where F : FnMut(&Self::State) -> Step<V, E>, | |
| 961 E : Error { | |
| 962 TimingIterator { | 997 TimingIterator { |
| 963 base_iterator : self.0.prepare(step_fn), | 998 base_iterator : self.0.prepare(), |
| 964 start_time : ProcessTime::now() | 999 start_time : ProcessTime::now() |
| 965 } | 1000 } |
| 966 } | 1001 } |
| 967 | 1002 |
| 968 #[inline] | 1003 #[inline] |
| 974 impl<BaseIterator> AlgIterator | 1009 impl<BaseIterator> AlgIterator |
| 975 for TimingIterator<BaseIterator> | 1010 for TimingIterator<BaseIterator> |
| 976 where BaseIterator : AlgIterator { | 1011 where BaseIterator : AlgIterator { |
| 977 type State = BaseIterator::State; | 1012 type State = BaseIterator::State; |
| 978 type Output = Timed<BaseIterator::Output>; | 1013 type Output = Timed<BaseIterator::Output>; |
| 979 type Err = BaseIterator::Err; | 1014 type Input = BaseIterator::Input; |
| 980 | 1015 |
| 981 #[inline] | 1016 #[inline] |
| 982 fn step(&mut self) -> Step<Self::Output, Self::Err> { | 1017 fn prestep(&mut self) -> Option<Self::State> { |
| 983 match self.base_iterator.step() { | 1018 self.base_iterator.prestep() |
| 984 Step::Result(data) => { | 1019 } |
| 1020 | |
| 1021 #[inline] | |
| 1022 fn poststep<E>(&mut self, res : Step<Self::Input, Self::State, E>) -> Step<Self::Output, Self::State, E> where E : Error { | |
| 1023 match self.base_iterator.poststep(res) { | |
| 1024 Step::Result(data, state) => { | |
| 985 Step::Result(Timed{ | 1025 Step::Result(Timed{ |
| 986 cpu_time : self.start_time.elapsed(), | 1026 cpu_time : self.start_time.elapsed(), |
| 1027 iter : self.iteration(), | |
| 987 data | 1028 data |
| 988 }) | 1029 }, state) |
| 989 }, | 1030 }, |
| 990 Step::Quiet => Step::Quiet, | 1031 Step::Quiet => Step::Quiet, |
| 991 Step::Terminated => Step::Terminated, | 1032 Step::Terminated => Step::Terminated, |
| 992 Step::Failure(e) => Step::Failure(e), | 1033 Step::Failure(e) => Step::Failure(e), |
| 993 } | 1034 } |
| 999 } | 1040 } |
| 1000 | 1041 |
| 1001 #[inline] | 1042 #[inline] |
| 1002 fn state(&self) -> Self::State { | 1043 fn state(&self) -> Self::State { |
| 1003 self.base_iterator.state() | 1044 self.base_iterator.state() |
| 1045 } | |
| 1046 } | |
| 1047 | |
| 1048 // | |
| 1049 // New for-loop interface | |
| 1050 // | |
| 1051 | |
| 1052 pub struct AlgIteratorIterator<I : AlgIterator> { | |
| 1053 algi : Rc<RefCell<I>>, | |
| 1054 } | |
| 1055 | |
| 1056 pub struct AlgIteratorIteration<I : AlgIterator> { | |
| 1057 state : I::State, | |
| 1058 algi : Rc<RefCell<I>>, | |
| 1059 } | |
| 1060 | |
| 1061 impl<I : AlgIterator> std::iter::Iterator for AlgIteratorIterator<I> { | |
| 1062 type Item = AlgIteratorIteration<I>; | |
| 1063 | |
| 1064 fn next(&mut self) -> Option<Self::Item> { | |
| 1065 let algi = self.algi.clone(); | |
| 1066 RefCell::borrow_mut(&self.algi).prestep().map(|state| AlgIteratorIteration { | |
| 1067 state, | |
| 1068 algi, | |
| 1069 }) | |
| 1070 } | |
| 1071 } | |
| 1072 | |
| 1073 /// Types of errors that may occur | |
| 1074 #[derive(Debug,PartialEq,Eq)] | |
| 1075 pub enum IterationError { | |
| 1076 /// [`AlgIteratorIteration::if_verbose_check`] is not called in iteration order. | |
| 1077 ReportingOrderingError | |
| 1078 } | |
| 1079 | |
| 1080 impl<I : AlgIterator> AlgIteratorIteration<I> { | |
| 1081 /// Call `call_objective` if this is a verbose iteration. | |
| 1082 /// | |
| 1083 /// Verbosity depends on the [`AlgIterator`] that produced this state. | |
| 1084 /// | |
| 1085 /// The closure `calc_objective` should return an arbitrary value of type `V`, to be inserted | |
| 1086 /// into the log, or whatever is deemed by the [`AlgIterator`]. For usage instructions see the | |
| 1087 /// [module documentation][self]. | |
| 1088 /// | |
| 1089 /// This function may panic if result reporting is not ordered correctly (an unlikely mistake | |
| 1090 /// if using this facility correctly). For a version that propagates errors, see | |
| 1091 /// [`Self::if_verbose_check`]. | |
| 1092 pub fn if_verbose(self, calc_objective : impl FnOnce() -> I::Input) { | |
| 1093 self.if_verbose_check(calc_objective).unwrap() | |
| 1094 } | |
| 1095 | |
| 1096 /// Version of [`Self::if_verbose`] that propagates errors instead of panicking. | |
| 1097 pub fn if_verbose_check(self, calc_objective : impl FnOnce() -> I::Input) | |
| 1098 -> Result<(), IterationError> { | |
| 1099 let mut algi = match RefCell::try_borrow_mut(&self.algi) { | |
| 1100 Err(_) => return Err(IterationError::ReportingOrderingError), | |
| 1101 Ok(algi) => algi | |
| 1102 }; | |
| 1103 if self.state.iteration() != algi.iteration() { | |
| 1104 Err(IterationError::ReportingOrderingError) | |
| 1105 } else { | |
| 1106 let res : Step<I::Input, I::State, std::convert::Infallible> | |
| 1107 = self.state.if_verbose(calc_objective); | |
| 1108 algi.poststep(res); | |
| 1109 Ok(()) | |
| 1110 } | |
| 1111 } | |
| 1112 | |
| 1113 /// Returns the current iteration count. | |
| 1114 pub fn iteration(&self) -> usize { | |
| 1115 self.state.iteration() | |
| 1116 } | |
| 1117 | |
| 1118 /// Indicates whether the iterator is quiet | |
| 1119 pub fn is_quiet(&self) -> bool { | |
| 1120 self.state.is_quiet() | |
| 1004 } | 1121 } |
| 1005 } | 1122 } |
| 1006 | 1123 |
| 1007 // | 1124 // |
| 1008 // Tests | 1125 // Tests |
| 1048 .skip(2) | 1165 .skip(2) |
| 1049 .step_by(3) | 1166 .step_by(3) |
| 1050 .collect::<Vec<int>>()) | 1167 .collect::<Vec<int>>()) |
| 1051 } | 1168 } |
| 1052 } | 1169 } |
| 1053 } | 1170 |
| 1171 #[test] | |
| 1172 fn iteration_for_loop() { | |
| 1173 let options = AlgIteratorOptions{ | |
| 1174 max_iter : 10, | |
| 1175 verbose_iter : Verbose::Every(3), | |
| 1176 .. Default::default() | |
| 1177 }; | |
| 1178 | |
| 1179 { | |
| 1180 let mut start = 1 as int; | |
| 1181 for state in options.iter() { | |
| 1182 start = start * 2; | |
| 1183 state.if_verbose(|| start) | |
| 1184 } | |
| 1185 assert_eq!(start, (2 as int).pow(10)); | |
| 1186 } | |
| 1187 | |
| 1188 { | |
| 1189 let mut start = 1 as int; | |
| 1190 let mut log = Logger::new(); | |
| 1191 let factory = options.instantiate() | |
| 1192 .with_iteration_number() | |
| 1193 .into_log(&mut log); | |
| 1194 for state in factory.iter() { | |
| 1195 start = start * 2; | |
| 1196 state.if_verbose(|| start) | |
| 1197 } | |
| 1198 assert_eq!(start, (2 as int).pow(10)); | |
| 1199 assert_eq!(log.data() | |
| 1200 .iter() | |
| 1201 .map(|LogItem{ data : v, iter : _ }| v.clone()) | |
| 1202 .collect::<Vec<int>>(), | |
| 1203 (1..10).map(|i| (2 as int).pow(i)) | |
| 1204 .skip(2) | |
| 1205 .step_by(3) | |
| 1206 .collect::<Vec<int>>()) | |
| 1207 } | |
| 1208 } | |
| 1209 | |
| 1210 } |