| 54 90/100 J=2029.497673 |
54 90/100 J=2029.497673 |
| 55 100/100 J=2502.377071 |
55 100/100 J=2502.377071 |
| 56 ``` |
56 ``` |
| 57 */ |
57 */ |
| 58 |
58 |
| 59 use colored::{Colorize, ColoredString}; |
59 use crate::logger::*; |
| |
60 use crate::types::*; |
| |
61 use colored::{ColoredString, Colorize}; |
| 60 use core::fmt::Debug; |
62 use core::fmt::Debug; |
| 61 use serde::{Serialize, Deserialize}; |
|
| 62 use cpu_time::ProcessTime; |
63 use cpu_time::ProcessTime; |
| |
64 use serde::{Deserialize, Serialize}; |
| |
65 use std::cell::RefCell; |
| |
66 use std::error::Error; |
| 63 use std::marker::PhantomData; |
67 use std::marker::PhantomData; |
| |
68 use std::rc::Rc; |
| 64 use std::time::Duration; |
69 use std::time::Duration; |
| 65 use std::error::Error; |
|
| 66 use std::cell::RefCell; |
|
| 67 use std::rc::Rc; |
|
| 68 use crate::types::*; |
|
| 69 use crate::logger::*; |
|
| 70 |
70 |
| 71 /// Create the displayed presentation for log items. |
71 /// Create the displayed presentation for log items. |
| 72 pub trait LogRepr : Debug { |
72 pub trait LogRepr: Debug { |
| 73 fn logrepr(&self) -> ColoredString { format!("« {self:?} »").as_str().into() } |
73 fn logrepr(&self) -> ColoredString { |
| |
74 format!("« {self:?} »").as_str().into() |
| |
75 } |
| 74 } |
76 } |
| 75 |
77 |
| 76 impl LogRepr for str { |
78 impl LogRepr for str { |
| 77 fn logrepr(&self) -> ColoredString { self.into() } |
79 fn logrepr(&self) -> ColoredString { |
| |
80 self.into() |
| |
81 } |
| 78 } |
82 } |
| 79 |
83 |
| 80 impl LogRepr for String { |
84 impl LogRepr for String { |
| 81 fn logrepr(&self) -> ColoredString { self.as_str().into() } |
85 fn logrepr(&self) -> ColoredString { |
| 82 } |
86 self.as_str().into() |
| 83 |
87 } |
| 84 impl<T> LogRepr for T where T : Num { |
88 } |
| 85 fn logrepr(&self) -> ColoredString { format!("J={self}").as_str().into() } |
89 |
| 86 } |
90 impl<T> LogRepr for T |
| 87 |
91 where |
| 88 impl<V> LogRepr for Option<V> where V : LogRepr { |
92 T: Num, |
| |
93 { |
| |
94 fn logrepr(&self) -> ColoredString { |
| |
95 format!("J={self}").as_str().into() |
| |
96 } |
| |
97 } |
| |
98 |
| |
99 impl<V> LogRepr for Option<V> |
| |
100 where |
| |
101 V: LogRepr, |
| |
102 { |
| 89 fn logrepr(&self) -> ColoredString { |
103 fn logrepr(&self) -> ColoredString { |
| 90 match self { |
104 match self { |
| 91 None => { "===missing value===".red() } |
105 None => "===missing value===".red(), |
| 92 Some(v) => { v.logrepr() } |
106 Some(v) => v.logrepr(), |
| 93 } |
107 } |
| 94 } |
108 } |
| 95 } |
109 } |
| 96 |
110 |
| 97 /// Helper struct for returning results annotated with an additional string to |
111 /// Helper struct for returning results annotated with an additional string to |
| 98 /// [`if_verbose`][AlgIteratorState::if_verbose]. The [`LogRepr`] implementation will |
112 /// [`if_verbose`][AlgIteratorState::if_verbose]. The [`LogRepr`] implementation will |
| 99 /// display that string when so decided by the specific [`AlgIterator`] in use. |
113 /// display that string when so decided by the specific [`AlgIterator`] in use. |
| 100 #[derive(Debug,Clone)] |
114 #[derive(Debug, Clone)] |
| 101 pub struct Annotated<F>(pub F, pub String); |
115 pub struct Annotated<F>(pub F, pub String); |
| 102 |
116 |
| 103 impl<V> LogRepr for Annotated<V> where V : LogRepr { |
117 impl<V> LogRepr for Annotated<V> |
| |
118 where |
| |
119 V: LogRepr, |
| |
120 { |
| 104 fn logrepr(&self) -> ColoredString { |
121 fn logrepr(&self) -> ColoredString { |
| 105 format!("{}\t| {}", self.0.logrepr(), self.1).as_str().into() |
122 format!("{}\t| {}", self.0.logrepr(), self.1) |
| 106 } |
123 .as_str() |
| 107 } |
124 .into() |
| 108 |
125 } |
| |
126 } |
| 109 |
127 |
| 110 /// Basic log item. |
128 /// Basic log item. |
| 111 #[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)] |
129 #[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)] |
| 112 pub struct LogItem<V> { |
130 pub struct LogItem<V> { |
| 113 pub iter : usize, |
131 pub iter: usize, |
| 114 // This causes [`csv`] to crash. |
132 // This causes [`csv`] to crash. |
| 115 //#[serde(flatten)] |
133 //#[serde(flatten)] |
| 116 pub data : V |
134 pub data: V, |
| 117 } |
135 } |
| 118 |
136 |
| 119 impl<V> LogItem<V> { |
137 impl<V> LogItem<V> { |
| 120 /// Creates a new log item |
138 /// Creates a new log item |
| 121 fn new(iter : usize, data : V) -> Self { |
139 fn new(iter: usize, data: V) -> Self { |
| 122 LogItem{ iter, data } |
140 LogItem { iter, data } |
| 123 } |
141 } |
| 124 } |
142 } |
| 125 |
143 |
| 126 /// State of an [`AlgIterator`]. |
144 /// State of an [`AlgIterator`]. |
| 127 /// |
145 /// |
| 128 /// This is the parameter obtained by the closure passed to [`AlgIterator::iterate`] or |
146 /// This is the parameter obtained by the closure passed to [`AlgIterator::iterate`] or |
| 129 /// [`AlgIteratorFactory::iterate`]. |
147 /// [`AlgIteratorFactory::iterate`]. |
| 130 pub trait AlgIteratorState : Sized { |
148 pub trait AlgIteratorState: Sized { |
| 131 /// Call `call_objective` if this is a verbose iteration. |
149 /// Call `call_objective` if this is a verbose iteration. |
| 132 /// |
150 /// |
| 133 /// Verbosity depends on the [`AlgIterator`] that produced this state. |
151 /// Verbosity depends on the [`AlgIterator`] that produced this state. |
| 134 /// |
152 /// |
| 135 /// The closure `calc_objective` should return an arbitrary value of type `V`, to be inserted |
153 /// The closure `calc_objective` should return an arbitrary value of type `V`, to be inserted |
| 136 /// into the log, or whatever is deemed by the [`AlgIterator`]. For usage instructions see the |
154 /// into the log, or whatever is deemed by the [`AlgIterator`]. For usage instructions see the |
| 137 /// [module documentation][self]. |
155 /// [module documentation][self]. |
| 138 fn if_verbose<V, E : Error>(self, calc_objective : impl FnOnce() -> V) -> Step<V, Self, E>; |
156 fn if_verbose<V, E: Error>(self, calc_objective: impl FnOnce() -> V) -> Step<V, Self, E>; |
| 139 |
157 |
| 140 /// Returns the current iteration count. |
158 /// Returns the current iteration count. |
| 141 fn iteration(&self) -> usize; |
159 fn iteration(&self) -> usize; |
| 142 |
160 |
| 143 /// Indicates whether the iterator is quiet |
161 /// Indicates whether the iterator is quiet |
| 144 fn is_quiet(&self) -> bool; |
162 fn is_quiet(&self) -> bool; |
| 145 } |
163 } |
| 146 |
164 |
| 147 /// Result of a step of an [`AlgIterator`] |
165 /// Result of a step of an [`AlgIterator`] |
| 148 #[derive(Debug, Serialize)] |
166 #[derive(Debug, Serialize)] |
| 149 pub enum Step<V, S, Fail : Error = std::convert::Infallible> { |
167 pub enum Step<V, S, Fail: Error = std::convert::Infallible> { |
| 150 /// Iteration should be terminated |
168 /// Iteration should be terminated |
| 151 Terminated, |
169 Terminated, |
| 152 /// Iteration should be terminated due to failure |
170 /// Iteration should be terminated due to failure |
| 153 Failure(Fail), |
171 Failure(Fail), |
| 154 /// No result this iteration (due to verbosity settings) |
172 /// No result this iteration (due to verbosity settings) |
| 155 Quiet, |
173 Quiet, |
| 156 /// Result of this iteration (due to verbosity settings) |
174 /// Result of this iteration (due to verbosity settings) |
| 157 Result(V, S), |
175 Result(V, S), |
| 158 } |
176 } |
| 159 |
177 |
| 160 impl<V, S, E : Error> Step<V, S, E> { |
178 impl<V, S, E: Error> Step<V, S, E> { |
| 161 /// Maps the value contained within the `Step`, if any, by the closure `f`. |
179 /// Maps the value contained within the `Step`, if any, by the closure `f`. |
| 162 pub fn map<U>(self, mut f : impl FnMut(V) -> U) -> Step<U, S, E> { |
180 pub fn map<U>(self, mut f: impl FnMut(V) -> U) -> Step<U, S, E> { |
| 163 match self { |
181 match self { |
| 164 Step::Result(v, s) => Step::Result(f(v), s), |
182 Step::Result(v, s) => Step::Result(f(v), s), |
| 165 Step::Failure(e) => Step::Failure(e), |
183 Step::Failure(e) => Step::Failure(e), |
| 166 Step::Quiet => Step::Quiet, |
184 Step::Quiet => Step::Quiet, |
| 167 Step::Terminated => Step::Terminated, |
185 Step::Terminated => Step::Terminated, |
| 168 } |
186 } |
| 169 } |
187 } |
| 170 } |
188 } |
| 171 |
189 |
| 172 impl<V, S, E : Error> Default for Step<V, S, E> { |
190 impl<V, S, E: Error> Default for Step<V, S, E> { |
| 173 fn default() -> Self { |
191 fn default() -> Self { |
| 174 Step::Quiet |
192 Step::Quiet |
| 175 } |
193 } |
| 176 } |
194 } |
| 177 |
195 |
| 178 /// An iterator for algorithms, produced by [`AlgIteratorFactory::prepare`]. |
196 /// An iterator for algorithms, produced by [`AlgIteratorFactory::prepare`]. |
| 179 /// |
197 /// |
| 180 /// Typically not accessed directly, but transparently produced by an [`AlgIteratorFactory`]. |
198 /// Typically not accessed directly, but transparently produced by an [`AlgIteratorFactory`]. |
| 181 /// Every [`AlgIteratorFactory`] has to implement a corresponding `AlgIterator`. |
199 /// Every [`AlgIteratorFactory`] has to implement a corresponding `AlgIterator`. |
| 182 pub trait AlgIterator : Sized { |
200 pub trait AlgIterator: Sized { |
| 183 /// The state type |
201 /// The state type |
| 184 type State : AlgIteratorState; |
202 type State: AlgIteratorState; |
| 185 /// The output type for [`Self::poststep`] and [`Self::step`]. |
203 /// The output type for [`Self::poststep`] and [`Self::step`]. |
| 186 type Output; |
204 type Output; |
| 187 /// The input type for [`Self::poststep`]. |
205 /// The input type for [`Self::poststep`]. |
| 188 type Input; |
206 type Input; |
| 189 |
207 |
| 190 /// Advance the iterator, performing `step_fn` with the state |
208 /// Advance the iterator, performing `step_fn` with the state |
| 191 fn step<F, E>(&mut self, step_fn : &mut F) -> Step<Self::Output, Self::State, E> |
209 fn step<F, E>(&mut self, step_fn: &mut F) -> Step<Self::Output, Self::State, E> |
| 192 where F : FnMut(Self::State) -> Step<Self::Input, Self::State, E>, |
210 where |
| 193 E : Error { |
211 F: FnMut(Self::State) -> Step<Self::Input, Self::State, E>, |
| 194 self.prestep().map_or(Step::Terminated, |
212 E: Error, |
| 195 |state| self.poststep(step_fn(state))) |
213 { |
| |
214 self.prestep() |
| |
215 .map_or(Step::Terminated, |state| self.poststep(step_fn(state))) |
| 196 } |
216 } |
| 197 |
217 |
| 198 /// Initial stage of advancing the iterator, before the actual step |
218 /// Initial stage of advancing the iterator, before the actual step |
| 199 fn prestep(&mut self) -> Option<Self::State>; |
219 fn prestep(&mut self) -> Option<Self::State>; |
| 200 |
220 |
| 201 /// Handle step result |
221 /// Handle step result |
| 202 fn poststep<E>(&mut self, result : Step<Self::Input, Self::State, E>) |
222 fn poststep<E>( |
| 203 -> Step<Self::Output, Self::State, E> |
223 &mut self, |
| 204 where E : Error; |
224 result: Step<Self::Input, Self::State, E>, |
| |
225 ) -> Step<Self::Output, Self::State, E> |
| |
226 where |
| |
227 E: Error; |
| 205 |
228 |
| 206 /// Return current iteration count. |
229 /// Return current iteration count. |
| 207 fn iteration(&self) -> usize { |
230 fn iteration(&self) -> usize { |
| 208 self.state().iteration() |
231 self.state().iteration() |
| 209 } |
232 } |
| 211 /// Return current state. |
234 /// Return current state. |
| 212 fn state(&self) -> Self::State; |
235 fn state(&self) -> Self::State; |
| 213 |
236 |
| 214 /// Iterate the `AlgIterator` until termination, erforming `step_fn` on each step. |
237 /// Iterate the `AlgIterator` until termination, erforming `step_fn` on each step. |
| 215 /// |
238 /// |
| 216 /// Returns either `()` or an error if the step closure terminated in [`Step::Failure´]. |
239 /// Returns either `()` or an error if the step closure terminated in [`Step::Failure`]. |
| 217 #[inline] |
240 #[inline] |
| 218 fn iterate<F, E>(&mut self, mut step_fn : F) -> Result<(), E> |
241 fn iterate<F, E>(&mut self, mut step_fn: F) -> Result<(), E> |
| 219 where F : FnMut(Self::State) -> Step<Self::Input, Self::State, E>, |
242 where |
| 220 E : Error { |
243 F: FnMut(Self::State) -> Step<Self::Input, Self::State, E>, |
| |
244 E: Error, |
| |
245 { |
| 221 loop { |
246 loop { |
| 222 match self.step(&mut step_fn) { |
247 match self.step(&mut step_fn) { |
| 223 Step::Terminated => return Ok(()), |
248 Step::Terminated => return Ok(()), |
| 224 Step::Failure(e) => return Err(e), |
249 Step::Failure(e) => return Err(e), |
| 225 _ => {}, |
250 _ => {} |
| 226 } |
251 } |
| 227 } |
252 } |
| 228 } |
253 } |
| 229 } |
254 } |
| 230 |
255 |
| 231 /// A factory for producing an [`AlgIterator`]. |
256 /// A factory for producing an [`AlgIterator`]. |
| 232 /// |
257 /// |
| 233 /// For usage instructions see the [module documentation][self]. |
258 /// For usage instructions see the [module documentation][self]. |
| 234 pub trait AlgIteratorFactory<V> : Sized { |
259 pub trait AlgIteratorFactory<V>: Sized { |
| 235 type Iter : AlgIterator<State = Self::State, Input = V, Output = Self::Output>; |
260 type Iter: AlgIterator<State = Self::State, Input = V, Output = Self::Output>; |
| 236 |
261 |
| 237 /// The state type of the corresponding [`AlgIterator`]. |
262 /// The state type of the corresponding [`AlgIterator`]. |
| 238 /// A reference to this is passed to the closures passed to methods such as [`Self::iterate`]. |
263 /// A reference to this is passed to the closures passed to methods such as [`Self::iterate`]. |
| 239 type State : AlgIteratorState; |
264 type State: AlgIteratorState; |
| 240 /// The output type of the corresponding [`AlgIterator`]. |
265 /// The output type of the corresponding [`AlgIterator`]. |
| 241 /// This is the output of the closures passed to methods such as [`Self::iterate`] after |
266 /// This is the output of the closures passed to methods such as [`Self::iterate`] after |
| 242 /// mappings performed by each [`AlgIterator`] implementation. |
267 /// mappings performed by each [`AlgIterator`] implementation. |
| 243 type Output; |
268 type Output; |
| 244 |
269 |
| 343 /// // calculate and return function value or other displayed data v |
378 /// // calculate and return function value or other displayed data v |
| 344 /// return 0 |
379 /// return 0 |
| 345 /// }) |
380 /// }) |
| 346 /// }) |
381 /// }) |
| 347 /// ``` |
382 /// ``` |
| 348 fn into_log<'log>(self, logger : &'log mut Logger<Self::Output>) |
383 fn into_log<'log>( |
| 349 -> LoggingIteratorFactory<'log, Self::Output, Self> |
384 self, |
| 350 where Self : Sized { |
385 logger: &'log mut Logger<Self::Output>, |
| 351 LoggingIteratorFactory { |
386 ) -> LoggingIteratorFactory<'log, Self::Output, Self> |
| 352 base_options : self, |
387 where |
| 353 logger, |
388 Self: Sized, |
| 354 } |
389 { |
| |
390 LoggingIteratorFactory { base_options: self, logger } |
| 355 } |
391 } |
| 356 |
392 |
| 357 /// Map the output of the iterator produced by the factory. |
393 /// Map the output of the iterator produced by the factory. |
| 358 /// |
394 /// |
| 359 /// Returns a new factory. |
395 /// Returns a new factory. |
| 360 fn mapped<U, G>(self, map : G) |
396 fn mapped<U, G>(self, map: G) -> MappingIteratorFactory<G, Self> |
| 361 -> MappingIteratorFactory<G, Self> |
397 where |
| 362 where Self : Sized, |
398 Self: Sized, |
| 363 G : Fn(usize, Self::Output) -> U { |
399 G: Fn(usize, Self::Output) -> U, |
| 364 MappingIteratorFactory { |
400 { |
| 365 base_options : self, |
401 MappingIteratorFactory { base_options: self, map } |
| 366 map |
|
| 367 } |
|
| 368 } |
402 } |
| 369 |
403 |
| 370 /// Adds iteration number to the output. |
404 /// Adds iteration number to the output. |
| 371 /// |
405 /// |
| 372 /// Returns a new factory. |
406 /// Returns a new factory. |
| 373 /// Typically followed by [`Self::into_log`]. |
407 /// Typically followed by [`Self::into_log`]. |
| 374 fn with_iteration_number(self) |
408 fn with_iteration_number( |
| 375 -> MappingIteratorFactory<fn(usize, Self::Output) -> LogItem<Self::Output>, Self> |
409 self, |
| 376 where Self : Sized { |
410 ) -> MappingIteratorFactory<fn(usize, Self::Output) -> LogItem<Self::Output>, Self> |
| |
411 where |
| |
412 Self: Sized, |
| |
413 { |
| 377 self.mapped(LogItem::new) |
414 self.mapped(LogItem::new) |
| 378 } |
415 } |
| 379 |
416 |
| 380 /// Add timing to the iterator produced by the factory. |
417 /// Add timing to the iterator produced by the factory. |
| 381 fn timed(self) -> TimingIteratorFactory<Self> |
418 fn timed(self) -> TimingIteratorFactory<Self> |
| 382 where Self : Sized { |
419 where |
| |
420 Self: Sized, |
| |
421 { |
| 383 TimingIteratorFactory(self) |
422 TimingIteratorFactory(self) |
| 384 } |
423 } |
| 385 |
424 |
| 386 /// Add value stopping threshold to the iterator produce by the factory |
425 /// Add value stopping threshold to the iterator produce by the factory |
| 387 fn stop_target(self, target : Self::Output) -> ValueIteratorFactory<Self::Output, Self> |
426 fn stop_target(self, target: Self::Output) -> ValueIteratorFactory<Self::Output, Self> |
| 388 where Self : Sized, |
427 where |
| 389 Self::Output : Num { |
428 Self: Sized, |
| 390 ValueIteratorFactory { base_options : self, target : target } |
429 Self::Output: Num, |
| |
430 { |
| |
431 ValueIteratorFactory { base_options: self, target: target } |
| 391 } |
432 } |
| 392 |
433 |
| 393 /// Add stall stopping to the iterator produce by the factory |
434 /// Add stall stopping to the iterator produce by the factory |
| 394 fn stop_stall(self, stall : Self::Output) -> StallIteratorFactory<Self::Output, Self> |
435 fn stop_stall(self, stall: Self::Output) -> StallIteratorFactory<Self::Output, Self> |
| 395 where Self : Sized, |
436 where |
| 396 Self::Output : Num { |
437 Self: Sized, |
| 397 StallIteratorFactory { base_options : self, stall : stall } |
438 Self::Output: Num, |
| |
439 { |
| |
440 StallIteratorFactory { base_options: self, stall: stall } |
| 398 } |
441 } |
| 399 |
442 |
| 400 /// Is the iterator quiet, i.e., on-verbose? |
443 /// Is the iterator quiet, i.e., on-verbose? |
| 401 fn is_quiet(&self) -> bool { false } |
444 fn is_quiet(&self) -> bool { |
| |
445 false |
| |
446 } |
| 402 |
447 |
| 403 /// Returns an an [`std::iter::Iterator`] that can be used in a `for`-loop. |
448 /// Returns an an [`std::iter::Iterator`] that can be used in a `for`-loop. |
| 404 fn iter(self) -> AlgIteratorIterator<Self::Iter> { |
449 fn iter(self) -> AlgIteratorIterator<Self::Iter> { |
| 405 AlgIteratorIterator { |
450 AlgIteratorIterator { algi: Rc::new(RefCell::new(self.prepare())) } |
| 406 algi : Rc::new(RefCell::new(self.prepare())), |
|
| 407 } |
|
| 408 } |
451 } |
| 409 |
452 |
| 410 /// Returns an an [`std::iter::Iterator`] that can be used in a `for`-loop, |
453 /// Returns an an [`std::iter::Iterator`] that can be used in a `for`-loop, |
| 411 /// also inputting an initial iteration status calculated by `f` if needed. |
454 /// also inputting an initial iteration status calculated by `f` if needed. |
| 412 fn iter_init(self, f : impl FnOnce() -> <Self::Iter as AlgIterator>::Input) |
455 fn iter_init( |
| 413 -> AlgIteratorIterator<Self::Iter> { |
456 self, |
| |
457 f: impl FnOnce() -> <Self::Iter as AlgIterator>::Input, |
| |
458 ) -> AlgIteratorIterator<Self::Iter> { |
| 414 let mut i = self.prepare(); |
459 let mut i = self.prepare(); |
| 415 let st = i.state(); |
460 let st = i.state(); |
| 416 let step : Step<<Self::Iter as AlgIterator>::Input, Self::State> = st.if_verbose(f); |
461 let step: Step<<Self::Iter as AlgIterator>::Input, Self::State> = st.if_verbose(f); |
| 417 i.poststep(step); |
462 i.poststep(step); |
| 418 AlgIteratorIterator { |
463 AlgIteratorIterator { algi: Rc::new(RefCell::new(i)) } |
| 419 algi : Rc::new(RefCell::new(i)), |
|
| 420 } |
|
| 421 } |
464 } |
| 422 } |
465 } |
| 423 |
466 |
| 424 /// Options for [`BasicAlgIteratorFactory`]. |
467 /// Options for [`BasicAlgIteratorFactory`]. |
| 425 /// |
468 /// |
| 429 /// let iter = AlgIteratorOptions{ max_iter : 10000, .. Default::default() }; |
472 /// let iter = AlgIteratorOptions{ max_iter : 10000, .. Default::default() }; |
| 430 /// ``` |
473 /// ``` |
| 431 #[derive(Clone, Copy, Debug, Serialize, Deserialize, Eq, PartialEq)] |
474 #[derive(Clone, Copy, Debug, Serialize, Deserialize, Eq, PartialEq)] |
| 432 pub struct AlgIteratorOptions { |
475 pub struct AlgIteratorOptions { |
| 433 /// Maximum number of iterations |
476 /// Maximum number of iterations |
| 434 pub max_iter : usize, |
477 pub max_iter: usize, |
| 435 /// Number of iterations between verbose iterations that display state. |
478 /// Number of iterations between verbose iterations that display state. |
| 436 pub verbose_iter : Verbose, |
479 pub verbose_iter: Verbose, |
| 437 /// Whether verbose iterations are displayed, or just passed onwards to a containing |
480 /// Whether verbose iterations are displayed, or just passed onwards to a containing |
| 438 /// `AlgIterator`. |
481 /// `AlgIterator`. |
| 439 pub quiet : bool, |
482 pub quiet: bool, |
| 440 } |
483 } |
| 441 |
484 |
| 442 #[derive(Clone, Copy, Debug, Serialize, Deserialize, Eq, PartialEq)] |
485 #[derive(Clone, Copy, Debug, Serialize, Deserialize, Eq, PartialEq)] |
| 443 pub enum Verbose { |
486 pub enum Verbose { |
| 444 /// Be verbose every $n$ iterations. |
487 /// Be verbose every $n$ iterations. |
| 445 Every(usize), |
488 Every(usize), |
| 446 /// Be verbose every $n$ iterations and initial $m$ iterations. |
489 /// Be verbose every $n$ iterations and initial $m$ iterations. |
| 447 EveryAndInitial{ every : usize, initial : usize }, |
490 EveryAndInitial { every: usize, initial: usize }, |
| 448 /// Be verbose if iteration number $n$ divides by $b^{\text{floor}(\log_b(n))}$, where |
491 /// Be verbose if iteration number $n$ divides by $b^{\text{floor}(\log_b(n))}$, where |
| 449 /// $b$ is indicated logarithmic base. So, with $b=10$, |
492 /// $b$ is indicated logarithmic base. So, with $b=10$, |
| 450 /// * every iteration for first 10 iterations, |
493 /// * every iteration for first 10 iterations, |
| 451 /// * every 10 iterations from there on until 100 iterations, |
494 /// * every 10 iterations from there on until 100 iterations, |
| 452 /// * every 100 iteartinos frmo there on until 1000 iterations, etc. |
495 /// * every 100 iteartinos frmo there on until 1000 iterations, etc. |
| 453 Logarithmic(usize), |
496 Logarithmic(usize), |
| 454 /// Same as `Logarithmic`, but $\log_b(n)$ is replaced by $min\{c, \log_b(n)\}$ where $c$ |
497 /// Same as `Logarithmic`, but $\log_b(n)$ is replaced by $min\{c, \log_b(n)\}$ where $c$ |
| 455 /// is the given `cap`. For example, with `base=10` and `cap=2`, the first ten iterations |
498 /// is the given `cap`. For example, with `base=10` and `cap=2`, the first ten iterations |
| 456 /// will be output, then every tenth iteration, and after 100 iterations, every 100th iteration, |
499 /// will be output, then every tenth iteration, and after 100 iterations, every 100th iteration, |
| 457 /// without further logarithmic progression. |
500 /// without further logarithmic progression. |
| 458 LogarithmicCap{ base : usize, cap : u32 }, |
501 LogarithmicCap { base: usize, cap: u32 }, |
| 459 } |
502 } |
| 460 |
503 |
| 461 impl Verbose { |
504 impl Verbose { |
| 462 /// Indicates whether given iteration number is verbose |
505 /// Indicates whether given iteration number is verbose |
| 463 pub fn is_verbose(&self, iter : usize) -> bool { |
506 pub fn is_verbose(&self, iter: usize) -> bool { |
| 464 match self { |
507 match self { |
| 465 &Verbose::Every(every) => { |
508 &Verbose::Every(every) => every != 0 && iter % every == 0, |
| 466 every != 0 && iter % every == 0 |
509 &Verbose::EveryAndInitial { every, initial } => { |
| 467 }, |
|
| 468 &Verbose::EveryAndInitial{ every, initial } => { |
|
| 469 iter <= initial || (every != 0 && iter % every == 0) |
510 iter <= initial || (every != 0 && iter % every == 0) |
| 470 }, |
511 } |
| 471 &Verbose::Logarithmic(base) => { |
512 &Verbose::Logarithmic(base) => { |
| 472 let every = base.pow((iter as float).log(base as float).floor() as u32); |
513 let every = base.pow((iter as float).log(base as float).floor() as u32); |
| 473 iter % every == 0 |
514 iter % every == 0 |
| 474 } |
515 } |
| 475 &Verbose::LogarithmicCap{base, cap} => { |
516 &Verbose::LogarithmicCap { base, cap } => { |
| 476 let every = base.pow(((iter as float).log(base as float).floor() as u32).min(cap)); |
517 let every = base.pow(((iter as float).log(base as float).floor() as u32).min(cap)); |
| 477 iter % every == 0 |
518 iter % every == 0 |
| 478 } |
519 } |
| 479 } |
520 } |
| 480 } |
521 } |
| 481 } |
522 } |
| 482 |
523 |
| 483 impl Default for AlgIteratorOptions { |
524 impl Default for AlgIteratorOptions { |
| 484 fn default() -> AlgIteratorOptions { |
525 fn default() -> AlgIteratorOptions { |
| 485 AlgIteratorOptions{ |
526 AlgIteratorOptions { |
| 486 max_iter : 1000, |
527 max_iter: 1000, |
| 487 verbose_iter : Verbose::EveryAndInitial { every : 100, initial : 10 }, |
528 verbose_iter: Verbose::EveryAndInitial { every: 100, initial: 10 }, |
| 488 quiet : false |
529 quiet: false, |
| 489 } |
530 } |
| 490 } |
531 } |
| 491 } |
532 } |
| 492 |
533 |
| 493 /// State of a `BasicAlgIterator` |
534 /// State of a `BasicAlgIterator` |
| 494 #[derive(Clone,Copy,Debug,Serialize,Eq,PartialEq)] |
535 #[derive(Clone, Copy, Debug, Serialize, Eq, PartialEq)] |
| 495 pub struct BasicState { |
536 pub struct BasicState { |
| 496 /// Current iteration |
537 /// Current iteration |
| 497 iter : usize, |
538 iter: usize, |
| 498 /// Whether the iteration is verbose, i.e., results should be displayed. |
539 /// Whether the iteration is verbose, i.e., results should be displayed. |
| 499 /// Requires `calc` to be `true`. |
540 /// Requires `calc` to be `true`. |
| 500 verbose : bool, |
541 verbose: bool, |
| 501 /// Whether results should be calculated. |
542 /// Whether results should be calculated. |
| 502 calc : bool, |
543 calc: bool, |
| 503 /// Indicates whether the iteration is quiet |
544 /// Indicates whether the iteration is quiet |
| 504 quiet : bool, |
545 quiet: bool, |
| 505 } |
546 } |
| 506 |
547 |
| 507 /// [`AlgIteratorFactory`] for [`BasicAlgIterator`] |
548 /// [`AlgIteratorFactory`] for [`BasicAlgIterator`] |
| 508 #[derive(Clone,Debug)] |
549 #[derive(Clone, Debug)] |
| 509 pub struct BasicAlgIteratorFactory<V> { |
550 pub struct BasicAlgIteratorFactory<V> { |
| 510 options : AlgIteratorOptions, |
551 options: AlgIteratorOptions, |
| 511 _phantoms : PhantomData<V>, |
552 _phantoms: PhantomData<V>, |
| 512 } |
553 } |
| 513 |
554 |
| 514 /// The simplest [`AlgIterator`], created by [`BasicAlgIteratorFactory`] |
555 /// The simplest [`AlgIterator`], created by [`BasicAlgIteratorFactory`] |
| 515 #[derive(Clone,Debug)] |
556 #[derive(Clone, Debug)] |
| 516 pub struct BasicAlgIterator<V> { |
557 pub struct BasicAlgIterator<V> { |
| 517 options : AlgIteratorOptions, |
558 options: AlgIteratorOptions, |
| 518 iter : usize, |
559 iter: usize, |
| 519 _phantoms : PhantomData<V>, |
560 _phantoms: PhantomData<V>, |
| 520 } |
561 } |
| 521 |
562 |
| 522 impl AlgIteratorOptions { |
563 impl AlgIteratorOptions { |
| 523 /// [`AlgIteratorOptions`] is directly a factory for [`BasicAlgIterator`], |
564 /// [`AlgIteratorOptions`] is directly a factory for [`BasicAlgIterator`], |
| 524 /// however, due to type inference issues, it may become convenient to instantiate |
565 /// however, due to type inference issues, it may become convenient to instantiate |
| 525 /// it to a specific return type for the inner step function. This method does that. |
566 /// it to a specific return type for the inner step function. This method does that. |
| 526 pub fn instantiate<V>(&self) -> BasicAlgIteratorFactory<V> { |
567 pub fn instantiate<V>(&self) -> BasicAlgIteratorFactory<V> { |
| 527 BasicAlgIteratorFactory { |
568 BasicAlgIteratorFactory { options: self.clone(), _phantoms: PhantomData } |
| 528 options : self.clone(), |
|
| 529 _phantoms : PhantomData |
|
| 530 } |
|
| 531 } |
569 } |
| 532 } |
570 } |
| 533 |
571 |
| 534 impl<V> AlgIteratorFactory<V> for AlgIteratorOptions |
572 impl<V> AlgIteratorFactory<V> for AlgIteratorOptions |
| 535 where V : LogRepr { |
573 where |
| |
574 V: LogRepr, |
| |
575 { |
| 536 type State = BasicState; |
576 type State = BasicState; |
| 537 type Iter = BasicAlgIterator<V>; |
577 type Iter = BasicAlgIterator<V>; |
| 538 type Output = V; |
578 type Output = V; |
| 539 |
579 |
| 540 fn prepare(self) -> Self::Iter { |
580 fn prepare(self) -> Self::Iter { |
| 541 BasicAlgIterator{ |
581 BasicAlgIterator { options: self, iter: 0, _phantoms: PhantomData } |
| 542 options : self, |
|
| 543 iter : 0, |
|
| 544 _phantoms : PhantomData, |
|
| 545 } |
|
| 546 } |
582 } |
| 547 |
583 |
| 548 #[inline] |
584 #[inline] |
| 549 fn is_quiet(&self) -> bool { |
585 fn is_quiet(&self) -> bool { |
| 550 self.quiet |
586 self.quiet |
| 551 } |
587 } |
| 552 } |
588 } |
| 553 |
589 |
| 554 impl<V> AlgIteratorFactory<V> for BasicAlgIteratorFactory<V> |
590 impl<V> AlgIteratorFactory<V> for BasicAlgIteratorFactory<V> |
| 555 where V : LogRepr { |
591 where |
| |
592 V: LogRepr, |
| |
593 { |
| 556 type State = BasicState; |
594 type State = BasicState; |
| 557 type Iter = BasicAlgIterator<V>; |
595 type Iter = BasicAlgIterator<V>; |
| 558 type Output = V; |
596 type Output = V; |
| 559 |
597 |
| 560 fn prepare(self) -> Self::Iter { |
598 fn prepare(self) -> Self::Iter { |
| 561 BasicAlgIterator { |
599 BasicAlgIterator { options: self.options, iter: 0, _phantoms: PhantomData } |
| 562 options : self.options, |
|
| 563 iter : 0, |
|
| 564 _phantoms : PhantomData |
|
| 565 } |
|
| 566 } |
600 } |
| 567 |
601 |
| 568 #[inline] |
602 #[inline] |
| 569 fn is_quiet(&self) -> bool { |
603 fn is_quiet(&self) -> bool { |
| 570 self.options.quiet |
604 self.options.quiet |
| 571 } |
605 } |
| 572 } |
606 } |
| 573 |
607 |
| 574 impl<V> AlgIterator for BasicAlgIterator<V> |
608 impl<V> AlgIterator for BasicAlgIterator<V> |
| 575 where V : LogRepr { |
609 where |
| |
610 V: LogRepr, |
| |
611 { |
| 576 type State = BasicState; |
612 type State = BasicState; |
| 577 type Output = V; |
613 type Output = V; |
| 578 type Input = V; |
614 type Input = V; |
| 579 |
615 |
| 580 #[inline] |
616 #[inline] |
| 645 |
679 |
| 646 /// An [`AlgIteratorFactory`] for an [`AlgIterator`] that detects “stall”. |
680 /// An [`AlgIteratorFactory`] for an [`AlgIterator`] that detects “stall”. |
| 647 /// |
681 /// |
| 648 /// We define stall as $(v_{k+n}-v_k)/v_k ≤ θ$, where $n$ the distance between |
682 /// We define stall as $(v_{k+n}-v_k)/v_k ≤ θ$, where $n$ the distance between |
| 649 /// [`Step::Result`] iterations, and $θ$ is the provided `stall` parameter. |
683 /// [`Step::Result`] iterations, and $θ$ is the provided `stall` parameter. |
| 650 #[derive(Clone,Copy,Debug,Serialize,Eq,PartialEq)] |
684 #[derive(Clone, Copy, Debug, Serialize, Eq, PartialEq)] |
| 651 pub struct StallIteratorFactory<U : Num, BaseFactory> { |
685 pub struct StallIteratorFactory<U: Num, BaseFactory> { |
| 652 /// An [`AlgIteratorFactory`] on which to build on |
686 /// An [`AlgIteratorFactory`] on which to build on |
| 653 pub base_options : BaseFactory, |
687 pub base_options: BaseFactory, |
| 654 /// Stalling threshold $θ$. |
688 /// Stalling threshold $θ$. |
| 655 pub stall : U, |
689 pub stall: U, |
| 656 } |
690 } |
| 657 |
691 |
| 658 /// Iterator produced by [`StallIteratorFactory`]. |
692 /// Iterator produced by [`StallIteratorFactory`]. |
| 659 pub struct StallIterator<U : Num, BaseIterator> { |
693 pub struct StallIterator<U: Num, BaseIterator> { |
| 660 base_iterator : BaseIterator, |
694 base_iterator: BaseIterator, |
| 661 stall : U, |
695 stall: U, |
| 662 previous_value : Option<U>, |
696 previous_value: Option<U>, |
| 663 } |
697 } |
| 664 |
698 |
| 665 impl<V, U, BaseFactory> AlgIteratorFactory<V> |
699 impl<V, U, BaseFactory> AlgIteratorFactory<V> for StallIteratorFactory<U, BaseFactory> |
| 666 for StallIteratorFactory<U, BaseFactory> |
700 where |
| 667 where BaseFactory : AlgIteratorFactory<V, Output=U>, |
701 BaseFactory: AlgIteratorFactory<V, Output = U>, |
| 668 U : SignedNum + PartialOrd { |
702 U: SignedNum + PartialOrd, |
| |
703 { |
| 669 type Iter = StallIterator<U, BaseFactory::Iter>; |
704 type Iter = StallIterator<U, BaseFactory::Iter>; |
| 670 type State = BaseFactory::State; |
705 type State = BaseFactory::State; |
| 671 type Output = BaseFactory::Output; |
706 type Output = BaseFactory::Output; |
| 672 |
707 |
| 673 fn prepare(self) -> Self::Iter { |
708 fn prepare(self) -> Self::Iter { |
| 674 StallIterator { |
709 StallIterator { |
| 675 base_iterator : self.base_options.prepare(), |
710 base_iterator: self.base_options.prepare(), |
| 676 stall : self.stall, |
711 stall: self.stall, |
| 677 previous_value : None, |
712 previous_value: None, |
| 678 } |
713 } |
| 679 } |
714 } |
| 680 |
715 |
| 681 fn is_quiet(&self) -> bool { |
716 fn is_quiet(&self) -> bool { |
| 682 self.base_options.is_quiet() |
717 self.base_options.is_quiet() |
| 683 } |
718 } |
| 684 } |
719 } |
| 685 |
720 |
| 686 impl<U, BaseIterator> AlgIterator |
721 impl<U, BaseIterator> AlgIterator for StallIterator<U, BaseIterator> |
| 687 for StallIterator<U, BaseIterator> |
722 where |
| 688 where BaseIterator : AlgIterator<Output=U>, |
723 BaseIterator: AlgIterator<Output = U>, |
| 689 U : SignedNum + PartialOrd { |
724 U: SignedNum + PartialOrd, |
| |
725 { |
| 690 type State = BaseIterator::State; |
726 type State = BaseIterator::State; |
| 691 type Output = U; |
727 type Output = U; |
| 692 type Input = BaseIterator::Input; |
728 type Input = BaseIterator::Input; |
| 693 |
729 |
| 694 #[inline] |
730 #[inline] |
| 695 fn prestep(&mut self) -> Option<Self::State> { |
731 fn prestep(&mut self) -> Option<Self::State> { |
| 696 self.base_iterator.prestep() |
732 self.base_iterator.prestep() |
| 697 } |
733 } |
| 698 |
734 |
| 699 #[inline] |
735 #[inline] |
| 700 fn poststep<E>(&mut self, res : Step<Self::Input, Self::State, E>) -> Step<U, Self::State, E> |
736 fn poststep<E>(&mut self, res: Step<Self::Input, Self::State, E>) -> Step<U, Self::State, E> |
| 701 where E : Error { |
737 where |
| |
738 E: Error, |
| |
739 { |
| 702 match self.base_iterator.poststep(res) { |
740 match self.base_iterator.poststep(res) { |
| 703 Step::Result(nv, state) => { |
741 Step::Result(nv, state) => { |
| 704 let previous_v = self.previous_value; |
742 let previous_v = self.previous_value; |
| 705 self.previous_value = Some(nv); |
743 self.previous_value = Some(nv); |
| 706 match previous_v { |
744 match previous_v { |
| 707 Some(pv) if (nv - pv).abs() <= self.stall * pv.abs() => Step::Terminated, |
745 Some(pv) if (nv - pv).abs() <= self.stall * pv.abs() => Step::Terminated, |
| 708 _ => Step::Result(nv, state), |
746 _ => Step::Result(nv, state), |
| 709 } |
747 } |
| 710 }, |
748 } |
| 711 val => val, |
749 val => val, |
| 712 } |
750 } |
| 713 } |
751 } |
| 714 |
752 |
| 715 #[inline] |
753 #[inline] |
| 723 } |
761 } |
| 724 } |
762 } |
| 725 |
763 |
| 726 /// An [`AlgIteratorFactory`] for an [`AlgIterator`] that detect whether step function |
764 /// An [`AlgIteratorFactory`] for an [`AlgIterator`] that detect whether step function |
| 727 /// return value is less than `target`, and terminates if it is. |
765 /// return value is less than `target`, and terminates if it is. |
| 728 #[derive(Clone,Copy,Debug,Serialize,Eq,PartialEq)] |
766 #[derive(Clone, Copy, Debug, Serialize, Eq, PartialEq)] |
| 729 pub struct ValueIteratorFactory<U : Num, BaseFactory> { |
767 pub struct ValueIteratorFactory<U: Num, BaseFactory> { |
| 730 /// An [`AlgIteratorFactory`] on which to build on |
768 /// An [`AlgIteratorFactory`] on which to build on |
| 731 pub base_options : BaseFactory, |
769 pub base_options: BaseFactory, |
| 732 /// Target value |
770 /// Target value |
| 733 pub target : U, |
771 pub target: U, |
| 734 } |
772 } |
| 735 |
773 |
| 736 /// Iterator produced by [`ValueIteratorFactory`]. |
774 /// Iterator produced by [`ValueIteratorFactory`]. |
| 737 pub struct ValueIterator<U : Num, BaseIterator> { |
775 pub struct ValueIterator<U: Num, BaseIterator> { |
| 738 base_iterator : BaseIterator, |
776 base_iterator: BaseIterator, |
| 739 target : U, |
777 target: U, |
| 740 } |
778 } |
| 741 |
779 |
| 742 impl<V, U, BaseFactory> AlgIteratorFactory<V> |
780 impl<V, U, BaseFactory> AlgIteratorFactory<V> for ValueIteratorFactory<U, BaseFactory> |
| 743 for ValueIteratorFactory<U, BaseFactory> |
781 where |
| 744 where BaseFactory : AlgIteratorFactory<V, Output=U>, |
782 BaseFactory: AlgIteratorFactory<V, Output = U>, |
| 745 U : SignedNum + PartialOrd { |
783 U: SignedNum + PartialOrd, |
| |
784 { |
| 746 type Iter = ValueIterator<U, BaseFactory::Iter>; |
785 type Iter = ValueIterator<U, BaseFactory::Iter>; |
| 747 type State = BaseFactory::State; |
786 type State = BaseFactory::State; |
| 748 type Output = BaseFactory::Output; |
787 type Output = BaseFactory::Output; |
| 749 |
788 |
| 750 fn prepare(self) -> Self::Iter { |
789 fn prepare(self) -> Self::Iter { |
| 751 ValueIterator { |
790 ValueIterator { base_iterator: self.base_options.prepare(), target: self.target } |
| 752 base_iterator : self.base_options.prepare(), |
|
| 753 target : self.target |
|
| 754 } |
|
| 755 } |
791 } |
| 756 |
792 |
| 757 fn is_quiet(&self) -> bool { |
793 fn is_quiet(&self) -> bool { |
| 758 self.base_options.is_quiet() |
794 self.base_options.is_quiet() |
| 759 } |
795 } |
| 760 } |
796 } |
| 761 |
797 |
| 762 impl<U, BaseIterator> AlgIterator |
798 impl<U, BaseIterator> AlgIterator for ValueIterator<U, BaseIterator> |
| 763 for ValueIterator<U, BaseIterator> |
799 where |
| 764 where BaseIterator : AlgIterator<Output=U>, |
800 BaseIterator: AlgIterator<Output = U>, |
| 765 U : SignedNum + PartialOrd { |
801 U: SignedNum + PartialOrd, |
| |
802 { |
| 766 type State = BaseIterator::State; |
803 type State = BaseIterator::State; |
| 767 type Output = U; |
804 type Output = U; |
| 768 type Input = BaseIterator::Input; |
805 type Input = BaseIterator::Input; |
| 769 |
806 |
| 770 #[inline] |
807 #[inline] |
| 771 fn prestep(&mut self) -> Option<Self::State> { |
808 fn prestep(&mut self) -> Option<Self::State> { |
| 772 self.base_iterator.prestep() |
809 self.base_iterator.prestep() |
| 773 } |
810 } |
| 774 |
811 |
| 775 #[inline] |
812 #[inline] |
| 776 fn poststep<E>(&mut self, res : Step<Self::Input, Self::State, E>) -> Step<U, Self::State, E> where E : Error{ |
813 fn poststep<E>(&mut self, res: Step<Self::Input, Self::State, E>) -> Step<U, Self::State, E> |
| |
814 where |
| |
815 E: Error, |
| |
816 { |
| 777 match self.base_iterator.poststep(res) { |
817 match self.base_iterator.poststep(res) { |
| 778 Step::Result(v, state) => { |
818 Step::Result(v, state) => { |
| 779 if v <= self.target { |
819 if v <= self.target { |
| 780 Step::Terminated |
820 Step::Terminated |
| 781 } else { |
821 } else { |
| 782 Step::Result(v, state) |
822 Step::Result(v, state) |
| 783 } |
823 } |
| 784 }, |
824 } |
| 785 val => val, |
825 val => val, |
| 786 } |
826 } |
| 787 } |
827 } |
| 788 |
828 |
| 789 #[inline] |
829 #[inline] |
| 806 /// Typically produced with [`AlgIteratorFactory::into_log`]. |
846 /// Typically produced with [`AlgIteratorFactory::into_log`]. |
| 807 /// The `Output` of the corresponding [`LoggingIterator`] is `()`: |
847 /// The `Output` of the corresponding [`LoggingIterator`] is `()`: |
| 808 #[derive(Debug)] |
848 #[derive(Debug)] |
| 809 pub struct LoggingIteratorFactory<'log, U, BaseFactory> { |
849 pub struct LoggingIteratorFactory<'log, U, BaseFactory> { |
| 810 /// Base [`AlgIteratorFactory`] on which to build |
850 /// Base [`AlgIteratorFactory`] on which to build |
| 811 base_options : BaseFactory, |
851 base_options: BaseFactory, |
| 812 /// The `Logger` to use. |
852 /// The `Logger` to use. |
| 813 logger : &'log mut Logger<U>, |
853 logger: &'log mut Logger<U>, |
| 814 } |
854 } |
| 815 |
855 |
| 816 /// Iterator produced by `LoggingIteratorFactory`. |
856 /// Iterator produced by `LoggingIteratorFactory`. |
| 817 pub struct LoggingIterator<'log, U, BaseIterator> { |
857 pub struct LoggingIterator<'log, U, BaseIterator> { |
| 818 base_iterator : BaseIterator, |
858 base_iterator: BaseIterator, |
| 819 logger : &'log mut Logger<U>, |
859 logger: &'log mut Logger<U>, |
| 820 } |
860 } |
| 821 |
|
| 822 |
861 |
| 823 impl<'log, V, BaseFactory> AlgIteratorFactory<V> |
862 impl<'log, V, BaseFactory> AlgIteratorFactory<V> |
| 824 for LoggingIteratorFactory<'log, BaseFactory::Output, BaseFactory> |
863 for LoggingIteratorFactory<'log, BaseFactory::Output, BaseFactory> |
| 825 where BaseFactory : AlgIteratorFactory<V>, |
864 where |
| 826 BaseFactory::Output : 'log { |
865 BaseFactory: AlgIteratorFactory<V>, |
| |
866 BaseFactory::Output: 'log, |
| |
867 { |
| 827 type State = BaseFactory::State; |
868 type State = BaseFactory::State; |
| 828 type Iter = LoggingIterator<'log, BaseFactory::Output, BaseFactory::Iter>; |
869 type Iter = LoggingIterator<'log, BaseFactory::Output, BaseFactory::Iter>; |
| 829 type Output = (); |
870 type Output = (); |
| 830 |
871 |
| 831 fn prepare(self) -> Self::Iter { |
872 fn prepare(self) -> Self::Iter { |
| 832 LoggingIterator { |
873 LoggingIterator { base_iterator: self.base_options.prepare(), logger: self.logger } |
| 833 base_iterator : self.base_options.prepare(), |
|
| 834 logger : self.logger, |
|
| 835 } |
|
| 836 } |
874 } |
| 837 |
875 |
| 838 #[inline] |
876 #[inline] |
| 839 fn is_quiet(&self) -> bool { |
877 fn is_quiet(&self) -> bool { |
| 840 self.base_options.is_quiet() |
878 self.base_options.is_quiet() |
| 841 } |
879 } |
| 842 } |
880 } |
| 843 |
881 |
| 844 impl<'log, BaseIterator> AlgIterator |
882 impl<'log, BaseIterator> AlgIterator for LoggingIterator<'log, BaseIterator::Output, BaseIterator> |
| 845 for LoggingIterator<'log, BaseIterator::Output, BaseIterator> |
883 where |
| 846 where BaseIterator : AlgIterator, |
884 BaseIterator: AlgIterator, |
| 847 BaseIterator::Output : 'log { |
885 BaseIterator::Output: 'log, |
| |
886 { |
| 848 type State = BaseIterator::State; |
887 type State = BaseIterator::State; |
| 849 type Output = (); |
888 type Output = (); |
| 850 type Input = BaseIterator::Input; |
889 type Input = BaseIterator::Input; |
| 851 |
890 |
| 852 #[inline] |
891 #[inline] |
| 853 fn prestep(&mut self) -> Option<Self::State> { |
892 fn prestep(&mut self) -> Option<Self::State> { |
| 854 self.base_iterator.prestep() |
893 self.base_iterator.prestep() |
| 855 } |
894 } |
| 856 |
895 |
| 857 #[inline] |
896 #[inline] |
| 858 fn poststep<E>(&mut self, res : Step<Self::Input, Self::State, E>) -> Step<(), Self::State, E> where E : Error { |
897 fn poststep<E>(&mut self, res: Step<Self::Input, Self::State, E>) -> Step<(), Self::State, E> |
| |
898 where |
| |
899 E: Error, |
| |
900 { |
| 859 match self.base_iterator.poststep(res) { |
901 match self.base_iterator.poststep(res) { |
| 860 Step::Result(v, _) => { |
902 Step::Result(v, _) => { |
| 861 self.logger.log(v); |
903 self.logger.log(v); |
| 862 Step::Quiet |
904 Step::Quiet |
| 863 }, |
905 } |
| 864 Step::Quiet => Step::Quiet, |
906 Step::Quiet => Step::Quiet, |
| 865 Step::Terminated => Step::Terminated, |
907 Step::Terminated => Step::Terminated, |
| 866 Step::Failure(e) => Step::Failure(e), |
908 Step::Failure(e) => Step::Failure(e), |
| 867 } |
909 } |
| 868 } |
910 } |
| 882 /// |
924 /// |
| 883 /// Typically produced with [`AlgIteratorFactory::mapped`]. |
925 /// Typically produced with [`AlgIteratorFactory::mapped`]. |
| 884 #[derive(Debug)] |
926 #[derive(Debug)] |
| 885 pub struct MappingIteratorFactory<G, BaseFactory> { |
927 pub struct MappingIteratorFactory<G, BaseFactory> { |
| 886 /// Base [`AlgIteratorFactory`] on which to build |
928 /// Base [`AlgIteratorFactory`] on which to build |
| 887 base_options : BaseFactory, |
929 base_options: BaseFactory, |
| 888 /// A closure `G : Fn(usize, BaseFactory::Output) -> U` that gets the current iteration |
930 /// A closure `G : Fn(usize, BaseFactory::Output) -> U` that gets the current iteration |
| 889 /// and the output of the base factory as input, and produces a new output. |
931 /// and the output of the base factory as input, and produces a new output. |
| 890 map : G, |
932 map: G, |
| 891 } |
933 } |
| 892 |
934 |
| 893 /// [`AlgIterator`] produced by [`MappingIteratorFactory`]. |
935 /// [`AlgIterator`] produced by [`MappingIteratorFactory`]. |
| 894 pub struct MappingIterator<G, BaseIterator> { |
936 pub struct MappingIterator<G, BaseIterator> { |
| 895 base_iterator : BaseIterator, |
937 base_iterator: BaseIterator, |
| 896 map : G, |
938 map: G, |
| 897 } |
939 } |
| 898 |
940 |
| 899 |
941 impl<V, U, G, BaseFactory> AlgIteratorFactory<V> for MappingIteratorFactory<G, BaseFactory> |
| 900 impl<V, U, G, BaseFactory> AlgIteratorFactory<V> |
942 where |
| 901 for MappingIteratorFactory<G, BaseFactory> |
943 BaseFactory: AlgIteratorFactory<V>, |
| 902 where BaseFactory : AlgIteratorFactory<V>, |
944 G: Fn(usize, BaseFactory::Output) -> U, |
| 903 G : Fn(usize, BaseFactory::Output) -> U { |
945 { |
| 904 type State = BaseFactory::State; |
946 type State = BaseFactory::State; |
| 905 type Iter = MappingIterator<G, BaseFactory::Iter>; |
947 type Iter = MappingIterator<G, BaseFactory::Iter>; |
| 906 type Output = U; |
948 type Output = U; |
| 907 |
949 |
| 908 fn prepare(self) -> Self::Iter { |
950 fn prepare(self) -> Self::Iter { |
| 909 MappingIterator { |
951 MappingIterator { base_iterator: self.base_options.prepare(), map: self.map } |
| 910 base_iterator : self.base_options.prepare(), |
|
| 911 map : self.map |
|
| 912 } |
|
| 913 } |
952 } |
| 914 |
953 |
| 915 #[inline] |
954 #[inline] |
| 916 fn is_quiet(&self) -> bool { |
955 fn is_quiet(&self) -> bool { |
| 917 self.base_options.is_quiet() |
956 self.base_options.is_quiet() |
| 918 } |
957 } |
| 919 } |
958 } |
| 920 |
959 |
| 921 impl<U, G, BaseIterator> AlgIterator |
960 impl<U, G, BaseIterator> AlgIterator for MappingIterator<G, BaseIterator> |
| 922 for MappingIterator<G, BaseIterator> |
961 where |
| 923 where BaseIterator : AlgIterator, |
962 BaseIterator: AlgIterator, |
| 924 G : Fn(usize, BaseIterator::Output) -> U { |
963 G: Fn(usize, BaseIterator::Output) -> U, |
| |
964 { |
| 925 type State = BaseIterator::State; |
965 type State = BaseIterator::State; |
| 926 type Output = U; |
966 type Output = U; |
| 927 type Input = BaseIterator::Input; |
967 type Input = BaseIterator::Input; |
| 928 |
968 |
| 929 #[inline] |
969 #[inline] |
| 930 fn prestep(&mut self) -> Option<Self::State> { |
970 fn prestep(&mut self) -> Option<Self::State> { |
| 931 self.base_iterator.prestep() |
971 self.base_iterator.prestep() |
| 932 } |
972 } |
| 933 |
973 |
| 934 #[inline] |
974 #[inline] |
| 935 fn poststep<E>(&mut self, res : Step<Self::Input, Self::State, E>) -> Step<Self::Output, Self::State, E> where E : Error { |
975 fn poststep<E>( |
| |
976 &mut self, |
| |
977 res: Step<Self::Input, Self::State, E>, |
| |
978 ) -> Step<Self::Output, Self::State, E> |
| |
979 where |
| |
980 E: Error, |
| |
981 { |
| 936 match self.base_iterator.poststep(res) { |
982 match self.base_iterator.poststep(res) { |
| 937 Step::Result(v, state) => Step::Result((self.map)(self.iteration(), v), state), |
983 Step::Result(v, state) => Step::Result((self.map)(self.iteration(), v), state), |
| 938 Step::Quiet => Step::Quiet, |
984 Step::Quiet => Step::Quiet, |
| 939 Step::Terminated => Step::Terminated, |
985 Step::Terminated => Step::Terminated, |
| 940 Step::Failure(e) => Step::Failure(e), |
986 Step::Failure(e) => Step::Failure(e), |
| 961 pub struct TimingIteratorFactory<BaseFactory>(pub BaseFactory); |
1007 pub struct TimingIteratorFactory<BaseFactory>(pub BaseFactory); |
| 962 |
1008 |
| 963 /// Iterator produced by [`TimingIteratorFactory`] |
1009 /// Iterator produced by [`TimingIteratorFactory`] |
| 964 #[derive(Debug)] |
1010 #[derive(Debug)] |
| 965 pub struct TimingIterator<BaseIterator> { |
1011 pub struct TimingIterator<BaseIterator> { |
| 966 base_iterator : BaseIterator, |
1012 base_iterator: BaseIterator, |
| 967 start_time : ProcessTime, |
1013 start_time: ProcessTime, |
| 968 } |
1014 } |
| 969 |
1015 |
| 970 /// Data `U` with production time attached |
1016 /// Data `U` with production time attached |
| 971 #[derive(Copy, Clone, Debug, Serialize)] |
1017 #[derive(Copy, Clone, Debug, Serialize)] |
| 972 pub struct Timed<U> { |
1018 pub struct Timed<U> { |
| 973 /// CPU time taken |
1019 /// CPU time taken |
| 974 pub cpu_time : Duration, |
1020 pub cpu_time: Duration, |
| 975 /// Iteration number |
1021 /// Iteration number |
| 976 pub iter : usize, |
1022 pub iter: usize, |
| 977 /// User data |
1023 /// User data |
| 978 //#[serde(flatten)] |
1024 //#[serde(flatten)] |
| 979 pub data : U |
1025 pub data: U, |
| 980 } |
1026 } |
| 981 |
1027 |
| 982 impl<T> LogRepr for Timed<T> where T : LogRepr { |
1028 impl<T> LogRepr for Timed<T> |
| |
1029 where |
| |
1030 T: LogRepr, |
| |
1031 { |
| 983 fn logrepr(&self) -> ColoredString { |
1032 fn logrepr(&self) -> ColoredString { |
| 984 format!("[{:.3}s] {}", self.cpu_time.as_secs_f64(), self.data.logrepr()).as_str().into() |
1033 format!( |
| 985 } |
1034 "[{:.3}s] {}", |
| 986 } |
1035 self.cpu_time.as_secs_f64(), |
| 987 |
1036 self.data.logrepr() |
| 988 |
1037 ) |
| 989 impl<V, BaseFactory> AlgIteratorFactory<V> |
1038 .as_str() |
| 990 for TimingIteratorFactory<BaseFactory> |
1039 .into() |
| 991 where BaseFactory : AlgIteratorFactory<V> { |
1040 } |
| |
1041 } |
| |
1042 |
| |
1043 impl<V, BaseFactory> AlgIteratorFactory<V> for TimingIteratorFactory<BaseFactory> |
| |
1044 where |
| |
1045 BaseFactory: AlgIteratorFactory<V>, |
| |
1046 { |
| 992 type State = BaseFactory::State; |
1047 type State = BaseFactory::State; |
| 993 type Iter = TimingIterator<BaseFactory::Iter>; |
1048 type Iter = TimingIterator<BaseFactory::Iter>; |
| 994 type Output = Timed<BaseFactory::Output>; |
1049 type Output = Timed<BaseFactory::Output>; |
| 995 |
1050 |
| 996 fn prepare(self) -> Self::Iter { |
1051 fn prepare(self) -> Self::Iter { |
| 997 TimingIterator { |
1052 TimingIterator { base_iterator: self.0.prepare(), start_time: ProcessTime::now() } |
| 998 base_iterator : self.0.prepare(), |
|
| 999 start_time : ProcessTime::now() |
|
| 1000 } |
|
| 1001 } |
1053 } |
| 1002 |
1054 |
| 1003 #[inline] |
1055 #[inline] |
| 1004 fn is_quiet(&self) -> bool { |
1056 fn is_quiet(&self) -> bool { |
| 1005 self.0.is_quiet() |
1057 self.0.is_quiet() |
| 1006 } |
1058 } |
| 1007 } |
1059 } |
| 1008 |
1060 |
| 1009 impl<BaseIterator> AlgIterator |
1061 impl<BaseIterator> AlgIterator for TimingIterator<BaseIterator> |
| 1010 for TimingIterator<BaseIterator> |
1062 where |
| 1011 where BaseIterator : AlgIterator { |
1063 BaseIterator: AlgIterator, |
| |
1064 { |
| 1012 type State = BaseIterator::State; |
1065 type State = BaseIterator::State; |
| 1013 type Output = Timed<BaseIterator::Output>; |
1066 type Output = Timed<BaseIterator::Output>; |
| 1014 type Input = BaseIterator::Input; |
1067 type Input = BaseIterator::Input; |
| 1015 |
1068 |
| 1016 #[inline] |
1069 #[inline] |
| 1017 fn prestep(&mut self) -> Option<Self::State> { |
1070 fn prestep(&mut self) -> Option<Self::State> { |
| 1018 self.base_iterator.prestep() |
1071 self.base_iterator.prestep() |
| 1019 } |
1072 } |
| 1020 |
1073 |
| 1021 #[inline] |
1074 #[inline] |
| 1022 fn poststep<E>(&mut self, res : Step<Self::Input, Self::State, E>) -> Step<Self::Output, Self::State, E> where E : Error { |
1075 fn poststep<E>( |
| |
1076 &mut self, |
| |
1077 res: Step<Self::Input, Self::State, E>, |
| |
1078 ) -> Step<Self::Output, Self::State, E> |
| |
1079 where |
| |
1080 E: Error, |
| |
1081 { |
| 1023 match self.base_iterator.poststep(res) { |
1082 match self.base_iterator.poststep(res) { |
| 1024 Step::Result(data, state) => { |
1083 Step::Result(data, state) => Step::Result( |
| 1025 Step::Result(Timed{ |
1084 Timed { cpu_time: self.start_time.elapsed(), iter: self.iteration(), data }, |
| 1026 cpu_time : self.start_time.elapsed(), |
1085 state, |
| 1027 iter : self.iteration(), |
1086 ), |
| 1028 data |
|
| 1029 }, state) |
|
| 1030 }, |
|
| 1031 Step::Quiet => Step::Quiet, |
1087 Step::Quiet => Step::Quiet, |
| 1032 Step::Terminated => Step::Terminated, |
1088 Step::Terminated => Step::Terminated, |
| 1033 Step::Failure(e) => Step::Failure(e), |
1089 Step::Failure(e) => Step::Failure(e), |
| 1034 } |
1090 } |
| 1035 } |
1091 } |