src/iterate.rs

Fri, 06 Dec 2024 13:06:22 -0500

author
Tuomo Valkonen <tuomov@iki.fi>
date
Fri, 06 Dec 2024 13:06:22 -0500
branch
dev
changeset 52
c70b575d22b6
parent 51
92ef745ec8db
child 87
72968cf30033
permissions
-rw-r--r--

Reflect and rotate of Loc

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

mercurial