src/iterate.rs

Sun, 20 Oct 2024 23:28:16 -0500

author
Tuomo Valkonen <tuomov@iki.fi>
date
Sun, 20 Oct 2024 23:28:16 -0500
branch
dev
changeset 40
daf0e3a70c79
parent 38
8aaa22fcd302
child 41
121cf065e9ed
permissions
-rw-r--r--

New iteration interface, allowing for loops.

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

mercurial