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 } |