Wed, 22 Apr 2026 23:41:59 -0500
Fix internal links in documentation
| 0 | 1 | /*! |
| 5 | 2 | Tools for separating the computational steps of an iterative algorithm from stopping rules |
| 3 | and reporting. | |
| 0 | 4 | |
| 5 | 5 | The computational step is to be implemented as a closure. That closure gets passed a `state` |
| 6 | parameter that implements an [`if_verbose`][AlgIteratorState::if_verbose] method that is to | |
| 7 | be called to determine whether function values or other potentially costly things need to be | |
| 8 | calculated on that iteration. The parameter of [`if_verbose`][AlgIteratorState::if_verbose] is | |
| 9 | another closure that does the necessary computation. | |
| 0 | 10 | |
| 11 | ## Simple example | |
| 12 | ||
| 13 | ```rust | |
| 5 | 14 | # use alg_tools::types::*; |
| 15 | # use alg_tools::iterate::*; | |
| 16 | let mut iter = AlgIteratorOptions{ | |
| 17 | max_iter : 100, | |
| 18 | verbose_iter : Verbose::Every(10), | |
| 19 | .. Default::default() | |
| 20 | }; | |
| 0 | 21 | let mut x = 1 as float; |
|
41
121cf065e9ed
Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents:
40
diff
changeset
|
22 | # let mut iter_clone = iter.clone(); |
| 0 | 23 | iter.iterate(|state|{ |
| 24 | // This is our computational step | |
| 25 | x = x + x.sqrt(); | |
| 26 | state.if_verbose(||{ | |
| 27 | // return current value when requested | |
| 28 | return x | |
| 29 | }) | |
|
41
121cf065e9ed
Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents:
40
diff
changeset
|
30 | }); |
|
121cf065e9ed
Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents:
40
diff
changeset
|
31 | // or alternatively (avoiding problems with moves) |
|
121cf065e9ed
Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents:
40
diff
changeset
|
32 | # iter = iter_clone; |
|
121cf065e9ed
Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents:
40
diff
changeset
|
33 | for state in iter.iter() { |
|
121cf065e9ed
Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents:
40
diff
changeset
|
34 | // This is our computational step |
|
121cf065e9ed
Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents:
40
diff
changeset
|
35 | x = x + x.sqrt(); |
|
121cf065e9ed
Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents:
40
diff
changeset
|
36 | state.if_verbose(||{ |
|
121cf065e9ed
Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents:
40
diff
changeset
|
37 | // return current value when requested |
|
121cf065e9ed
Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents:
40
diff
changeset
|
38 | return x |
|
121cf065e9ed
Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents:
40
diff
changeset
|
39 | }) |
|
121cf065e9ed
Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents:
40
diff
changeset
|
40 | } |
| 0 | 41 | ``` |
| 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. | |
| 43 | ||
| 44 | This will print out | |
| 45 | ```output | |
| 46 | 10/100 J=31.051164 | |
| 47 | 20/100 J=108.493699 | |
| 48 | 30/100 J=234.690039 | |
| 49 | 40/100 J=410.056327 | |
| 50 | 50/100 J=634.799262 | |
| 51 | 60/100 J=909.042928 | |
| 52 | 70/100 J=1232.870172 | |
| 53 | 80/100 J=1606.340254 | |
| 54 | 90/100 J=2029.497673 | |
| 55 | 100/100 J=2502.377071 | |
| 56 | ``` | |
| 57 | */ | |
| 58 | ||
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
59 | use crate::logger::*; |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
60 | use crate::types::*; |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
61 | use colored::{ColoredString, Colorize}; |
| 0 | 62 | use core::fmt::Debug; |
| 63 | use cpu_time::ProcessTime; | |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
64 | use serde::{Deserialize, Serialize}; |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
65 | use std::cell::RefCell; |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
66 | use std::error::Error; |
| 0 | 67 | use std::marker::PhantomData; |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
68 | use std::rc::Rc; |
| 0 | 69 | use std::time::Duration; |
| 70 | ||
| 5 | 71 | /// Create the displayed presentation for log items. |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
72 | pub trait LogRepr: Debug { |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
73 | fn logrepr(&self) -> ColoredString { |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
74 | format!("« {self:?} »").as_str().into() |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
75 | } |
| 0 | 76 | } |
| 77 | ||
| 78 | impl LogRepr for str { | |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
79 | fn logrepr(&self) -> ColoredString { |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
80 | self.into() |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
81 | } |
| 0 | 82 | } |
| 83 | ||
| 84 | impl LogRepr for String { | |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
85 | fn logrepr(&self) -> ColoredString { |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
86 | self.as_str().into() |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
87 | } |
| 0 | 88 | } |
| 89 | ||
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
90 | impl<T> LogRepr for T |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
91 | where |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
92 | T: Num, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
93 | { |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
94 | fn logrepr(&self) -> ColoredString { |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
95 | format!("J={self}").as_str().into() |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
96 | } |
| 0 | 97 | } |
| 98 | ||
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
99 | impl<V> LogRepr for Option<V> |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
100 | where |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
101 | V: LogRepr, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
102 | { |
| 0 | 103 | fn logrepr(&self) -> ColoredString { |
| 104 | match self { | |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
105 | None => "===missing value===".red(), |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
106 | Some(v) => v.logrepr(), |
| 0 | 107 | } |
| 108 | } | |
| 109 | } | |
| 110 | ||
| 5 | 111 | /// Helper struct for returning results annotated with an additional string to |
| 112 | /// [`if_verbose`][AlgIteratorState::if_verbose]. The [`LogRepr`] implementation will | |
| 113 | /// display that string when so decided by the specific [`AlgIterator`] in use. | |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
114 | #[derive(Debug, Clone)] |
| 0 | 115 | pub struct Annotated<F>(pub F, pub String); |
| 116 | ||
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
117 | impl<V> LogRepr for Annotated<V> |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
118 | where |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
119 | V: LogRepr, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
120 | { |
| 0 | 121 | fn logrepr(&self) -> ColoredString { |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
122 | format!("{}\t| {}", self.0.logrepr(), self.1) |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
123 | .as_str() |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
124 | .into() |
| 0 | 125 | } |
| 126 | } | |
| 127 | ||
| 128 | /// Basic log item. | |
| 129 | #[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)] | |
| 130 | pub struct LogItem<V> { | |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
131 | pub iter: usize, |
| 0 | 132 | // This causes [`csv`] to crash. |
| 133 | //#[serde(flatten)] | |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
134 | pub data: V, |
| 0 | 135 | } |
| 136 | ||
| 5 | 137 | impl<V> LogItem<V> { |
| 138 | /// Creates a new log item | |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
139 | fn new(iter: usize, data: V) -> Self { |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
140 | LogItem { iter, data } |
| 5 | 141 | } |
| 0 | 142 | } |
| 143 | ||
| 5 | 144 | /// State of an [`AlgIterator`]. |
| 145 | /// | |
| 146 | /// This is the parameter obtained by the closure passed to [`AlgIterator::iterate`] or | |
| 147 | /// [`AlgIteratorFactory::iterate`]. | |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
148 | pub trait AlgIteratorState: Sized { |
|
3
20db884b7028
Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
149 | /// Call `call_objective` if this is a verbose iteration. |
|
20db884b7028
Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
150 | /// |
|
20db884b7028
Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
151 | /// Verbosity depends on the [`AlgIterator`] that produced this state. |
|
20db884b7028
Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
152 | /// |
|
20db884b7028
Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
153 | /// The closure `calc_objective` should return an arbitrary value of type `V`, to be inserted |
|
20db884b7028
Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
154 | /// into the log, or whatever is deemed by the [`AlgIterator`]. For usage instructions see the |
|
20db884b7028
Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
155 | /// [module documentation][self]. |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
156 | fn if_verbose<V, E: Error>(self, calc_objective: impl FnOnce() -> V) -> Step<V, Self, E>; |
| 0 | 157 | |
| 5 | 158 | /// Returns the current iteration count. |
| 0 | 159 | fn iteration(&self) -> usize; |
|
31
50a77e4efcbb
Add is_quiet to AlgIteratorState as well.
Tuomo Valkonen <tuomov@iki.fi>
parents:
5
diff
changeset
|
160 | |
|
50a77e4efcbb
Add is_quiet to AlgIteratorState as well.
Tuomo Valkonen <tuomov@iki.fi>
parents:
5
diff
changeset
|
161 | /// Indicates whether the iterator is quiet |
|
50a77e4efcbb
Add is_quiet to AlgIteratorState as well.
Tuomo Valkonen <tuomov@iki.fi>
parents:
5
diff
changeset
|
162 | fn is_quiet(&self) -> bool; |
| 0 | 163 | } |
| 164 | ||
| 165 | /// Result of a step of an [`AlgIterator`] | |
| 166 | #[derive(Debug, Serialize)] | |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
167 | pub enum Step<V, S, Fail: Error = std::convert::Infallible> { |
| 0 | 168 | /// Iteration should be terminated |
| 169 | Terminated, | |
|
3
20db884b7028
Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
170 | /// Iteration should be terminated due to failure |
|
20db884b7028
Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
171 | Failure(Fail), |
| 0 | 172 | /// No result this iteration (due to verbosity settings) |
| 173 | Quiet, | |
| 174 | /// Result of this iteration (due to verbosity settings) | |
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
175 | Result(V, S), |
| 0 | 176 | } |
| 177 | ||
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
178 | impl<V, S, E: Error> Step<V, S, E> { |
|
3
20db884b7028
Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
179 | /// Maps the value contained within the `Step`, if any, by the closure `f`. |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
180 | pub fn map<U>(self, mut f: impl FnMut(V) -> U) -> Step<U, S, E> { |
|
3
20db884b7028
Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
181 | match self { |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
182 | Step::Result(v, s) => Step::Result(f(v), s), |
|
3
20db884b7028
Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
183 | Step::Failure(e) => Step::Failure(e), |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
184 | Step::Quiet => Step::Quiet, |
|
3
20db884b7028
Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
185 | Step::Terminated => Step::Terminated, |
|
20db884b7028
Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
186 | } |
|
20db884b7028
Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
187 | } |
|
20db884b7028
Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
188 | } |
|
20db884b7028
Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
189 | |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
190 | impl<V, S, E: Error> Default for Step<V, S, E> { |
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
191 | fn default() -> Self { |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
192 | Step::Quiet |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
193 | } |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
194 | } |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
195 | |
| 5 | 196 | /// An iterator for algorithms, produced by [`AlgIteratorFactory::prepare`]. |
|
3
20db884b7028
Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
197 | /// |
|
20db884b7028
Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
198 | /// Typically not accessed directly, but transparently produced by an [`AlgIteratorFactory`]. |
|
20db884b7028
Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
199 | /// Every [`AlgIteratorFactory`] has to implement a corresponding `AlgIterator`. |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
200 | pub trait AlgIterator: Sized { |
| 5 | 201 | /// The state type |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
202 | type State: AlgIteratorState; |
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
203 | /// The output type for [`Self::poststep`] and [`Self::step`]. |
| 0 | 204 | type Output; |
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
205 | /// The input type for [`Self::poststep`]. |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
206 | type Input; |
| 0 | 207 | |
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
208 | /// Advance the iterator, performing `step_fn` with the state |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
209 | fn step<F, E>(&mut self, step_fn: &mut F) -> Step<Self::Output, Self::State, E> |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
210 | where |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
211 | F: FnMut(Self::State) -> Step<Self::Input, Self::State, E>, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
212 | E: Error, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
213 | { |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
214 | self.prestep() |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
215 | .map_or(Step::Terminated, |state| self.poststep(step_fn(state))) |
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
216 | } |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
217 | |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
218 | /// Initial stage of advancing the iterator, before the actual step |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
219 | fn prestep(&mut self) -> Option<Self::State>; |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
220 | |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
221 | /// Handle step result |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
222 | fn poststep<E>( |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
223 | &mut self, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
224 | result: Step<Self::Input, Self::State, E>, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
225 | ) -> Step<Self::Output, Self::State, E> |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
226 | where |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
227 | E: Error; |
| 0 | 228 | |
| 229 | /// Return current iteration count. | |
| 230 | fn iteration(&self) -> usize { | |
| 231 | self.state().iteration() | |
| 232 | } | |
| 233 | ||
| 5 | 234 | /// Return current state. |
| 0 | 235 | fn state(&self) -> Self::State; |
| 236 | ||
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
237 | /// Iterate the `AlgIterator` until termination, erforming `step_fn` on each step. |
|
3
20db884b7028
Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
238 | /// |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
239 | /// Returns either `()` or an error if the step closure terminated in [`Step::Failure`]. |
| 0 | 240 | #[inline] |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
241 | fn iterate<F, E>(&mut self, mut step_fn: F) -> Result<(), E> |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
242 | where |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
243 | F: FnMut(Self::State) -> Step<Self::Input, Self::State, E>, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
244 | E: Error, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
245 | { |
| 0 | 246 | loop { |
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
247 | match self.step(&mut step_fn) { |
|
3
20db884b7028
Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
248 | Step::Terminated => return Ok(()), |
|
20db884b7028
Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
249 | Step::Failure(e) => return Err(e), |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
250 | _ => {} |
| 0 | 251 | } |
| 252 | } | |
| 253 | } | |
| 254 | } | |
| 255 | ||
| 5 | 256 | /// A factory for producing an [`AlgIterator`]. |
| 0 | 257 | /// |
| 5 | 258 | /// For usage instructions see the [module documentation][self]. |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
259 | pub trait AlgIteratorFactory<V>: Sized { |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
260 | type Iter: AlgIterator<State = Self::State, Input = V, Output = Self::Output>; |
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
261 | |
| 5 | 262 | /// The state type of the corresponding [`AlgIterator`]. |
| 263 | /// A reference to this is passed to the closures passed to methods such as [`Self::iterate`]. | |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
264 | type State: AlgIteratorState; |
| 5 | 265 | /// The output type of the corresponding [`AlgIterator`]. |
| 266 | /// This is the output of the closures passed to methods such as [`Self::iterate`] after | |
| 267 | /// mappings performed by each [`AlgIterator`] implementation. | |
| 0 | 268 | type Output; |
| 269 | ||
| 270 | /// Prepare an [`AlgIterator`], consuming the factory. | |
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
271 | fn prepare(self) -> Self::Iter; |
| 0 | 272 | |
|
3
20db884b7028
Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
273 | /// Iterate the the closure `step`. |
|
20db884b7028
Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
274 | /// |
| 5 | 275 | /// The closure should accept a `state` parameter (satisfying the trait [`AlgIteratorState`]). |
| 276 | /// It should return the output of | |
| 277 | /// `state.`[`if_verbose`][AlgIteratorState::if_verbose], [`Step::Terminated`] to indicate | |
| 278 | /// completion for other reason, or [`Step::Failure`] for termination for failure. | |
|
3
20db884b7028
Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
279 | /// |
|
20db884b7028
Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
280 | /// This method is equivalent to [`Self::prepare`] followed by [`AlgIterator::iterate`]. |
|
20db884b7028
Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
281 | #[inline] |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
282 | fn iterate_fallible<F, E>(self, step: F) -> Result<(), E> |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
283 | where |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
284 | F: FnMut(Self::State) -> Step<V, Self::State, E>, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
285 | E: Error, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
286 | { |
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
287 | self.prepare().iterate(step) |
|
3
20db884b7028
Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
288 | } |
|
20db884b7028
Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
289 | |
| 46 | 290 | /// Iterate the closure `step`. |
|
3
20db884b7028
Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
291 | /// |
| 5 | 292 | /// The closure should accept a `state` parameter (satisfying the trait [`AlgIteratorState`]), |
| 293 | /// It should return the output of | |
| 294 | /// `state.`[`if_verbose`][AlgIteratorState::if_verbose]. | |
|
3
20db884b7028
Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
295 | /// |
|
20db884b7028
Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
296 | /// For usage instructions see the [module documentation][self]. |
| 0 | 297 | /// |
|
3
20db884b7028
Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
298 | /// This method is equivalent to [`Self::prepare`] followed by [`AlgIterator::iterate`] |
|
20db884b7028
Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
299 | /// with the error type `E=`[`std::convert::Infallible`]. |
| 0 | 300 | #[inline] |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
301 | fn iterate<F>(self, step: F) |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
302 | where |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
303 | F: FnMut(Self::State) -> Step<V, Self::State>, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
304 | { |
|
3
20db884b7028
Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
305 | self.iterate_fallible(step).unwrap_or_default() |
|
20db884b7028
Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
306 | } |
|
20db884b7028
Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
307 | |
|
20db884b7028
Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
308 | /// Iterate the closure `step` with data produced by `datasource`. |
|
20db884b7028
Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
309 | /// |
| 5 | 310 | /// The closure should accept a `state` parameter (satisfying the trait [`AlgIteratorState`]), |
| 311 | /// and a data parameter taken from `datasource`. It should return the output of | |
| 312 | /// `state.`[`if_verbose`][AlgIteratorState::if_verbose], [`Step::Terminated`] to indicate | |
|
3
20db884b7028
Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
313 | /// completion for other reason, or [`Step::Failure`] for termination for failure. |
|
20db884b7028
Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
314 | /// |
|
20db884b7028
Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
315 | /// If the `datasource` runs out of data, the iterator is considered having terminated |
|
20db884b7028
Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
316 | /// successsfully. |
|
20db884b7028
Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
317 | /// |
|
20db884b7028
Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
318 | /// For usage instructions see the [module documentation][self]. |
|
20db884b7028
Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
319 | #[inline] |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
320 | fn iterate_data_fallible<F, D, I, E>(self, mut datasource: I, mut step: F) -> Result<(), E> |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
321 | where |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
322 | F: FnMut(Self::State, D) -> Step<V, Self::State, E>, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
323 | I: Iterator<Item = D>, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
324 | E: Error, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
325 | { |
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
326 | self.prepare().iterate(move |state| { |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
327 | datasource |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
328 | .next() |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
329 | .map_or(Step::Terminated, |d| step(state, d)) |
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
330 | }) |
| 0 | 331 | } |
| 332 | ||
|
3
20db884b7028
Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
333 | /// Iterate the closure `step` with data produced by `datasource`. |
|
20db884b7028
Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
334 | /// |
| 5 | 335 | /// The closure should accept a `state` parameter (satisfying the trait [`AlgIteratorState`]), |
| 336 | /// and a data parameter taken from `datasource`. It should return the output of | |
| 337 | /// `state.`[`if_verbose`][AlgIteratorState::if_verbose]. | |
|
3
20db884b7028
Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
338 | /// |
|
20db884b7028
Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
339 | /// If the `datasource` runs out of data, the iterator is considered having terminated |
|
20db884b7028
Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
340 | /// successsfully. |
|
20db884b7028
Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
341 | /// |
| 0 | 342 | /// For usage instructions see the [module documentation][self]. |
| 343 | #[inline] | |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
344 | fn iterate_data<F, D, I>(self, datasource: I, step: F) |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
345 | where |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
346 | F: FnMut(Self::State, D) -> Step<V, Self::State>, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
347 | I: Iterator<Item = D>, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
348 | { |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
349 | self.iterate_data_fallible(datasource, step) |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
350 | .unwrap_or_default() |
| 0 | 351 | } |
| 352 | ||
| 353 | // fn make_iterate<'own>(self) | |
| 354 | // -> Box<dyn (FnMut(dyn FnMut(&Self::State) -> Option<V>) -> ()) + 'own> { | |
| 355 | // Box::new(move |step| self.iterate(step)) | |
| 356 | // } | |
| 357 | ||
| 358 | // fn make_iterate_data<'own, D, I>(self, datasource : I) | |
| 359 | // -> Box<dyn (FnMut(dyn FnMut(&Self::State, D) -> Option<V>) -> ()) + 'own> | |
| 360 | // where I : Iterator<Item = D> + 'own { | |
| 361 | // Box::new(move |step| self.iterate_data(step, datasource)) | |
| 362 | // } | |
| 363 | ||
| 364 | /// Add logging to the iterator produced by the factory. | |
| 5 | 365 | /// |
| 366 | /// Returns a new factory whose corresponding [`AlgIterator`] only inserts that data into the | |
| 367 | /// log without passing it onwards. | |
| 368 | /// | |
| 369 | /// Use as: | |
| 370 | /// ```rust | |
| 371 | /// # use alg_tools::iterate::*; | |
| 372 | /// # use alg_tools::logger::*; | |
| 373 | /// let iter = AlgIteratorOptions::default(); | |
| 374 | /// let mut log = Logger::new(); | |
| 375 | /// iter.into_log(&mut log).iterate(|state|{ | |
| 376 | /// // perform iterations | |
| 377 | /// state.if_verbose(||{ | |
| 378 | /// // calculate and return function value or other displayed data v | |
| 379 | /// return 0 | |
| 380 | /// }) | |
| 381 | /// }) | |
| 382 | /// ``` | |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
383 | fn into_log<'log>( |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
384 | self, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
385 | logger: &'log mut Logger<Self::Output>, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
386 | ) -> LoggingIteratorFactory<'log, Self::Output, Self> |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
387 | where |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
388 | Self: Sized, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
389 | { |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
390 | LoggingIteratorFactory { base_options: self, logger } |
| 0 | 391 | } |
| 392 | ||
| 393 | /// Map the output of the iterator produced by the factory. | |
| 5 | 394 | /// |
| 395 | /// Returns a new factory. | |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
396 | fn mapped<U, G>(self, map: G) -> MappingIteratorFactory<G, Self> |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
397 | where |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
398 | Self: Sized, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
399 | G: Fn(usize, Self::Output) -> U, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
400 | { |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
401 | MappingIteratorFactory { base_options: self, map } |
| 0 | 402 | } |
| 403 | ||
| 5 | 404 | /// Adds iteration number to the output. |
| 405 | /// | |
| 406 | /// Returns a new factory. | |
| 407 | /// Typically followed by [`Self::into_log`]. | |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
408 | fn with_iteration_number( |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
409 | self, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
410 | ) -> MappingIteratorFactory<fn(usize, Self::Output) -> LogItem<Self::Output>, Self> |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
411 | where |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
412 | Self: Sized, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
413 | { |
| 5 | 414 | self.mapped(LogItem::new) |
| 0 | 415 | } |
| 416 | ||
| 417 | /// Add timing to the iterator produced by the factory. | |
| 418 | fn timed(self) -> TimingIteratorFactory<Self> | |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
419 | where |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
420 | Self: Sized, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
421 | { |
| 0 | 422 | TimingIteratorFactory(self) |
| 423 | } | |
| 424 | ||
| 425 | /// Add value stopping threshold to the iterator produce by the factory | |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
426 | fn stop_target(self, target: Self::Output) -> ValueIteratorFactory<Self::Output, Self> |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
427 | where |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
428 | Self: Sized, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
429 | Self::Output: Num, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
430 | { |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
431 | ValueIteratorFactory { base_options: self, target: target } |
| 0 | 432 | } |
| 433 | ||
| 434 | /// Add stall stopping to the iterator produce by the factory | |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
435 | fn stop_stall(self, stall: Self::Output) -> StallIteratorFactory<Self::Output, Self> |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
436 | where |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
437 | Self: Sized, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
438 | Self::Output: Num, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
439 | { |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
440 | StallIteratorFactory { base_options: self, stall: stall } |
| 0 | 441 | } |
| 442 | ||
| 443 | /// Is the iterator quiet, i.e., on-verbose? | |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
444 | fn is_quiet(&self) -> bool { |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
445 | false |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
446 | } |
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
447 | |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
448 | /// Returns an an [`std::iter::Iterator`] that can be used in a `for`-loop. |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
449 | fn iter(self) -> AlgIteratorIterator<Self::Iter> { |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
450 | AlgIteratorIterator { algi: Rc::new(RefCell::new(self.prepare())) } |
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
451 | } |
| 46 | 452 | |
| 453 | /// Returns an an [`std::iter::Iterator`] that can be used in a `for`-loop, | |
| 454 | /// also inputting an initial iteration status calculated by `f` if needed. | |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
455 | fn iter_init( |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
456 | self, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
457 | f: impl FnOnce() -> <Self::Iter as AlgIterator>::Input, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
458 | ) -> AlgIteratorIterator<Self::Iter> { |
| 46 | 459 | let mut i = self.prepare(); |
| 460 | let st = i.state(); | |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
461 | let step: Step<<Self::Iter as AlgIterator>::Input, Self::State> = st.if_verbose(f); |
| 46 | 462 | i.poststep(step); |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
463 | AlgIteratorIterator { algi: Rc::new(RefCell::new(i)) } |
| 46 | 464 | } |
| 0 | 465 | } |
| 466 | ||
| 5 | 467 | /// Options for [`BasicAlgIteratorFactory`]. |
| 468 | /// | |
| 469 | /// Use as: | |
| 0 | 470 | /// ``` |
| 471 | /// # use alg_tools::iterate::*; | |
| 472 | /// let iter = AlgIteratorOptions{ max_iter : 10000, .. Default::default() }; | |
| 473 | /// ``` | |
| 474 | #[derive(Clone, Copy, Debug, Serialize, Deserialize, Eq, PartialEq)] | |
| 475 | pub struct AlgIteratorOptions { | |
| 476 | /// Maximum number of iterations | |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
477 | pub max_iter: usize, |
| 0 | 478 | /// Number of iterations between verbose iterations that display state. |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
479 | pub verbose_iter: Verbose, |
| 0 | 480 | /// Whether verbose iterations are displayed, or just passed onwards to a containing |
| 481 | /// `AlgIterator`. | |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
482 | pub quiet: bool, |
| 0 | 483 | } |
| 484 | ||
| 485 | #[derive(Clone, Copy, Debug, Serialize, Deserialize, Eq, PartialEq)] | |
| 486 | pub enum Verbose { | |
| 487 | /// Be verbose every $n$ iterations. | |
| 488 | Every(usize), | |
| 489 | /// Be verbose every $n$ iterations and initial $m$ iterations. | |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
490 | EveryAndInitial { every: usize, initial: usize }, |
| 0 | 491 | /// Be verbose if iteration number $n$ divides by $b^{\text{floor}(\log_b(n))}$, where |
| 492 | /// $b$ is indicated logarithmic base. So, with $b=10$, | |
| 493 | /// * every iteration for first 10 iterations, | |
| 494 | /// * every 10 iterations from there on until 100 iterations, | |
| 495 | /// * every 100 iteartinos frmo there on until 1000 iterations, etc. | |
| 496 | Logarithmic(usize), | |
|
87
72968cf30033
LogarithmicCap verbosity option
Tuomo Valkonen <tuomov@iki.fi>
parents:
51
diff
changeset
|
497 | /// Same as `Logarithmic`, but $\log_b(n)$ is replaced by $min\{c, \log_b(n)\}$ where $c$ |
|
72968cf30033
LogarithmicCap verbosity option
Tuomo Valkonen <tuomov@iki.fi>
parents:
51
diff
changeset
|
498 | /// is the given `cap`. For example, with `base=10` and `cap=2`, the first ten iterations |
|
72968cf30033
LogarithmicCap verbosity option
Tuomo Valkonen <tuomov@iki.fi>
parents:
51
diff
changeset
|
499 | /// will be output, then every tenth iteration, and after 100 iterations, every 100th iteration, |
|
72968cf30033
LogarithmicCap verbosity option
Tuomo Valkonen <tuomov@iki.fi>
parents:
51
diff
changeset
|
500 | /// without further logarithmic progression. |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
501 | LogarithmicCap { base: usize, cap: u32 }, |
| 0 | 502 | } |
| 503 | ||
| 504 | impl Verbose { | |
| 505 | /// Indicates whether given iteration number is verbose | |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
506 | pub fn is_verbose(&self, iter: usize) -> bool { |
| 0 | 507 | match self { |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
508 | &Verbose::Every(every) => every != 0 && iter % every == 0, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
509 | &Verbose::EveryAndInitial { every, initial } => { |
| 0 | 510 | iter <= initial || (every != 0 && iter % every == 0) |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
511 | } |
| 0 | 512 | &Verbose::Logarithmic(base) => { |
|
25
d14c877e14b7
Logarithmic logging base correction
Tuomo Valkonen <tuomov@iki.fi>
parents:
5
diff
changeset
|
513 | let every = base.pow((iter as float).log(base as float).floor() as u32); |
| 0 | 514 | iter % every == 0 |
| 515 | } | |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
516 | &Verbose::LogarithmicCap { base, cap } => { |
|
87
72968cf30033
LogarithmicCap verbosity option
Tuomo Valkonen <tuomov@iki.fi>
parents:
51
diff
changeset
|
517 | let every = base.pow(((iter as float).log(base as float).floor() as u32).min(cap)); |
|
72968cf30033
LogarithmicCap verbosity option
Tuomo Valkonen <tuomov@iki.fi>
parents:
51
diff
changeset
|
518 | iter % every == 0 |
|
72968cf30033
LogarithmicCap verbosity option
Tuomo Valkonen <tuomov@iki.fi>
parents:
51
diff
changeset
|
519 | } |
| 0 | 520 | } |
| 521 | } | |
| 522 | } | |
| 523 | ||
| 524 | impl Default for AlgIteratorOptions { | |
| 525 | fn default() -> AlgIteratorOptions { | |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
526 | AlgIteratorOptions { |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
527 | max_iter: 1000, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
528 | verbose_iter: Verbose::EveryAndInitial { every: 100, initial: 10 }, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
529 | quiet: false, |
| 0 | 530 | } |
| 531 | } | |
| 532 | } | |
| 533 | ||
| 534 | /// State of a `BasicAlgIterator` | |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
535 | #[derive(Clone, Copy, Debug, Serialize, Eq, PartialEq)] |
| 0 | 536 | pub struct BasicState { |
| 5 | 537 | /// Current iteration |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
538 | iter: usize, |
| 5 | 539 | /// Whether the iteration is verbose, i.e., results should be displayed. |
| 540 | /// Requires `calc` to be `true`. | |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
541 | verbose: bool, |
| 5 | 542 | /// Whether results should be calculated. |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
543 | calc: bool, |
|
31
50a77e4efcbb
Add is_quiet to AlgIteratorState as well.
Tuomo Valkonen <tuomov@iki.fi>
parents:
5
diff
changeset
|
544 | /// Indicates whether the iteration is quiet |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
545 | quiet: bool, |
| 0 | 546 | } |
| 547 | ||
| 548 | /// [`AlgIteratorFactory`] for [`BasicAlgIterator`] | |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
549 | #[derive(Clone, Debug)] |
| 0 | 550 | pub struct BasicAlgIteratorFactory<V> { |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
551 | options: AlgIteratorOptions, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
552 | _phantoms: PhantomData<V>, |
| 0 | 553 | } |
| 554 | ||
| 5 | 555 | /// The simplest [`AlgIterator`], created by [`BasicAlgIteratorFactory`] |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
556 | #[derive(Clone, Debug)] |
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
557 | pub struct BasicAlgIterator<V> { |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
558 | options: AlgIteratorOptions, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
559 | iter: usize, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
560 | _phantoms: PhantomData<V>, |
| 0 | 561 | } |
| 562 | ||
| 563 | impl AlgIteratorOptions { | |
| 564 | /// [`AlgIteratorOptions`] is directly a factory for [`BasicAlgIterator`], | |
| 565 | /// however, due to type inference issues, it may become convenient to instantiate | |
| 566 | /// it to a specific return type for the inner step function. This method does that. | |
| 567 | pub fn instantiate<V>(&self) -> BasicAlgIteratorFactory<V> { | |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
568 | BasicAlgIteratorFactory { options: self.clone(), _phantoms: PhantomData } |
| 0 | 569 | } |
| 570 | } | |
| 571 | ||
| 572 | impl<V> AlgIteratorFactory<V> for AlgIteratorOptions | |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
573 | where |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
574 | V: LogRepr, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
575 | { |
| 0 | 576 | type State = BasicState; |
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
577 | type Iter = BasicAlgIterator<V>; |
| 0 | 578 | type Output = V; |
| 579 | ||
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
580 | fn prepare(self) -> Self::Iter { |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
581 | BasicAlgIterator { options: self, iter: 0, _phantoms: PhantomData } |
| 0 | 582 | } |
| 583 | ||
| 584 | #[inline] | |
| 585 | fn is_quiet(&self) -> bool { | |
| 586 | self.quiet | |
| 587 | } | |
| 588 | } | |
| 589 | ||
| 590 | impl<V> AlgIteratorFactory<V> for BasicAlgIteratorFactory<V> | |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
591 | where |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
592 | V: LogRepr, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
593 | { |
| 0 | 594 | type State = BasicState; |
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
595 | type Iter = BasicAlgIterator<V>; |
| 0 | 596 | type Output = V; |
| 597 | ||
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
598 | fn prepare(self) -> Self::Iter { |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
599 | BasicAlgIterator { options: self.options, iter: 0, _phantoms: PhantomData } |
| 0 | 600 | } |
| 601 | ||
| 602 | #[inline] | |
| 603 | fn is_quiet(&self) -> bool { | |
| 604 | self.options.quiet | |
| 605 | } | |
| 606 | } | |
| 607 | ||
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
608 | impl<V> AlgIterator for BasicAlgIterator<V> |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
609 | where |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
610 | V: LogRepr, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
611 | { |
| 0 | 612 | type State = BasicState; |
| 613 | type Output = V; | |
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
614 | type Input = V; |
| 0 | 615 | |
| 616 | #[inline] | |
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
617 | fn prestep(&mut self) -> Option<Self::State> { |
| 0 | 618 | if self.iter >= self.options.max_iter { |
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
619 | None |
| 0 | 620 | } else { |
| 621 | self.iter += 1; | |
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
622 | Some(self.state()) |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
623 | } |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
624 | } |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
625 | |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
626 | fn poststep<E: Error>(&mut self, res: Step<V, Self::State, E>) -> Step<V, Self::State, E> { |
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
627 | if let Step::Result(ref val, ref state) = res { |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
628 | if state.verbose && !self.options.quiet { |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
629 | println!( |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
630 | "{}{}/{} {}{}", |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
631 | "".dimmed(), |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
632 | state.iter, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
633 | self.options.max_iter, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
634 | val.logrepr(), |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
635 | "".clear() |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
636 | ); |
| 0 | 637 | } |
| 638 | } | |
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
639 | res |
| 0 | 640 | } |
| 641 | ||
| 642 | #[inline] | |
| 643 | fn iteration(&self) -> usize { | |
| 644 | self.iter | |
| 645 | } | |
| 646 | ||
| 647 | #[inline] | |
| 648 | fn state(&self) -> BasicState { | |
| 649 | let iter = self.iter; | |
| 650 | let verbose = self.options.verbose_iter.is_verbose(iter); | |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
651 | BasicState { iter: iter, verbose: verbose, calc: verbose, quiet: self.options.quiet } |
| 0 | 652 | } |
| 653 | } | |
| 654 | ||
| 655 | impl AlgIteratorState for BasicState { | |
| 656 | #[inline] | |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
657 | fn if_verbose<V, E: Error>(self, calc_objective: impl FnOnce() -> V) -> Step<V, Self, E> { |
| 0 | 658 | if self.calc { |
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
659 | Step::Result(calc_objective(), self) |
| 0 | 660 | } else { |
|
3
20db884b7028
Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
661 | Step::Quiet |
| 0 | 662 | } |
| 663 | } | |
| 664 | ||
| 665 | #[inline] | |
| 666 | fn iteration(&self) -> usize { | |
|
31
50a77e4efcbb
Add is_quiet to AlgIteratorState as well.
Tuomo Valkonen <tuomov@iki.fi>
parents:
5
diff
changeset
|
667 | self.iter |
|
50a77e4efcbb
Add is_quiet to AlgIteratorState as well.
Tuomo Valkonen <tuomov@iki.fi>
parents:
5
diff
changeset
|
668 | } |
|
50a77e4efcbb
Add is_quiet to AlgIteratorState as well.
Tuomo Valkonen <tuomov@iki.fi>
parents:
5
diff
changeset
|
669 | |
|
50a77e4efcbb
Add is_quiet to AlgIteratorState as well.
Tuomo Valkonen <tuomov@iki.fi>
parents:
5
diff
changeset
|
670 | #[inline] |
|
50a77e4efcbb
Add is_quiet to AlgIteratorState as well.
Tuomo Valkonen <tuomov@iki.fi>
parents:
5
diff
changeset
|
671 | fn is_quiet(&self) -> bool { |
|
50a77e4efcbb
Add is_quiet to AlgIteratorState as well.
Tuomo Valkonen <tuomov@iki.fi>
parents:
5
diff
changeset
|
672 | self.quiet |
| 0 | 673 | } |
| 674 | } | |
| 675 | ||
| 676 | // | |
| 677 | // Stall detecting iteration function. | |
| 678 | // | |
| 679 | ||
| 5 | 680 | /// An [`AlgIteratorFactory`] for an [`AlgIterator`] that detects “stall”. |
| 681 | /// | |
| 682 | /// We define stall as $(v_{k+n}-v_k)/v_k ≤ θ$, where $n$ the distance between | |
| 683 | /// [`Step::Result`] iterations, and $θ$ is the provided `stall` parameter. | |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
684 | #[derive(Clone, Copy, Debug, Serialize, Eq, PartialEq)] |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
685 | pub struct StallIteratorFactory<U: Num, BaseFactory> { |
| 5 | 686 | /// An [`AlgIteratorFactory`] on which to build on |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
687 | pub base_options: BaseFactory, |
| 0 | 688 | /// Stalling threshold $θ$. |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
689 | pub stall: U, |
| 0 | 690 | } |
| 691 | ||
| 692 | /// Iterator produced by [`StallIteratorFactory`]. | |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
693 | pub struct StallIterator<U: Num, BaseIterator> { |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
694 | base_iterator: BaseIterator, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
695 | stall: U, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
696 | previous_value: Option<U>, |
| 0 | 697 | } |
| 698 | ||
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
699 | impl<V, U, BaseFactory> AlgIteratorFactory<V> for StallIteratorFactory<U, BaseFactory> |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
700 | where |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
701 | BaseFactory: AlgIteratorFactory<V, Output = U>, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
702 | U: SignedNum + PartialOrd, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
703 | { |
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
704 | type Iter = StallIterator<U, BaseFactory::Iter>; |
| 0 | 705 | type State = BaseFactory::State; |
| 706 | type Output = BaseFactory::Output; | |
| 707 | ||
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
708 | fn prepare(self) -> Self::Iter { |
| 0 | 709 | StallIterator { |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
710 | base_iterator: self.base_options.prepare(), |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
711 | stall: self.stall, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
712 | previous_value: None, |
| 0 | 713 | } |
| 714 | } | |
| 715 | ||
| 716 | fn is_quiet(&self) -> bool { | |
| 717 | self.base_options.is_quiet() | |
| 718 | } | |
| 719 | } | |
| 720 | ||
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
721 | impl<U, BaseIterator> AlgIterator for StallIterator<U, BaseIterator> |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
722 | where |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
723 | BaseIterator: AlgIterator<Output = U>, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
724 | U: SignedNum + PartialOrd, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
725 | { |
| 0 | 726 | type State = BaseIterator::State; |
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
727 | type Output = U; |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
728 | type Input = BaseIterator::Input; |
| 0 | 729 | |
| 730 | #[inline] | |
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
731 | fn prestep(&mut self) -> Option<Self::State> { |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
732 | self.base_iterator.prestep() |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
733 | } |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
734 | |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
735 | #[inline] |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
736 | fn poststep<E>(&mut self, res: Step<Self::Input, Self::State, E>) -> Step<U, Self::State, E> |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
737 | where |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
738 | E: Error, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
739 | { |
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
740 | match self.base_iterator.poststep(res) { |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
741 | Step::Result(nv, state) => { |
| 0 | 742 | let previous_v = self.previous_value; |
| 743 | self.previous_value = Some(nv); | |
| 744 | match previous_v { | |
| 745 | Some(pv) if (nv - pv).abs() <= self.stall * pv.abs() => Step::Terminated, | |
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
746 | _ => Step::Result(nv, state), |
| 0 | 747 | } |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
748 | } |
| 0 | 749 | val => val, |
| 750 | } | |
| 751 | } | |
| 752 | ||
| 753 | #[inline] | |
| 754 | fn iteration(&self) -> usize { | |
| 755 | self.base_iterator.iteration() | |
| 756 | } | |
| 757 | ||
| 758 | #[inline] | |
| 759 | fn state(&self) -> Self::State { | |
| 760 | self.base_iterator.state() | |
| 761 | } | |
| 762 | } | |
| 763 | ||
| 764 | /// An [`AlgIteratorFactory`] for an [`AlgIterator`] that detect whether step function | |
| 765 | /// return value is less than `target`, and terminates if it is. | |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
766 | #[derive(Clone, Copy, Debug, Serialize, Eq, PartialEq)] |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
767 | pub struct ValueIteratorFactory<U: Num, BaseFactory> { |
| 5 | 768 | /// An [`AlgIteratorFactory`] on which to build on |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
769 | pub base_options: BaseFactory, |
| 5 | 770 | /// Target value |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
771 | pub target: U, |
| 0 | 772 | } |
| 773 | ||
| 774 | /// Iterator produced by [`ValueIteratorFactory`]. | |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
775 | pub struct ValueIterator<U: Num, BaseIterator> { |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
776 | base_iterator: BaseIterator, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
777 | target: U, |
| 0 | 778 | } |
| 779 | ||
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
780 | impl<V, U, BaseFactory> AlgIteratorFactory<V> for ValueIteratorFactory<U, BaseFactory> |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
781 | where |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
782 | BaseFactory: AlgIteratorFactory<V, Output = U>, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
783 | U: SignedNum + PartialOrd, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
784 | { |
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
785 | type Iter = ValueIterator<U, BaseFactory::Iter>; |
| 0 | 786 | type State = BaseFactory::State; |
| 787 | type Output = BaseFactory::Output; | |
| 788 | ||
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
789 | fn prepare(self) -> Self::Iter { |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
790 | ValueIterator { base_iterator: self.base_options.prepare(), target: self.target } |
| 0 | 791 | } |
| 792 | ||
| 793 | fn is_quiet(&self) -> bool { | |
| 794 | self.base_options.is_quiet() | |
| 795 | } | |
| 796 | } | |
| 797 | ||
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
798 | impl<U, BaseIterator> AlgIterator for ValueIterator<U, BaseIterator> |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
799 | where |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
800 | BaseIterator: AlgIterator<Output = U>, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
801 | U: SignedNum + PartialOrd, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
802 | { |
| 0 | 803 | type State = BaseIterator::State; |
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
804 | type Output = U; |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
805 | type Input = BaseIterator::Input; |
| 0 | 806 | |
| 807 | #[inline] | |
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
808 | fn prestep(&mut self) -> Option<Self::State> { |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
809 | self.base_iterator.prestep() |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
810 | } |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
811 | |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
812 | #[inline] |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
813 | fn poststep<E>(&mut self, res: Step<Self::Input, Self::State, E>) -> Step<U, Self::State, E> |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
814 | where |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
815 | E: Error, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
816 | { |
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
817 | match self.base_iterator.poststep(res) { |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
818 | Step::Result(v, state) => { |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
819 | if v <= self.target { |
| 0 | 820 | Step::Terminated |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
821 | } else { |
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
822 | Step::Result(v, state) |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
823 | } |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
824 | } |
| 0 | 825 | val => val, |
| 826 | } | |
| 827 | } | |
| 828 | ||
| 829 | #[inline] | |
| 830 | fn iteration(&self) -> usize { | |
| 831 | self.base_iterator.iteration() | |
| 832 | } | |
| 833 | ||
| 834 | #[inline] | |
| 835 | fn state(&self) -> Self::State { | |
| 836 | self.base_iterator.state() | |
| 837 | } | |
| 838 | } | |
| 839 | ||
| 840 | // | |
| 841 | // Logging iterator | |
| 842 | // | |
| 843 | ||
| 844 | /// [`AlgIteratorFactory`] for a logging [`AlgIterator`]. | |
| 5 | 845 | /// |
| 846 | /// Typically produced with [`AlgIteratorFactory::into_log`]. | |
| 0 | 847 | /// The `Output` of the corresponding [`LoggingIterator`] is `()`: |
| 848 | #[derive(Debug)] | |
| 849 | pub struct LoggingIteratorFactory<'log, U, BaseFactory> { | |
| 5 | 850 | /// Base [`AlgIteratorFactory`] on which to build |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
851 | base_options: BaseFactory, |
| 5 | 852 | /// The `Logger` to use. |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
853 | logger: &'log mut Logger<U>, |
| 0 | 854 | } |
| 855 | ||
| 856 | /// Iterator produced by `LoggingIteratorFactory`. | |
| 857 | pub struct LoggingIterator<'log, U, BaseIterator> { | |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
858 | base_iterator: BaseIterator, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
859 | logger: &'log mut Logger<U>, |
| 0 | 860 | } |
| 861 | ||
| 862 | impl<'log, V, BaseFactory> AlgIteratorFactory<V> | |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
863 | for LoggingIteratorFactory<'log, BaseFactory::Output, BaseFactory> |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
864 | where |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
865 | BaseFactory: AlgIteratorFactory<V>, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
866 | BaseFactory::Output: 'log, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
867 | { |
| 0 | 868 | type State = BaseFactory::State; |
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
869 | type Iter = LoggingIterator<'log, BaseFactory::Output, BaseFactory::Iter>; |
| 0 | 870 | type Output = (); |
| 871 | ||
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
872 | fn prepare(self) -> Self::Iter { |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
873 | LoggingIterator { base_iterator: self.base_options.prepare(), logger: self.logger } |
| 0 | 874 | } |
| 875 | ||
| 876 | #[inline] | |
| 877 | fn is_quiet(&self) -> bool { | |
| 878 | self.base_options.is_quiet() | |
| 879 | } | |
| 880 | } | |
| 881 | ||
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
882 | impl<'log, BaseIterator> AlgIterator for LoggingIterator<'log, BaseIterator::Output, BaseIterator> |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
883 | where |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
884 | BaseIterator: AlgIterator, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
885 | BaseIterator::Output: 'log, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
886 | { |
| 0 | 887 | type State = BaseIterator::State; |
| 888 | type Output = (); | |
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
889 | type Input = BaseIterator::Input; |
| 0 | 890 | |
| 891 | #[inline] | |
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
892 | fn prestep(&mut self) -> Option<Self::State> { |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
893 | self.base_iterator.prestep() |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
894 | } |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
895 | |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
896 | #[inline] |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
897 | fn poststep<E>(&mut self, res: Step<Self::Input, Self::State, E>) -> Step<(), Self::State, E> |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
898 | where |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
899 | E: Error, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
900 | { |
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
901 | match self.base_iterator.poststep(res) { |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
902 | Step::Result(v, _) => { |
| 0 | 903 | self.logger.log(v); |
| 904 | Step::Quiet | |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
905 | } |
| 0 | 906 | Step::Quiet => Step::Quiet, |
| 907 | Step::Terminated => Step::Terminated, | |
|
3
20db884b7028
Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
908 | Step::Failure(e) => Step::Failure(e), |
| 0 | 909 | } |
| 910 | } | |
| 911 | ||
| 912 | #[inline] | |
| 913 | fn iteration(&self) -> usize { | |
| 914 | self.base_iterator.iteration() | |
| 915 | } | |
| 916 | ||
| 917 | #[inline] | |
| 918 | fn state(&self) -> Self::State { | |
| 919 | self.base_iterator.state() | |
| 920 | } | |
| 921 | } | |
| 922 | ||
| 923 | /// This [`AlgIteratorFactory`] allows output mapping. | |
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
924 | /// |
| 5 | 925 | /// Typically produced with [`AlgIteratorFactory::mapped`]. |
| 0 | 926 | #[derive(Debug)] |
| 927 | pub struct MappingIteratorFactory<G, BaseFactory> { | |
| 5 | 928 | /// Base [`AlgIteratorFactory`] on which to build |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
929 | base_options: BaseFactory, |
| 5 | 930 | /// A closure `G : Fn(usize, BaseFactory::Output) -> U` that gets the current iteration |
| 931 | /// and the output of the base factory as input, and produces a new output. | |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
932 | map: G, |
| 0 | 933 | } |
| 934 | ||
| 5 | 935 | /// [`AlgIterator`] produced by [`MappingIteratorFactory`]. |
| 0 | 936 | pub struct MappingIterator<G, BaseIterator> { |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
937 | base_iterator: BaseIterator, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
938 | map: G, |
| 0 | 939 | } |
| 940 | ||
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
941 | impl<V, U, G, BaseFactory> AlgIteratorFactory<V> for MappingIteratorFactory<G, BaseFactory> |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
942 | where |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
943 | BaseFactory: AlgIteratorFactory<V>, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
944 | G: Fn(usize, BaseFactory::Output) -> U, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
945 | { |
| 0 | 946 | type State = BaseFactory::State; |
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
947 | type Iter = MappingIterator<G, BaseFactory::Iter>; |
| 0 | 948 | type Output = U; |
| 949 | ||
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
950 | fn prepare(self) -> Self::Iter { |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
951 | MappingIterator { base_iterator: self.base_options.prepare(), map: self.map } |
| 0 | 952 | } |
| 953 | ||
| 954 | #[inline] | |
| 955 | fn is_quiet(&self) -> bool { | |
| 956 | self.base_options.is_quiet() | |
| 957 | } | |
| 958 | } | |
| 959 | ||
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
960 | impl<U, G, BaseIterator> AlgIterator for MappingIterator<G, BaseIterator> |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
961 | where |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
962 | BaseIterator: AlgIterator, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
963 | G: Fn(usize, BaseIterator::Output) -> U, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
964 | { |
| 0 | 965 | type State = BaseIterator::State; |
| 966 | type Output = U; | |
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
967 | type Input = BaseIterator::Input; |
| 0 | 968 | |
| 969 | #[inline] | |
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
970 | fn prestep(&mut self) -> Option<Self::State> { |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
971 | self.base_iterator.prestep() |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
972 | } |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
973 | |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
974 | #[inline] |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
975 | fn poststep<E>( |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
976 | &mut self, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
977 | res: Step<Self::Input, Self::State, E>, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
978 | ) -> Step<Self::Output, Self::State, E> |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
979 | where |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
980 | E: Error, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
981 | { |
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
982 | match self.base_iterator.poststep(res) { |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
983 | Step::Result(v, state) => Step::Result((self.map)(self.iteration(), v), state), |
| 0 | 984 | Step::Quiet => Step::Quiet, |
| 985 | Step::Terminated => Step::Terminated, | |
|
3
20db884b7028
Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
986 | Step::Failure(e) => Step::Failure(e), |
| 0 | 987 | } |
| 988 | } | |
| 989 | ||
| 990 | #[inline] | |
| 991 | fn iteration(&self) -> usize { | |
| 992 | self.base_iterator.iteration() | |
| 993 | } | |
| 994 | ||
| 995 | #[inline] | |
| 996 | fn state(&self) -> Self::State { | |
| 997 | self.base_iterator.state() | |
| 998 | } | |
| 999 | } | |
| 1000 | ||
| 1001 | // | |
| 1002 | // Timing iterator | |
| 1003 | // | |
| 1004 | ||
| 5 | 1005 | /// An [`AlgIteratorFactory`] for an [`AlgIterator`] that adds spent CPU time to verbose events. |
| 0 | 1006 | #[derive(Debug)] |
| 1007 | pub struct TimingIteratorFactory<BaseFactory>(pub BaseFactory); | |
| 1008 | ||
| 1009 | /// Iterator produced by [`TimingIteratorFactory`] | |
| 1010 | #[derive(Debug)] | |
| 1011 | pub struct TimingIterator<BaseIterator> { | |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1012 | base_iterator: BaseIterator, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1013 | start_time: ProcessTime, |
| 0 | 1014 | } |
| 1015 | ||
| 1016 | /// Data `U` with production time attached | |
| 1017 | #[derive(Copy, Clone, Debug, Serialize)] | |
| 1018 | pub struct Timed<U> { | |
| 51 | 1019 | /// CPU time taken |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1020 | pub cpu_time: Duration, |
| 51 | 1021 | /// Iteration number |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1022 | pub iter: usize, |
| 51 | 1023 | /// User data |
| 0 | 1024 | //#[serde(flatten)] |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1025 | pub data: U, |
| 0 | 1026 | } |
| 1027 | ||
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1028 | impl<T> LogRepr for Timed<T> |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1029 | where |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1030 | T: LogRepr, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1031 | { |
| 0 | 1032 | fn logrepr(&self) -> ColoredString { |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1033 | format!( |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1034 | "[{:.3}s] {}", |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1035 | self.cpu_time.as_secs_f64(), |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1036 | self.data.logrepr() |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1037 | ) |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1038 | .as_str() |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1039 | .into() |
| 0 | 1040 | } |
| 1041 | } | |
| 1042 | ||
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1043 | impl<V, BaseFactory> AlgIteratorFactory<V> for TimingIteratorFactory<BaseFactory> |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1044 | where |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1045 | BaseFactory: AlgIteratorFactory<V>, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1046 | { |
| 0 | 1047 | type State = BaseFactory::State; |
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
1048 | type Iter = TimingIterator<BaseFactory::Iter>; |
| 0 | 1049 | type Output = Timed<BaseFactory::Output>; |
| 1050 | ||
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
1051 | fn prepare(self) -> Self::Iter { |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1052 | TimingIterator { base_iterator: self.0.prepare(), start_time: ProcessTime::now() } |
| 0 | 1053 | } |
| 1054 | ||
| 1055 | #[inline] | |
| 1056 | fn is_quiet(&self) -> bool { | |
| 1057 | self.0.is_quiet() | |
| 1058 | } | |
| 1059 | } | |
| 1060 | ||
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1061 | impl<BaseIterator> AlgIterator for TimingIterator<BaseIterator> |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1062 | where |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1063 | BaseIterator: AlgIterator, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1064 | { |
| 0 | 1065 | type State = BaseIterator::State; |
| 1066 | type Output = Timed<BaseIterator::Output>; | |
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
1067 | type Input = BaseIterator::Input; |
| 0 | 1068 | |
| 1069 | #[inline] | |
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
1070 | fn prestep(&mut self) -> Option<Self::State> { |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
1071 | self.base_iterator.prestep() |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
1072 | } |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
1073 | |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
1074 | #[inline] |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1075 | fn poststep<E>( |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1076 | &mut self, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1077 | res: Step<Self::Input, Self::State, E>, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1078 | ) -> Step<Self::Output, Self::State, E> |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1079 | where |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1080 | E: Error, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1081 | { |
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
1082 | match self.base_iterator.poststep(res) { |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1083 | Step::Result(data, state) => Step::Result( |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1084 | Timed { cpu_time: self.start_time.elapsed(), iter: self.iteration(), data }, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1085 | state, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1086 | ), |
| 0 | 1087 | Step::Quiet => Step::Quiet, |
| 1088 | Step::Terminated => Step::Terminated, | |
|
3
20db884b7028
Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
1089 | Step::Failure(e) => Step::Failure(e), |
| 0 | 1090 | } |
| 1091 | } | |
| 1092 | ||
| 1093 | #[inline] | |
| 1094 | fn iteration(&self) -> usize { | |
| 1095 | self.base_iterator.iteration() | |
| 1096 | } | |
| 1097 | ||
| 1098 | #[inline] | |
| 1099 | fn state(&self) -> Self::State { | |
| 1100 | self.base_iterator.state() | |
| 1101 | } | |
| 1102 | } | |
| 1103 | ||
| 1104 | // | |
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
1105 | // New for-loop interface |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
1106 | // |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
1107 | |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1108 | pub struct AlgIteratorIterator<I: AlgIterator> { |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1109 | algi: Rc<RefCell<I>>, |
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
1110 | } |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
1111 | |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1112 | pub struct AlgIteratorIteration<I: AlgIterator> { |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1113 | state: I::State, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1114 | algi: Rc<RefCell<I>>, |
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
1115 | } |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
1116 | |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1117 | impl<I: AlgIterator> std::iter::Iterator for AlgIteratorIterator<I> { |
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
1118 | type Item = AlgIteratorIteration<I>; |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
1119 | |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
1120 | fn next(&mut self) -> Option<Self::Item> { |
|
41
121cf065e9ed
Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents:
40
diff
changeset
|
1121 | let algi = self.algi.clone(); |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1122 | RefCell::borrow_mut(&self.algi) |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1123 | .prestep() |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1124 | .map(|state| AlgIteratorIteration { state, algi }) |
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
1125 | } |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
1126 | } |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
1127 | |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
1128 | /// Types of errors that may occur |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1129 | #[derive(Debug, PartialEq, Eq)] |
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
1130 | pub enum IterationError { |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
1131 | /// [`AlgIteratorIteration::if_verbose_check`] is not called in iteration order. |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1132 | ReportingOrderingError, |
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
1133 | } |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
1134 | |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1135 | impl<I: AlgIterator> AlgIteratorIteration<I> { |
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
1136 | /// Call `call_objective` if this is a verbose iteration. |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
1137 | /// |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
1138 | /// Verbosity depends on the [`AlgIterator`] that produced this state. |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
1139 | /// |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
1140 | /// The closure `calc_objective` should return an arbitrary value of type `V`, to be inserted |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
1141 | /// into the log, or whatever is deemed by the [`AlgIterator`]. For usage instructions see the |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
1142 | /// [module documentation][self]. |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
1143 | /// |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
1144 | /// This function may panic if result reporting is not ordered correctly (an unlikely mistake |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
1145 | /// if using this facility correctly). For a version that propagates errors, see |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
1146 | /// [`Self::if_verbose_check`]. |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1147 | pub fn if_verbose(self, calc_objective: impl FnOnce() -> I::Input) { |
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
1148 | self.if_verbose_check(calc_objective).unwrap() |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
1149 | } |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
1150 | |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
1151 | /// Version of [`Self::if_verbose`] that propagates errors instead of panicking. |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1152 | pub fn if_verbose_check( |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1153 | self, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1154 | calc_objective: impl FnOnce() -> I::Input, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1155 | ) -> Result<(), IterationError> { |
|
41
121cf065e9ed
Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents:
40
diff
changeset
|
1156 | let mut algi = match RefCell::try_borrow_mut(&self.algi) { |
|
121cf065e9ed
Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents:
40
diff
changeset
|
1157 | Err(_) => return Err(IterationError::ReportingOrderingError), |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1158 | Ok(algi) => algi, |
|
41
121cf065e9ed
Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents:
40
diff
changeset
|
1159 | }; |
|
121cf065e9ed
Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents:
40
diff
changeset
|
1160 | if self.state.iteration() != algi.iteration() { |
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
1161 | Err(IterationError::ReportingOrderingError) |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
1162 | } else { |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1163 | let res: Step<I::Input, I::State, std::convert::Infallible> = |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1164 | self.state.if_verbose(calc_objective); |
|
41
121cf065e9ed
Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents:
40
diff
changeset
|
1165 | algi.poststep(res); |
|
40
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
1166 | Ok(()) |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
1167 | } |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
1168 | } |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
1169 | |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
1170 | /// Returns the current iteration count. |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
1171 | pub fn iteration(&self) -> usize { |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
1172 | self.state.iteration() |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
1173 | } |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
1174 | |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
1175 | /// Indicates whether the iterator is quiet |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
1176 | pub fn is_quiet(&self) -> bool { |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
1177 | self.state.is_quiet() |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
1178 | } |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
1179 | } |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
1180 | |
|
daf0e3a70c79
New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
38
diff
changeset
|
1181 | // |
| 0 | 1182 | // Tests |
| 1183 | // | |
| 1184 | ||
| 1185 | #[cfg(test)] | |
| 1186 | mod tests { | |
| 1187 | use super::*; | |
| 1188 | use crate::logger::Logger; | |
| 1189 | #[test] | |
| 1190 | fn iteration() { | |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1191 | let options = AlgIteratorOptions { |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1192 | max_iter: 10, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1193 | verbose_iter: Verbose::Every(3), |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1194 | ..Default::default() |
| 0 | 1195 | }; |
| 1196 | ||
| 1197 | { | |
| 1198 | let mut start = 1 as int; | |
| 1199 | options.iterate(|state| { | |
| 1200 | start = start * 2; | |
| 1201 | state.if_verbose(|| start) | |
| 1202 | }); | |
| 1203 | assert_eq!(start, (2 as int).pow(10)); | |
| 1204 | } | |
| 1205 | ||
| 1206 | { | |
| 1207 | let mut start = 1 as int; | |
| 1208 | let mut log = Logger::new(); | |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1209 | let factory = options |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1210 | .instantiate() |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1211 | .with_iteration_number() |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1212 | .into_log(&mut log); |
| 0 | 1213 | factory.iterate(|state| { |
| 1214 | start = start * 2; | |
| 1215 | state.if_verbose(|| start) | |
| 1216 | }); | |
| 1217 | assert_eq!(start, (2 as int).pow(10)); | |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1218 | assert_eq!( |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1219 | log.data() |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1220 | .iter() |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1221 | .map(|LogItem { data: v, iter: _ }| v.clone()) |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1222 | .collect::<Vec<int>>(), |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1223 | (1..10) |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1224 | .map(|i| (2 as int).pow(i)) |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1225 | .skip(2) |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1226 | .step_by(3) |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1227 | .collect::<Vec<int>>() |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1228 | ) |
| 0 | 1229 | } |
| 1230 | } | |
|
41
121cf065e9ed
Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents:
40
diff
changeset
|
1231 | |
|
121cf065e9ed
Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents:
40
diff
changeset
|
1232 | #[test] |
|
121cf065e9ed
Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents:
40
diff
changeset
|
1233 | fn iteration_for_loop() { |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1234 | let options = AlgIteratorOptions { |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1235 | max_iter: 10, |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1236 | verbose_iter: Verbose::Every(3), |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1237 | ..Default::default() |
|
41
121cf065e9ed
Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents:
40
diff
changeset
|
1238 | }; |
|
121cf065e9ed
Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents:
40
diff
changeset
|
1239 | |
|
121cf065e9ed
Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents:
40
diff
changeset
|
1240 | { |
|
121cf065e9ed
Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents:
40
diff
changeset
|
1241 | let mut start = 1 as int; |
|
121cf065e9ed
Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents:
40
diff
changeset
|
1242 | for state in options.iter() { |
|
121cf065e9ed
Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents:
40
diff
changeset
|
1243 | start = start * 2; |
|
121cf065e9ed
Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents:
40
diff
changeset
|
1244 | state.if_verbose(|| start) |
|
121cf065e9ed
Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents:
40
diff
changeset
|
1245 | } |
|
121cf065e9ed
Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents:
40
diff
changeset
|
1246 | assert_eq!(start, (2 as int).pow(10)); |
|
121cf065e9ed
Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents:
40
diff
changeset
|
1247 | } |
|
121cf065e9ed
Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents:
40
diff
changeset
|
1248 | |
|
121cf065e9ed
Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents:
40
diff
changeset
|
1249 | { |
|
121cf065e9ed
Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents:
40
diff
changeset
|
1250 | let mut start = 1 as int; |
|
121cf065e9ed
Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents:
40
diff
changeset
|
1251 | let mut log = Logger::new(); |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1252 | let factory = options |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1253 | .instantiate() |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1254 | .with_iteration_number() |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1255 | .into_log(&mut log); |
|
41
121cf065e9ed
Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents:
40
diff
changeset
|
1256 | for state in factory.iter() { |
|
121cf065e9ed
Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents:
40
diff
changeset
|
1257 | start = start * 2; |
|
121cf065e9ed
Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents:
40
diff
changeset
|
1258 | state.if_verbose(|| start) |
|
121cf065e9ed
Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents:
40
diff
changeset
|
1259 | } |
|
121cf065e9ed
Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents:
40
diff
changeset
|
1260 | assert_eq!(start, (2 as int).pow(10)); |
|
197
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1261 | assert_eq!( |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1262 | log.data() |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1263 | .iter() |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1264 | .map(|LogItem { data: v, iter: _ }| v.clone()) |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1265 | .collect::<Vec<int>>(), |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1266 | (1..10) |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1267 | .map(|i| (2 as int).pow(i)) |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1268 | .skip(2) |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1269 | .step_by(3) |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1270 | .collect::<Vec<int>>() |
|
1f301affeae3
Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents:
87
diff
changeset
|
1271 | ) |
|
41
121cf065e9ed
Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents:
40
diff
changeset
|
1272 | } |
|
121cf065e9ed
Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents:
40
diff
changeset
|
1273 | } |
| 0 | 1274 | } |