src/iterate.rs

Mon, 21 Oct 2024 09:59:45 -0500

author
Tuomo Valkonen <tuomov@iki.fi>
date
Mon, 21 Oct 2024 09:59:45 -0500
branch
dev
changeset 43
239aa32f0e7d
parent 41
121cf065e9ed
child 46
bd924d62d952
permissions
-rw-r--r--

Implement Display for 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].
40
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
138 fn if_verbose<V, E : Error>(self, calc_objective : impl FnMut() -> 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
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
263 /// 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
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 }
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
409 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
410
5
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
411 /// Options for [`BasicAlgIteratorFactory`].
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
412 ///
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
413 /// Use as:
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
414 /// ```
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
415 /// # use alg_tools::iterate::*;
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
416 /// let iter = AlgIteratorOptions{ max_iter : 10000, .. Default::default() };
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
417 /// ```
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
418 #[derive(Clone, Copy, Debug, Serialize, Deserialize, Eq, PartialEq)]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
419 pub struct AlgIteratorOptions {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
420 /// Maximum number of iterations
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
421 pub max_iter : usize,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
422 /// Number of iterations between verbose iterations that display state.
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
423 pub verbose_iter : Verbose,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
424 /// 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
425 /// `AlgIterator`.
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
426 pub quiet : bool,
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
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
429 #[derive(Clone, Copy, Debug, Serialize, Deserialize, Eq, PartialEq)]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
430 pub enum Verbose {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
431 /// Be verbose every $n$ iterations.
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
432 Every(usize),
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
433 /// Be verbose every $n$ iterations and initial $m$ iterations.
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
434 EveryAndInitial{ every : usize, initial : usize },
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
435 /// 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
436 /// $b$ is indicated logarithmic base. So, with $b=10$,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
437 /// * every iteration for first 10 iterations,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
438 /// * every 10 iterations from there on until 100 iterations,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
439 /// * every 100 iteartinos frmo there on until 1000 iterations, etc.
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
440 Logarithmic(usize),
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
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
443 impl Verbose {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
444 /// Indicates whether given iteration number is verbose
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
445 pub fn is_verbose(&self, iter : usize) -> bool {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
446 match self {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
447 &Verbose::Every(every) => {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
448 every != 0 && iter % every == 0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
449 },
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
450 &Verbose::EveryAndInitial{ every, initial } => {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
451 iter <= initial || (every != 0 && iter % every == 0)
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
452 },
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
453 &Verbose::Logarithmic(base) => {
25
d14c877e14b7 Logarithmic logging base correction
Tuomo Valkonen <tuomov@iki.fi>
parents: 5
diff changeset
454 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
455 iter % every == 0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
456 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
457 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
458 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
459 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
460
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
461 impl Default for AlgIteratorOptions {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
462 fn default() -> AlgIteratorOptions {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
463 AlgIteratorOptions{
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
464 max_iter : 1000,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
465 verbose_iter : Verbose::EveryAndInitial { every : 100, initial : 10 },
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
466 quiet : false
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
467 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
468 }
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 /// State of a `BasicAlgIterator`
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
472 #[derive(Clone,Copy,Debug,Serialize,Eq,PartialEq)]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
473 pub struct BasicState {
5
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
474 /// Current iteration
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
475 iter : usize,
5
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
476 /// Whether the iteration is verbose, i.e., results should be displayed.
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
477 /// Requires `calc` to be `true`.
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
478 verbose : bool,
5
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
479 /// Whether results should be calculated.
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
480 calc : bool,
31
50a77e4efcbb Add is_quiet to AlgIteratorState as well.
Tuomo Valkonen <tuomov@iki.fi>
parents: 5
diff changeset
481 /// Indicates whether the iteration is quiet
50a77e4efcbb Add is_quiet to AlgIteratorState as well.
Tuomo Valkonen <tuomov@iki.fi>
parents: 5
diff changeset
482 quiet : bool,
0
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
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
485 /// [`AlgIteratorFactory`] for [`BasicAlgIterator`]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
486 #[derive(Clone,Debug)]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
487 pub struct BasicAlgIteratorFactory<V> {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
488 options : AlgIteratorOptions,
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
489 _phantoms : PhantomData<V>,
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
490 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
491
5
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
492 /// The simplest [`AlgIterator`], created by [`BasicAlgIteratorFactory`]
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
493 #[derive(Clone,Debug)]
40
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
494 pub struct BasicAlgIterator<V> {
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
495 options : AlgIteratorOptions,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
496 iter : usize,
40
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
497 _phantoms : PhantomData<V>,
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
498 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
499
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
500 impl AlgIteratorOptions {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
501 /// [`AlgIteratorOptions`] is directly a factory for [`BasicAlgIterator`],
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
502 /// 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
503 /// 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
504 pub fn instantiate<V>(&self) -> BasicAlgIteratorFactory<V> {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
505 BasicAlgIteratorFactory {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
506 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
507 _phantoms : PhantomData
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
508 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
509 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
510 }
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 impl<V> AlgIteratorFactory<V> for AlgIteratorOptions
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
513 where V : LogRepr {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
514 type State = BasicState;
40
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
515 type Iter = BasicAlgIterator<V>;
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
516 type Output = V;
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
517
40
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
518 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
519 BasicAlgIterator{
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
520 options : self,
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
521 iter : 0,
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
522 _phantoms : PhantomData,
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
523 }
0
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
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
526 #[inline]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
527 fn is_quiet(&self) -> bool {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
528 self.quiet
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
529 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
530 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
531
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
532 impl<V> AlgIteratorFactory<V> for BasicAlgIteratorFactory<V>
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
533 where V : LogRepr {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
534 type State = BasicState;
40
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
535 type Iter = BasicAlgIterator<V>;
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
536 type Output = V;
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
537
40
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
538 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
539 BasicAlgIterator {
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
540 options : self.options,
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
541 iter : 0,
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
542 _phantoms : PhantomData
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
543 }
0
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
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
546 #[inline]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
547 fn is_quiet(&self) -> bool {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
548 self.options.quiet
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
549 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
550 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
551
40
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
552 impl<V> AlgIterator for BasicAlgIterator<V>
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
553 where V : LogRepr {
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
554 type State = BasicState;
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
555 type Output = V;
40
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
556 type Input = V;
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 #[inline]
40
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
559 fn prestep(&mut self) -> Option<Self::State> {
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
560 if self.iter >= self.options.max_iter {
40
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
561 None
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
562 } else {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
563 self.iter += 1;
40
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
564 Some(self.state())
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
565 }
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
566 }
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
567
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
568 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
569 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
570 if state.verbose && !self.options.quiet {
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
571 println!("{}{}/{} {}{}", "".dimmed(),
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
572 state.iter,
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
573 self.options.max_iter,
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
574 val.logrepr(),
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
575 "".clear());
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
576 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
577 }
40
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
578 res
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
579 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
580
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
581 #[inline]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
582 fn iteration(&self) -> usize {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
583 self.iter
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
584 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
585
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
586 #[inline]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
587 fn state(&self) -> BasicState {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
588 let iter = self.iter;
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
589 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
590 BasicState {
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
591 iter : iter,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
592 verbose : verbose,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
593 calc : verbose,
31
50a77e4efcbb Add is_quiet to AlgIteratorState as well.
Tuomo Valkonen <tuomov@iki.fi>
parents: 5
diff changeset
594 quiet : self.options.quiet
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
595 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
596 }
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 impl AlgIteratorState for BasicState {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
600 #[inline]
40
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
601 fn if_verbose<V, E : Error>(self, mut calc_objective : impl FnMut() -> V) -> Step<V, Self, E> {
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
602 if self.calc {
40
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
603 Step::Result(calc_objective(), self)
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
604 } else {
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
605 Step::Quiet
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
606 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
607 }
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 #[inline]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
610 fn iteration(&self) -> usize {
31
50a77e4efcbb Add is_quiet to AlgIteratorState as well.
Tuomo Valkonen <tuomov@iki.fi>
parents: 5
diff changeset
611 self.iter
50a77e4efcbb Add is_quiet to AlgIteratorState as well.
Tuomo Valkonen <tuomov@iki.fi>
parents: 5
diff changeset
612 }
50a77e4efcbb Add is_quiet to AlgIteratorState as well.
Tuomo Valkonen <tuomov@iki.fi>
parents: 5
diff changeset
613
50a77e4efcbb Add is_quiet to AlgIteratorState as well.
Tuomo Valkonen <tuomov@iki.fi>
parents: 5
diff changeset
614 #[inline]
50a77e4efcbb Add is_quiet to AlgIteratorState as well.
Tuomo Valkonen <tuomov@iki.fi>
parents: 5
diff changeset
615 fn is_quiet(&self) -> bool {
50a77e4efcbb Add is_quiet to AlgIteratorState as well.
Tuomo Valkonen <tuomov@iki.fi>
parents: 5
diff changeset
616 self.quiet
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
617 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
618 }
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 // Stall detecting iteration function.
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
622 //
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
623
5
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
624 /// An [`AlgIteratorFactory`] for an [`AlgIterator`] that detects “stall”.
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
625 ///
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
626 /// 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
627 /// [`Step::Result`] iterations, and $θ$ is the provided `stall` parameter.
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
628 #[derive(Clone,Copy,Debug,Serialize,Eq,PartialEq)]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
629 pub struct StallIteratorFactory<U : Num, BaseFactory> {
5
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
630 /// An [`AlgIteratorFactory`] on which to build on
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
631 pub base_options : BaseFactory,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
632 /// Stalling threshold $θ$.
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
633 pub stall : U,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
634 }
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 /// Iterator produced by [`StallIteratorFactory`].
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
637 pub struct StallIterator<U : Num, BaseIterator> {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
638 base_iterator : BaseIterator,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
639 stall : U,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
640 previous_value : Option<U>,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
641 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
642
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
643 impl<V, U, BaseFactory> AlgIteratorFactory<V>
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
644 for StallIteratorFactory<U, BaseFactory>
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
645 where BaseFactory : AlgIteratorFactory<V, Output=U>,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
646 U : SignedNum + PartialOrd {
40
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
647 type Iter = StallIterator<U, BaseFactory::Iter>;
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
648 type State = BaseFactory::State;
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
649 type Output = BaseFactory::Output;
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
650
40
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
651 fn prepare(self) -> Self::Iter {
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
652 StallIterator {
40
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
653 base_iterator : self.base_options.prepare(),
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
654 stall : self.stall,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
655 previous_value : None,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
656 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
657 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
658
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
659 fn is_quiet(&self) -> bool {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
660 self.base_options.is_quiet()
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
661 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
662 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
663
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
664 impl<U, BaseIterator> AlgIterator
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
665 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
666 where BaseIterator : AlgIterator<Output=U>,
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
667 U : SignedNum + PartialOrd {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
668 type State = BaseIterator::State;
40
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
669 type Output = U;
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
670 type Input = BaseIterator::Input;
0
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 #[inline]
40
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
673 fn prestep(&mut self) -> Option<Self::State> {
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
674 self.base_iterator.prestep()
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
675 }
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
676
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
677 #[inline]
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
678 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
679 where E : Error {
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
680 match self.base_iterator.poststep(res) {
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
681 Step::Result(nv, state) => {
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
682 let previous_v = self.previous_value;
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
683 self.previous_value = Some(nv);
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
684 match previous_v {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
685 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
686 _ => Step::Result(nv, state),
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
687 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
688 },
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
689 val => val,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
690 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
691 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
692
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
693 #[inline]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
694 fn iteration(&self) -> usize {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
695 self.base_iterator.iteration()
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
696 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
697
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
698 #[inline]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
699 fn state(&self) -> Self::State {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
700 self.base_iterator.state()
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 }
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 /// An [`AlgIteratorFactory`] for an [`AlgIterator`] that detect whether step function
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
705 /// return value is less than `target`, and terminates if it is.
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
706 #[derive(Clone,Copy,Debug,Serialize,Eq,PartialEq)]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
707 pub struct ValueIteratorFactory<U : Num, BaseFactory> {
5
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
708 /// An [`AlgIteratorFactory`] on which to build on
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
709 pub base_options : BaseFactory,
5
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
710 /// Target value
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
711 pub target : U,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
712 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
713
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
714 /// Iterator produced by [`ValueIteratorFactory`].
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
715 pub struct ValueIterator<U : Num, BaseIterator> {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
716 base_iterator : BaseIterator,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
717 target : U,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
718 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
719
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
720 impl<V, U, BaseFactory> AlgIteratorFactory<V>
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
721 for ValueIteratorFactory<U, BaseFactory>
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
722 where BaseFactory : AlgIteratorFactory<V, Output=U>,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
723 U : SignedNum + PartialOrd {
40
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
724 type Iter = ValueIterator<U, BaseFactory::Iter>;
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
725 type State = BaseFactory::State;
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
726 type Output = BaseFactory::Output;
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
727
40
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
728 fn prepare(self) -> Self::Iter {
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
729 ValueIterator {
40
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
730 base_iterator : self.base_options.prepare(),
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
731 target : self.target
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 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
734
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
735 fn is_quiet(&self) -> bool {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
736 self.base_options.is_quiet()
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
737 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
738 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
739
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
740 impl<U, BaseIterator> AlgIterator
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
741 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
742 where BaseIterator : AlgIterator<Output=U>,
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
743 U : SignedNum + PartialOrd {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
744 type State = BaseIterator::State;
40
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
745 type Output = U;
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
746 type Input = BaseIterator::Input;
0
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 #[inline]
40
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
749 fn prestep(&mut self) -> Option<Self::State> {
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
750 self.base_iterator.prestep()
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
751 }
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
752
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
753 #[inline]
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
754 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
755 match self.base_iterator.poststep(res) {
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
756 Step::Result(v, state) => {
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
757 if v <= self.target {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
758 Step::Terminated
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
759 } else {
40
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
760 Step::Result(v, state)
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
761 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
762 },
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
763 val => val,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
764 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
765 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
766
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
767 #[inline]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
768 fn iteration(&self) -> usize {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
769 self.base_iterator.iteration()
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
770 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
771
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
772 #[inline]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
773 fn state(&self) -> Self::State {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
774 self.base_iterator.state()
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 }
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 // Logging iterator
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
780 //
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
781
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
782 /// [`AlgIteratorFactory`] for a logging [`AlgIterator`].
5
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
783 ///
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
784 /// Typically produced with [`AlgIteratorFactory::into_log`].
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
785 /// The `Output` of the corresponding [`LoggingIterator`] is `()`:
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
786 #[derive(Debug)]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
787 pub struct LoggingIteratorFactory<'log, U, BaseFactory> {
5
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
788 /// Base [`AlgIteratorFactory`] on which to build
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
789 base_options : BaseFactory,
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
790 /// The `Logger` to use.
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
791 logger : &'log mut Logger<U>,
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
792 }
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 /// Iterator produced by `LoggingIteratorFactory`.
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
795 pub struct LoggingIterator<'log, U, BaseIterator> {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
796 base_iterator : BaseIterator,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
797 logger : &'log mut Logger<U>,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
798 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
799
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
800
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
801 impl<'log, V, BaseFactory> AlgIteratorFactory<V>
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
802 for LoggingIteratorFactory<'log, BaseFactory::Output, BaseFactory>
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
803 where BaseFactory : AlgIteratorFactory<V>,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
804 BaseFactory::Output : 'log {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
805 type State = BaseFactory::State;
40
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
806 type Iter = LoggingIterator<'log, BaseFactory::Output, BaseFactory::Iter>;
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
807 type Output = ();
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
808
40
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
809 fn prepare(self) -> Self::Iter {
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
810 LoggingIterator {
40
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
811 base_iterator : self.base_options.prepare(),
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
812 logger : self.logger,
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 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
815
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
816 #[inline]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
817 fn is_quiet(&self) -> bool {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
818 self.base_options.is_quiet()
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
819 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
820 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
821
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
822 impl<'log, BaseIterator> AlgIterator
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
823 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
824 where BaseIterator : AlgIterator,
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
825 BaseIterator::Output : 'log {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
826 type State = BaseIterator::State;
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
827 type Output = ();
40
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
828 type Input = BaseIterator::Input;
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
829
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
830 #[inline]
40
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
831 fn prestep(&mut self) -> Option<Self::State> {
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
832 self.base_iterator.prestep()
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
833 }
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
834
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
835 #[inline]
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
836 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
837 match self.base_iterator.poststep(res) {
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
838 Step::Result(v, _) => {
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
839 self.logger.log(v);
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
840 Step::Quiet
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
841 },
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
842 Step::Quiet => Step::Quiet,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
843 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
844 Step::Failure(e) => Step::Failure(e),
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
845 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
846 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
847
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
848 #[inline]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
849 fn iteration(&self) -> usize {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
850 self.base_iterator.iteration()
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
851 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
852
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
853 #[inline]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
854 fn state(&self) -> Self::State {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
855 self.base_iterator.state()
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
856 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
857 }
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 /// This [`AlgIteratorFactory`] allows output mapping.
40
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
860 ///
5
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
861 /// Typically produced with [`AlgIteratorFactory::mapped`].
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
862 #[derive(Debug)]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
863 pub struct MappingIteratorFactory<G, BaseFactory> {
5
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
864 /// Base [`AlgIteratorFactory`] on which to build
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
865 base_options : BaseFactory,
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
866 /// 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
867 /// 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
868 map : G,
0
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
5
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
871 /// [`AlgIterator`] produced by [`MappingIteratorFactory`].
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
872 pub struct MappingIterator<G, BaseIterator> {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
873 base_iterator : BaseIterator,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
874 map : G,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
875 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
876
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
877
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
878 impl<V, U, G, BaseFactory> AlgIteratorFactory<V>
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
879 for MappingIteratorFactory<G, BaseFactory>
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
880 where BaseFactory : AlgIteratorFactory<V>,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
881 G : Fn(usize, BaseFactory::Output) -> U {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
882 type State = BaseFactory::State;
40
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
883 type Iter = MappingIterator<G, BaseFactory::Iter>;
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
884 type Output = U;
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
885
40
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
886 fn prepare(self) -> Self::Iter {
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
887 MappingIterator {
40
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
888 base_iterator : self.base_options.prepare(),
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
889 map : self.map
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 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
892
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
893 #[inline]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
894 fn is_quiet(&self) -> bool {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
895 self.base_options.is_quiet()
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
896 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
897 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
898
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
899 impl<U, G, BaseIterator> AlgIterator
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
900 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
901 where BaseIterator : AlgIterator,
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
902 G : Fn(usize, BaseIterator::Output) -> U {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
903 type State = BaseIterator::State;
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
904 type Output = U;
40
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
905 type Input = BaseIterator::Input;
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
906
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
907 #[inline]
40
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
908 fn prestep(&mut self) -> Option<Self::State> {
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
909 self.base_iterator.prestep()
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
910 }
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
911
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
912 #[inline]
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
913 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
914 match self.base_iterator.poststep(res) {
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
915 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
916 Step::Quiet => Step::Quiet,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
917 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
918 Step::Failure(e) => Step::Failure(e),
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 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
921
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
922 #[inline]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
923 fn iteration(&self) -> usize {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
924 self.base_iterator.iteration()
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
925 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
926
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
927 #[inline]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
928 fn state(&self) -> Self::State {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
929 self.base_iterator.state()
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
930 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
931 }
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 // Timing iterator
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
935 //
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
936
5
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
937 /// 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
938 #[derive(Debug)]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
939 pub struct TimingIteratorFactory<BaseFactory>(pub BaseFactory);
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
940
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
941 /// Iterator produced by [`TimingIteratorFactory`]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
942 #[derive(Debug)]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
943 pub struct TimingIterator<BaseIterator> {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
944 base_iterator : BaseIterator,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
945 start_time : ProcessTime,
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
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
948 /// Data `U` with production time attached
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
949 #[derive(Copy, Clone, Debug, Serialize)]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
950 pub struct Timed<U> {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
951 pub cpu_time : Duration,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
952 //#[serde(flatten)]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
953 pub data : U
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
954 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
955
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
956 impl<T> LogRepr for Timed<T> where T : LogRepr {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
957 fn logrepr(&self) -> ColoredString {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
958 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
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
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
962
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
963 impl<V, BaseFactory> AlgIteratorFactory<V>
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
964 for TimingIteratorFactory<BaseFactory>
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
965 where BaseFactory : AlgIteratorFactory<V> {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
966 type State = BaseFactory::State;
40
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
967 type Iter = TimingIterator<BaseFactory::Iter>;
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
968 type Output = Timed<BaseFactory::Output>;
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
969
40
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
970 fn prepare(self) -> Self::Iter {
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
971 TimingIterator {
40
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
972 base_iterator : self.0.prepare(),
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
973 start_time : ProcessTime::now()
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
974 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
975 }
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 #[inline]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
978 fn is_quiet(&self) -> bool {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
979 self.0.is_quiet()
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
980 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
981 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
982
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
983 impl<BaseIterator> AlgIterator
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
984 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
985 where BaseIterator : AlgIterator {
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
986 type State = BaseIterator::State;
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
987 type Output = Timed<BaseIterator::Output>;
40
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
988 type Input = BaseIterator::Input;
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
989
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
990 #[inline]
40
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
991 fn prestep(&mut self) -> Option<Self::State> {
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
992 self.base_iterator.prestep()
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
993 }
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
994
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
995 #[inline]
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
996 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
997 match self.base_iterator.poststep(res) {
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
998 Step::Result(data, state) => {
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
999 Step::Result(Timed{
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1000 cpu_time : self.start_time.elapsed(),
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1001 data
40
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
1002 }, state)
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1003 },
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1004 Step::Quiet => Step::Quiet,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1005 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
1006 Step::Failure(e) => Step::Failure(e),
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1007 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1008 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1009
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1010 #[inline]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1011 fn iteration(&self) -> usize {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1012 self.base_iterator.iteration()
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1013 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1014
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1015 #[inline]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1016 fn state(&self) -> Self::State {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1017 self.base_iterator.state()
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1018 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1019 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1020
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1021 //
40
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
1022 // New for-loop interface
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
1023 //
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
1024
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
1025 pub struct AlgIteratorIterator<I : AlgIterator> {
41
121cf065e9ed Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
1026 algi : Rc<RefCell<I>>,
40
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
1027 }
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
1028
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
1029 pub struct AlgIteratorIteration<I : AlgIterator> {
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
1030 state : I::State,
41
121cf065e9ed Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
1031 algi : Rc<RefCell<I>>,
40
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
1032 }
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
1033
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
1034 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
1035 type Item = AlgIteratorIteration<I>;
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
1036
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
1037 fn next(&mut self) -> Option<Self::Item> {
41
121cf065e9ed Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
1038 let algi = self.algi.clone();
121cf065e9ed Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
1039 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
1040 state,
41
121cf065e9ed Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
1041 algi,
40
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 }
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
1044 }
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 /// Types of errors that may occur
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
1047 #[derive(Debug,PartialEq,Eq)]
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
1048 pub enum IterationError {
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
1049 /// [`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
1050 ReportingOrderingError
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
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
1053 impl<I : AlgIterator> AlgIteratorIteration<I> {
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
1054 /// 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
1055 ///
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
1056 /// 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
1057 ///
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
1058 /// 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
1059 /// 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
1060 /// [module documentation][self].
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 /// 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
1063 /// 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
1064 /// [`Self::if_verbose_check`].
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
1065 pub fn if_verbose(self, calc_objective : impl FnMut() -> I::Input) {
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
1066 self.if_verbose_check(calc_objective).unwrap()
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
1067 }
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
1068
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
1069 /// Version of [`Self::if_verbose`] that propagates errors instead of panicking.
41
121cf065e9ed Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
1070 pub fn if_verbose_check(self, calc_objective : impl FnMut() -> I::Input)
40
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
1071 -> Result<(), IterationError> {
41
121cf065e9ed Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
1072 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
1073 Err(_) => return Err(IterationError::ReportingOrderingError),
121cf065e9ed Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
1074 Ok(algi) => algi
121cf065e9ed Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
1075 };
121cf065e9ed Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
1076 if self.state.iteration() != algi.iteration() {
40
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
1077 Err(IterationError::ReportingOrderingError)
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
1078 } else {
41
121cf065e9ed Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
1079 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
1080 = self.state.if_verbose(calc_objective);
121cf065e9ed Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
1081 algi.poststep(res);
40
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
1082 Ok(())
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
1083 }
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
1084 }
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 /// Returns the current iteration count.
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
1087 pub fn iteration(&self) -> usize {
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
1088 self.state.iteration()
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
1089 }
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
1090
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
1091 /// Indicates whether the iterator is quiet
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
1092 pub fn is_quiet(&self) -> bool {
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
1093 self.state.is_quiet()
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
1094 }
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
1095 }
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
1096
daf0e3a70c79 New iteration interface, allowing for loops.
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
1097 //
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1098 // Tests
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1099 //
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1100
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1101 #[cfg(test)]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1102 mod tests {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1103 use super::*;
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1104 use crate::logger::Logger;
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1105 #[test]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1106 fn iteration() {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1107 let options = AlgIteratorOptions{
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1108 max_iter : 10,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1109 verbose_iter : Verbose::Every(3),
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1110 .. Default::default()
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1111 };
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1112
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1113 {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1114 let mut start = 1 as int;
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1115 options.iterate(|state| {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1116 start = start * 2;
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1117 state.if_verbose(|| start)
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 assert_eq!(start, (2 as int).pow(10));
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1120 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1121
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1122 {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1123 let mut start = 1 as int;
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1124 let mut log = Logger::new();
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1125 let factory = options.instantiate()
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1126 .with_iteration_number()
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1127 .into_log(&mut log);
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1128 factory.iterate(|state| {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1129 start = start * 2;
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1130 state.if_verbose(|| start)
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 assert_eq!(start, (2 as int).pow(10));
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1133 assert_eq!(log.data()
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1134 .iter()
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1135 .map(|LogItem{ data : v, iter : _ }| v.clone())
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1136 .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
1137 (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
1138 .skip(2)
df3901ec2f5d Fix some unit tests after fundamental changes that made them invalid
Tuomo Valkonen <tuomov@iki.fi>
parents: 0
diff changeset
1139 .step_by(3)
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1140 .collect::<Vec<int>>())
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1141 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1142 }
41
121cf065e9ed Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
1143
121cf065e9ed Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
1144 #[test]
121cf065e9ed Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
1145 fn iteration_for_loop() {
121cf065e9ed Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
1146 let options = AlgIteratorOptions{
121cf065e9ed Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
1147 max_iter : 10,
121cf065e9ed Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
1148 verbose_iter : Verbose::Every(3),
121cf065e9ed Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
1149 .. Default::default()
121cf065e9ed Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
1150 };
121cf065e9ed Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
1151
121cf065e9ed Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
1152 {
121cf065e9ed Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
1153 let mut start = 1 as int;
121cf065e9ed Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
1154 for state in options.iter() {
121cf065e9ed Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
1155 start = start * 2;
121cf065e9ed Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
1156 state.if_verbose(|| start)
121cf065e9ed Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
1157 }
121cf065e9ed Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
1158 assert_eq!(start, (2 as int).pow(10));
121cf065e9ed Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
1159 }
121cf065e9ed Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
1160
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 let mut start = 1 as int;
121cf065e9ed Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
1163 let mut log = Logger::new();
121cf065e9ed Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
1164 let factory = options.instantiate()
121cf065e9ed Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
1165 .with_iteration_number()
121cf065e9ed Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
1166 .into_log(&mut log);
121cf065e9ed Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
1167 for state in factory.iter() {
121cf065e9ed Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
1168 start = start * 2;
121cf065e9ed Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
1169 state.if_verbose(|| start)
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 assert_eq!(start, (2 as int).pow(10));
121cf065e9ed Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
1172 assert_eq!(log.data()
121cf065e9ed Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
1173 .iter()
121cf065e9ed Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
1174 .map(|LogItem{ data : v, iter : _ }| v.clone())
121cf065e9ed Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
1175 .collect::<Vec<int>>(),
121cf065e9ed Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
1176 (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
1177 .skip(2)
121cf065e9ed Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
1178 .step_by(3)
121cf065e9ed Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
1179 .collect::<Vec<int>>())
121cf065e9ed Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
1180 }
121cf065e9ed Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
1181 }
121cf065e9ed Simplify iterate facility for-loop mechanism
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
1182
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1183 }

mercurial