src/iterate.rs

Wed, 07 Dec 2022 07:00:27 +0200

author
Tuomo Valkonen <tuomov@iki.fi>
date
Wed, 07 Dec 2022 07:00:27 +0200
changeset 18
2b75e98df693
parent 5
59dc4c5883f4
child 25
d14c877e14b7
permissions
-rw-r--r--

Added tag v0.1.0 for changeset 51bfde513cfa

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;
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
55 use crate::types::*;
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
56 use crate::logger::*;
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
57
5
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
58 /// Create the displayed presentation for log items.
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
59 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
60 fn logrepr(&self) -> ColoredString { format!("« {self:?} »").as_str().into() }
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
61 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
62
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
63 impl LogRepr for str {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
64 fn logrepr(&self) -> ColoredString { self.into() }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
65 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
66
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
67 impl LogRepr for String {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
68 fn logrepr(&self) -> ColoredString { self.as_str().into() }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
69 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
70
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
71 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
72 fn logrepr(&self) -> ColoredString { format!("J={self}").as_str().into() }
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
73 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
74
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
75 impl<V> LogRepr for Option<V> where V : LogRepr {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
76 fn logrepr(&self) -> ColoredString {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
77 match self {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
78 None => { "===missing value===".red() }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
79 Some(v) => { v.logrepr() }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
80 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
81 }
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
5
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
84 /// Helper struct for returning results annotated with an additional string to
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
85 /// [`if_verbose`][AlgIteratorState::if_verbose]. The [`LogRepr`] implementation will
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
86 /// 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
87 #[derive(Debug,Clone)]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
88 pub struct Annotated<F>(pub F, pub String);
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
89
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
90 impl<V> LogRepr for Annotated<V> where V : LogRepr {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
91 fn logrepr(&self) -> ColoredString {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
92 format!("{}\t| {}", self.0.logrepr(), self.1).as_str().into()
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
93 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
94 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
95
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
96
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
97 /// Basic log item.
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
98 #[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
99 pub struct LogItem<V> {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
100 pub iter : usize,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
101 // This causes [`csv`] to crash.
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
102 //#[serde(flatten)]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
103 pub data : V
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
104 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
105
5
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
106 impl<V> LogItem<V> {
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
107 /// Creates a new log item
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
108 fn new(iter : usize, data : V) -> Self {
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
109 LogItem{ iter, data }
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
110 }
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
111 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
112
5
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
113 /// State of an [`AlgIterator`].
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
114 ///
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
115 /// 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
116 /// [`AlgIteratorFactory::iterate`].
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
117 pub trait AlgIteratorState {
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
118 /// 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
119 ///
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
120 /// 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
121 ///
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
122 /// 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
123 /// 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
124 /// [module documentation][self].
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
125 fn if_verbose<V, E : Error>(&self, calc_objective : impl FnMut() -> V) -> Step<V, E>;
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
126
5
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
127 /// Returns the current iteration count.
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
128 fn iteration(&self) -> usize;
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
129 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
130
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
131 /// Result of a step of an [`AlgIterator`]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
132 #[derive(Debug, Serialize)]
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
133 pub enum Step<V, Fail : Error = std::convert::Infallible> {
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
134 /// Iteration should be terminated
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
135 Terminated,
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
136 /// 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
137 Failure(Fail),
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
138 /// No result this iteration (due to verbosity settings)
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
139 Quiet,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
140 /// Result of this iteration (due to verbosity settings)
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
141 Result(V),
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
142 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
143
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
144 impl<V, E : Error> Step<V, E> {
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
145 /// Maps the value contained within the `Step`, if any, by the closure `f`.
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
146 pub fn map<U>(self, mut f : impl FnMut(V) -> U) -> Step<U, E> {
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
147 match self {
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
148 Step::Result(v) => Step::Result(f(v)),
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
149 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
150 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
151 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
152 }
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
153 }
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
154 }
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
155
5
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
156 /// 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
157 ///
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
158 /// 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
159 /// 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
160 pub trait AlgIterator : Sized {
5
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
161 /// The state type
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
162 type State : AlgIteratorState;
5
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
163 /// The output type for [`Self::step`].
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
164 type Output;
5
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
165 /// The error type for [`Self::step`] and [`Self::iterate`].
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
166 type Err : Error;
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
167
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
168 /// Advance the iterator.
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
169 fn step(&mut self) -> Step<Self::Output, Self::Err>;
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
170
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
171 /// Return current iteration count.
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
172 fn iteration(&self) -> usize {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
173 self.state().iteration()
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
174 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
175
5
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
176 /// Return current state.
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
177 fn state(&self) -> Self::State;
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
178
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
179 /// Iterate the `AlgIterator` until termination.
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
180 ///
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
181 /// 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
182 #[inline]
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
183 fn iterate(&mut self) -> Result<(), Self::Err> {
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
184 loop {
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
185 match self.step() {
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
186 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
187 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
188 _ => {},
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
189 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
190 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
191 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
192
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
193 /// Converts the `AlgIterator` into a plain [`Iterator`].
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
194 ///
5
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
195 /// [`Step::Quiet`] results are discarded, and [`Step::Failure`] results **panic**.
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
196 fn downcast(self) -> AlgIteratorI<Self> {
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
197 AlgIteratorI(self)
0
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 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
200
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
201 /// Conversion of an `AlgIterator` into a plain [`Iterator`].
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
202 ///
5
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
203 /// The conversion discards [`Step::Quiet`] and **panics** on [`Step::Failure`].
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
204 pub struct AlgIteratorI<A>(A);
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
205
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
206 impl<A> Iterator for AlgIteratorI<A>
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
207 where A : AlgIterator {
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
208 type Item = A::Output;
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
209
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
210 fn next(&mut self) -> Option<A::Output> {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
211 loop {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
212 match self.0.step() {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
213 Step::Result(v) => return Some(v),
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
214 Step::Failure(e) => panic!("{e:?}"),
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
215 Step::Terminated => return None,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
216 Step::Quiet => continue,
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 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
220 }
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 /// A factory for producing an [`AlgIterator`].
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
223 ///
5
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
224 /// For usage instructions see the [module documentation][self].
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
225 pub trait AlgIteratorFactory<V> : Sized {
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
226 type Iter<F, E> : AlgIterator<State = Self::State, Output = Self::Output, Err = E>
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
227 where F : FnMut(&Self::State) -> Step<V, E>,
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
228 E : Error;
5
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
229 /// The state type of the corresponding [`AlgIterator`].
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
230 /// 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
231 type State : AlgIteratorState;
5
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
232 /// The output type of the corresponding [`AlgIterator`].
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
233 /// 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
234 /// mappings performed by each [`AlgIterator`] implementation.
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
235 type Output;
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
236
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
237 /// Prepare an [`AlgIterator`], consuming the factory.
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
238 ///
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
239 /// The function `step_fn` should accept a `state` ([`AlgIteratorState`] parameter, and return
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
240 /// a [`Step`].
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
241 fn prepare<F, E>(self, step_fn : F) -> Self::Iter<F, E>
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
242 where F : FnMut(&Self::State) -> Step<V, E>,
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
243 E : Error;
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
244
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
245 /// 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
246 ///
5
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
247 /// The closure should accept a `state` parameter (satisfying the trait [`AlgIteratorState`]).
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
248 /// It should return the output of
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
249 /// `state.`[`if_verbose`][AlgIteratorState::if_verbose], [`Step::Terminated`] to indicate
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
250 /// 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
251 ///
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
252 /// 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
253 #[inline]
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
254 fn iterate_fallible<F, E>(self, step : F) -> Result<(), E>
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
255 where F : FnMut(&Self::State) -> Step<V, E>,
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
256 E : Error {
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
257 self.prepare(step).iterate()
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
258 }
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
259
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
260 /// 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
261 ///
5
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
262 /// The closure should accept a `state` parameter (satisfying the trait [`AlgIteratorState`]),
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
263 /// It should return the output of
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
264 /// `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
265 ///
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
266 /// For usage instructions see the [module documentation][self].
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
267 ///
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
268 /// 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
269 /// with the error type `E=`[`std::convert::Infallible`].
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
270 #[inline]
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
271 fn iterate<F>(self, step : F)
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
272 where F : FnMut(&Self::State) -> Step<V> {
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
273 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
274 }
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
275
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
276 /// 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
277 ///
5
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
278 /// The closure should accept a `state` parameter (satisfying the trait [`AlgIteratorState`]),
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
279 /// 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
280 /// `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
281 /// 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
282 ///
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
283 /// 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
284 /// successsfully.
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
285 ///
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
286 /// 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
287 #[inline]
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
288 fn iterate_data_fallible<F, D, I, E>(self, mut datasource : I, mut step : F) -> Result<(), E>
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
289 where F : FnMut(&Self::State, D) -> Step<V, E>,
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
290 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
291 E : Error {
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
292 self.prepare(move |state| {
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
293 datasource.next().map_or(Step::Terminated, |d| step(state, d))
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
294 }).iterate()
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
295 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
296
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
297 /// 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
298 ///
5
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
299 /// The closure should accept a `state` parameter (satisfying the trait [`AlgIteratorState`]),
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
300 /// 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
301 /// `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
302 ///
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
303 /// 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
304 /// successsfully.
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
305 ///
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
306 /// For usage instructions see the [module documentation][self].
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
307 #[inline]
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
308 fn iterate_data<F, D, I>(self, datasource : I, step : F)
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
309 where F : FnMut(&Self::State, D) -> Step<V>,
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
310 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
311 self.iterate_data_fallible(datasource, step).unwrap_or_default()
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
312 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
313
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
314 // fn make_iterate<'own>(self)
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
315 // -> Box<dyn (FnMut(dyn FnMut(&Self::State) -> Option<V>) -> ()) + 'own> {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
316 // Box::new(move |step| self.iterate(step))
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
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
319 // fn make_iterate_data<'own, D, I>(self, datasource : I)
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
320 // -> Box<dyn (FnMut(dyn FnMut(&Self::State, D) -> Option<V>) -> ()) + 'own>
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
321 // where I : Iterator<Item = D> + 'own {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
322 // Box::new(move |step| self.iterate_data(step, datasource))
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
323 // }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
324
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
325 /// Add logging to the iterator produced by the factory.
5
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
326 ///
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
327 /// 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
328 /// log without passing it onwards.
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
329 ///
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
330 /// Use as:
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
331 /// ```rust
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
332 /// # use alg_tools::iterate::*;
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
333 /// # use alg_tools::logger::*;
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
334 /// let iter = AlgIteratorOptions::default();
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
335 /// let mut log = Logger::new();
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
336 /// iter.into_log(&mut log).iterate(|state|{
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
337 /// // perform iterations
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
338 /// state.if_verbose(||{
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
339 /// // calculate and return function value or other displayed data v
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
340 /// return 0
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
341 /// })
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
342 /// })
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
343 /// ```
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
344 fn into_log<'log>(self, logger : &'log mut Logger<Self::Output>)
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
345 -> LoggingIteratorFactory<'log, Self::Output, Self>
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
346 where Self : Sized {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
347 LoggingIteratorFactory {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
348 base_options : self,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
349 logger,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
350 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
351 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
352
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
353 /// Map the output of the iterator produced by the factory.
5
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
354 ///
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
355 /// Returns a new factory.
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
356 fn mapped<U, G>(self, map : G)
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
357 -> MappingIteratorFactory<G, Self>
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
358 where Self : Sized,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
359 G : Fn(usize, Self::Output) -> U {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
360 MappingIteratorFactory {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
361 base_options : self,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
362 map
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
363 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
364 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
365
5
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
366 /// Adds iteration number to the output.
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
367 ///
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
368 /// Returns a new factory.
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
369 /// Typically followed by [`Self::into_log`].
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
370 fn with_iteration_number(self)
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
371 -> MappingIteratorFactory<fn(usize, Self::Output) -> LogItem<Self::Output>, Self>
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
372 where Self : Sized {
5
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
373 self.mapped(LogItem::new)
0
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
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
376 /// Add timing to the iterator produced by the factory.
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
377 fn timed(self) -> TimingIteratorFactory<Self>
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
378 where Self : Sized {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
379 TimingIteratorFactory(self)
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 value stopping threshold to the iterator produce by the factory
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
383 fn stop_target(self, target : Self::Output) -> ValueIteratorFactory<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 ValueIteratorFactory { base_options : self, target : target }
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 /// Add stall stopping to the iterator produce by the factory
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
390 fn stop_stall(self, stall : Self::Output) -> StallIteratorFactory<Self::Output, Self>
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
391 where Self : Sized,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
392 Self::Output : Num {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
393 StallIteratorFactory { base_options : self, stall : stall }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
394 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
395
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
396 /// Is the iterator quiet, i.e., on-verbose?
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
397 fn is_quiet(&self) -> bool { false }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
398 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
399
5
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
400 /// Options for [`BasicAlgIteratorFactory`].
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
401 ///
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
402 /// Use as:
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
403 /// ```
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
404 /// # use alg_tools::iterate::*;
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
405 /// let iter = AlgIteratorOptions{ max_iter : 10000, .. Default::default() };
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
406 /// ```
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
407 #[derive(Clone, Copy, Debug, Serialize, Deserialize, Eq, PartialEq)]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
408 pub struct AlgIteratorOptions {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
409 /// Maximum number of iterations
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
410 pub max_iter : usize,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
411 /// Number of iterations between verbose iterations that display state.
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
412 pub verbose_iter : Verbose,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
413 /// 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
414 /// `AlgIterator`.
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
415 pub quiet : bool,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
416 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
417
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
418 #[derive(Clone, Copy, Debug, Serialize, Deserialize, Eq, PartialEq)]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
419 pub enum Verbose {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
420 /// Be verbose every $n$ iterations.
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
421 Every(usize),
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
422 /// Be verbose every $n$ iterations and initial $m$ iterations.
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
423 EveryAndInitial{ every : usize, initial : usize },
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
424 /// 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
425 /// $b$ is indicated logarithmic base. So, with $b=10$,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
426 /// * every iteration for first 10 iterations,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
427 /// * every 10 iterations from there on until 100 iterations,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
428 /// * every 100 iteartinos frmo there on until 1000 iterations, etc.
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
429 Logarithmic(usize),
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
430 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
431
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
432 impl Verbose {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
433 /// Indicates whether given iteration number is verbose
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
434 pub fn is_verbose(&self, iter : usize) -> bool {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
435 match self {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
436 &Verbose::Every(every) => {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
437 every != 0 && iter % every == 0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
438 },
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
439 &Verbose::EveryAndInitial{ every, initial } => {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
440 iter <= initial || (every != 0 && iter % every == 0)
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
441 },
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
442 &Verbose::Logarithmic(base) => {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
443 let every = 10usize.pow((iter as float).log(base as float).floor() as u32);
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
444 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 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
447 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
448 }
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 impl Default for AlgIteratorOptions {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
451 fn default() -> AlgIteratorOptions {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
452 AlgIteratorOptions{
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
453 max_iter : 1000,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
454 verbose_iter : Verbose::EveryAndInitial { every : 100, initial : 10 },
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
455 quiet : false
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
456 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
457 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
458 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
459
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
460 /// State of a `BasicAlgIterator`
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
461 #[derive(Clone,Copy,Debug,Serialize,Eq,PartialEq)]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
462 pub struct BasicState {
5
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
463 /// Current iteration
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
464 iter : usize,
5
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
465 /// Whether the iteration is verbose, i.e., results should be displayed.
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
466 /// Requires `calc` to be `true`.
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
467 verbose : bool,
5
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
468 /// Whether results should be calculated.
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
469 calc : bool,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
470 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
471
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
472 /// [`AlgIteratorFactory`] for [`BasicAlgIterator`]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
473 #[derive(Clone,Debug)]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
474 pub struct BasicAlgIteratorFactory<V> {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
475 options : AlgIteratorOptions,
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
476 _phantoms : PhantomData<V>,
0
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
5
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
479 /// The simplest [`AlgIterator`], created by [`BasicAlgIteratorFactory`]
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
480 #[derive(Clone,Debug)]
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
481 pub struct BasicAlgIterator<F, V, E : Error> {
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
482 options : AlgIteratorOptions,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
483 iter : usize,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
484 step_fn : F,
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
485 _phantoms : PhantomData<(V, E)>,
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
486 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
487
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
488 impl AlgIteratorOptions {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
489 /// [`AlgIteratorOptions`] is directly a factory for [`BasicAlgIterator`],
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
490 /// 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
491 /// 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
492 pub fn instantiate<V>(&self) -> BasicAlgIteratorFactory<V> {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
493 BasicAlgIteratorFactory {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
494 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
495 _phantoms : PhantomData
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
496 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
497 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
498 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
499
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
500 impl<V> AlgIteratorFactory<V> for AlgIteratorOptions
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
501 where V : LogRepr {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
502 type State = BasicState;
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
503 type Iter<F, E> = BasicAlgIterator<F, V, E>
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
504 where F : FnMut(&Self::State) -> Step<V, E>,
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
505 E : Error;
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
506 type Output = V;
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
507
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
508 fn prepare<F, E>(self, step_fn : F) -> Self::Iter<F, E>
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
509 where F : FnMut(&Self::State) -> Step<V, E>,
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
510 E : Error {
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
511 BasicAlgIterator{
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
512 options : self,
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
513 iter : 0,
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
514 step_fn,
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;
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
528 type Iter<F, E> = BasicAlgIterator<F, V, E>
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
529 where F : FnMut(&Self::State) -> Step<V, E>,
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
530 E : Error;
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
531 type Output = V;
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
532
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
533 fn prepare<F, E>(self, step_fn : F) -> Self::Iter<F, E>
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
534 where F : FnMut(&Self::State) -> Step<V, E>,
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
535 E : Error {
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
536 BasicAlgIterator {
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
537 options : self.options,
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
538 iter : 0,
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
539 step_fn,
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
540 _phantoms : PhantomData
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
541 }
0
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 #[inline]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
545 fn is_quiet(&self) -> bool {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
546 self.options.quiet
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
547 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
548 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
549
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
550 impl<F, V, E> AlgIterator for BasicAlgIterator<F, V, E>
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
551 where V : LogRepr,
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
552 E : Error,
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
553 F : FnMut(&BasicState) -> Step<V, E> {
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
554 type State = BasicState;
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
555 type Output = V;
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
556 type Err = E;
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
557
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
558 #[inline]
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
559 fn step(&mut self) -> Step<V, E> {
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
560 if self.iter >= self.options.max_iter {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
561 Step::Terminated
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
562 } else {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
563 self.iter += 1;
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
564 let state = self.state();
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
565 let res = (self.step_fn)(&state);
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
566 if let Step::Result(ref val) = res {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
567 if state.verbose && !self.options.quiet {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
568 println!("{}{}/{} {}{}", "".dimmed(),
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
569 state.iter,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
570 self.options.max_iter,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
571 val.logrepr(),
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
572 "".clear());
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 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
575 res
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
576 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
577 }
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 iteration(&self) -> usize {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
581 self.iter
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
582 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
583
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
584 #[inline]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
585 fn state(&self) -> BasicState {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
586 let iter = self.iter;
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
587 let verbose = self.options.verbose_iter.is_verbose(iter);
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
588 BasicState{
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
589 iter : iter,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
590 verbose : verbose,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
591 calc : verbose,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
592 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
593 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
594 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
595
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
596 impl AlgIteratorState for BasicState {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
597 #[inline]
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
598 fn if_verbose<V, E : Error>(&self, mut calc_objective : impl FnMut() -> V) -> Step<V, E> {
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
599 if self.calc {
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
600 Step::Result(calc_objective())
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
601 } else {
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
602 Step::Quiet
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
603 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
604 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
605
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
606 #[inline]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
607 fn iteration(&self) -> usize {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
608 return self.iter;
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
609 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
610 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
611
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
612 //
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
613 // Stall detecting iteration function.
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
614 //
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
615
5
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
616 /// An [`AlgIteratorFactory`] for an [`AlgIterator`] that detects “stall”.
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
617 ///
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
618 /// 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
619 /// [`Step::Result`] iterations, and $θ$ is the provided `stall` parameter.
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
620 #[derive(Clone,Copy,Debug,Serialize,Eq,PartialEq)]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
621 pub struct StallIteratorFactory<U : Num, BaseFactory> {
5
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
622 /// An [`AlgIteratorFactory`] on which to build on
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
623 pub base_options : BaseFactory,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
624 /// Stalling threshold $θ$.
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
625 pub stall : U,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
626 }
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 /// Iterator produced by [`StallIteratorFactory`].
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
629 pub struct StallIterator<U : Num, BaseIterator> {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
630 base_iterator : BaseIterator,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
631 stall : U,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
632 previous_value : Option<U>,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
633 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
634
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
635 impl<V, U, BaseFactory> AlgIteratorFactory<V>
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
636 for StallIteratorFactory<U, BaseFactory>
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
637 where BaseFactory : AlgIteratorFactory<V, Output=U>,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
638 U : SignedNum + PartialOrd {
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
639 type Iter<F, E> = StallIterator<U, BaseFactory::Iter<F, E>>
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
640 where F : FnMut(&Self::State) -> Step<V, E>,
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
641 E : Error;
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
642 type State = BaseFactory::State;
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
643 type Output = BaseFactory::Output;
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
644
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
645 fn prepare<F, E>(self, step_fn : F) -> Self::Iter<F, E>
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
646 where F : FnMut(&Self::State) -> Step<V, E>,
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
647 E : Error {
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
648 StallIterator {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
649 base_iterator : self.base_options.prepare(step_fn),
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
650 stall : self.stall,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
651 previous_value : None,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
652 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
653 }
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 fn is_quiet(&self) -> bool {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
656 self.base_options.is_quiet()
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
657 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
658 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
659
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
660 impl<U, BaseIterator> AlgIterator
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
661 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
662 where BaseIterator : AlgIterator<Output=U>,
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
663 U : SignedNum + PartialOrd {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
664 type State = BaseIterator::State;
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
665 type Output = BaseIterator::Output;
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
666 type Err = BaseIterator::Err;
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
667
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
668 #[inline]
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
669 fn step(&mut self) -> Step<U, Self::Err> {
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
670 match self.base_iterator.step() {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
671 Step::Result(nv) => {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
672 let previous_v = self.previous_value;
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
673 self.previous_value = Some(nv);
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
674 match previous_v {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
675 Some(pv) if (nv - pv).abs() <= self.stall * pv.abs() => Step::Terminated,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
676 _ => Step::Result(nv),
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
677 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
678 },
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
679 val => val,
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
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
683 #[inline]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
684 fn iteration(&self) -> usize {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
685 self.base_iterator.iteration()
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
686 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
687
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
688 #[inline]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
689 fn state(&self) -> Self::State {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
690 self.base_iterator.state()
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
691 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
692 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
693
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
694 /// An [`AlgIteratorFactory`] for an [`AlgIterator`] that detect whether step function
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
695 /// return value is less than `target`, and terminates if it is.
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
696 #[derive(Clone,Copy,Debug,Serialize,Eq,PartialEq)]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
697 pub struct ValueIteratorFactory<U : Num, BaseFactory> {
5
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
698 /// An [`AlgIteratorFactory`] on which to build on
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
699 pub base_options : BaseFactory,
5
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
700 /// Target value
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
701 pub target : U,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
702 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
703
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
704 /// Iterator produced by [`ValueIteratorFactory`].
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
705 pub struct ValueIterator<U : Num, BaseIterator> {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
706 base_iterator : BaseIterator,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
707 target : U,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
708 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
709
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
710 impl<V, U, BaseFactory> AlgIteratorFactory<V>
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
711 for ValueIteratorFactory<U, BaseFactory>
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
712 where BaseFactory : AlgIteratorFactory<V, Output=U>,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
713 U : SignedNum + PartialOrd {
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
714 type Iter<F, E> = ValueIterator<U, BaseFactory::Iter<F, E>>
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
715 where F : FnMut(&Self::State) -> Step<V, E>,
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
716 E : Error;
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
717 type State = BaseFactory::State;
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
718 type Output = BaseFactory::Output;
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
719
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
720 fn prepare<F, E>(self, step_fn : F) -> Self::Iter<F, E>
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
721 where F : FnMut(&Self::State) -> Step<V, E>,
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
722 E : Error {
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
723 ValueIterator {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
724 base_iterator : self.base_options.prepare(step_fn),
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
725 target : self.target
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
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
729 fn is_quiet(&self) -> bool {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
730 self.base_options.is_quiet()
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
731 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
732 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
733
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
734 impl<U, BaseIterator> AlgIterator
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
735 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
736 where BaseIterator : AlgIterator<Output=U>,
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
737 U : SignedNum + PartialOrd {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
738 type State = BaseIterator::State;
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
739 type Output = BaseIterator::Output;
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
740 type Err = BaseIterator::Err;
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
741
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
742 #[inline]
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
743 fn step(&mut self) -> Step<U, Self::Err> {
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
744 match self.base_iterator.step() {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
745 Step::Result(v) => {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
746 if v <= self.target {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
747 Step::Terminated
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
748 } else {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
749 Step::Result(v)
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
750 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
751 },
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
752 val => val,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
753 }
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 #[inline]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
757 fn iteration(&self) -> usize {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
758 self.base_iterator.iteration()
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
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
761 #[inline]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
762 fn state(&self) -> Self::State {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
763 self.base_iterator.state()
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
764 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
765 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
766
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
767 //
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
768 // Logging iterator
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 /// [`AlgIteratorFactory`] for a logging [`AlgIterator`].
5
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
772 ///
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
773 /// Typically produced with [`AlgIteratorFactory::into_log`].
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
774 /// The `Output` of the corresponding [`LoggingIterator`] is `()`:
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
775 #[derive(Debug)]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
776 pub struct LoggingIteratorFactory<'log, U, BaseFactory> {
5
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
777 /// Base [`AlgIteratorFactory`] on which to build
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
778 base_options : BaseFactory,
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
779 /// The `Logger` to use.
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
780 logger : &'log mut Logger<U>,
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
781 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
782
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
783 /// Iterator produced by `LoggingIteratorFactory`.
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
784 pub struct LoggingIterator<'log, U, BaseIterator> {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
785 base_iterator : BaseIterator,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
786 logger : &'log mut Logger<U>,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
787 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
788
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
789
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
790 impl<'log, V, BaseFactory> AlgIteratorFactory<V>
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
791 for LoggingIteratorFactory<'log, BaseFactory::Output, BaseFactory>
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
792 where BaseFactory : AlgIteratorFactory<V>,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
793 BaseFactory::Output : 'log {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
794 type State = BaseFactory::State;
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
795 type Iter<F, E> = LoggingIterator<'log, BaseFactory::Output, BaseFactory::Iter<F, E>>
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
796 where F : FnMut(&Self::State) -> Step<V, E>,
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
797 E : Error;
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
798 type Output = ();
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
799
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
800 fn prepare<F, E>(self, step_fn : F) -> Self::Iter<F, E>
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
801 where F : FnMut(&Self::State) -> Step<V, E>,
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
802 E : Error {
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
803 LoggingIterator {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
804 base_iterator : self.base_options.prepare(step_fn),
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 = ();
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
821 type Err = BaseIterator::Err;
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]
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
824 fn step(&mut self) -> Step<Self::Output, Self::Err> {
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
825 match self.base_iterator.step() {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
826 Step::Result(v) => {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
827 self.logger.log(v);
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
828 Step::Quiet
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
829 },
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
830 Step::Quiet => Step::Quiet,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
831 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
832 Step::Failure(e) => Step::Failure(e),
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
833 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
834 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
835
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
836 #[inline]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
837 fn iteration(&self) -> usize {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
838 self.base_iterator.iteration()
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 state(&self) -> Self::State {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
843 self.base_iterator.state()
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
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
847 /// This [`AlgIteratorFactory`] allows output mapping.
5
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
848 ///
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
849 /// Typically produced with [`AlgIteratorFactory::mapped`].
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
850 #[derive(Debug)]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
851 pub struct MappingIteratorFactory<G, BaseFactory> {
5
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
852 /// Base [`AlgIteratorFactory`] on which to build
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
853 base_options : BaseFactory,
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
854 /// 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
855 /// 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
856 map : G,
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
857 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
858
5
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
859 /// [`AlgIterator`] produced by [`MappingIteratorFactory`].
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
860 pub struct MappingIterator<G, BaseIterator> {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
861 base_iterator : BaseIterator,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
862 map : G,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
863 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
864
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
865
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
866 impl<V, U, G, BaseFactory> AlgIteratorFactory<V>
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
867 for MappingIteratorFactory<G, BaseFactory>
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
868 where BaseFactory : AlgIteratorFactory<V>,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
869 G : Fn(usize, BaseFactory::Output) -> U {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
870 type State = BaseFactory::State;
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
871 type Iter<F, E> = MappingIterator<G, BaseFactory::Iter<F, E>>
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
872 where F : FnMut(&Self::State) -> Step<V, E>,
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
873 E : Error;
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
874 type Output = U;
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
875
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
876 fn prepare<F, E>(self, step_fn : F) -> Self::Iter<F, E>
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
877 where F : FnMut(&Self::State) -> Step<V, E>,
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
878 E : Error {
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
879 MappingIterator {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
880 base_iterator : self.base_options.prepare(step_fn),
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
881 map : self.map
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
882 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
883 }
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 #[inline]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
886 fn is_quiet(&self) -> bool {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
887 self.base_options.is_quiet()
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
888 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
889 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
890
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
891 impl<U, G, BaseIterator> AlgIterator
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
892 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
893 where BaseIterator : AlgIterator,
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
894 G : Fn(usize, BaseIterator::Output) -> U {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
895 type State = BaseIterator::State;
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
896 type Output = U;
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
897 type Err = BaseIterator::Err;
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
898
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
899 #[inline]
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
900 fn step(&mut self) -> Step<Self::Output, Self::Err> {
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
901 match self.base_iterator.step() {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
902 Step::Result(v) => Step::Result((self.map)(self.iteration(), v)),
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
903 Step::Quiet => Step::Quiet,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
904 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
905 Step::Failure(e) => Step::Failure(e),
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
906 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
907 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
908
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
909 #[inline]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
910 fn iteration(&self) -> usize {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
911 self.base_iterator.iteration()
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 #[inline]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
915 fn state(&self) -> Self::State {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
916 self.base_iterator.state()
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
917 }
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 //
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
921 // Timing iterator
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
922 //
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
923
5
59dc4c5883f4 Improve documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
924 /// 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
925 #[derive(Debug)]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
926 pub struct TimingIteratorFactory<BaseFactory>(pub BaseFactory);
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
927
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
928 /// Iterator produced by [`TimingIteratorFactory`]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
929 #[derive(Debug)]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
930 pub struct TimingIterator<BaseIterator> {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
931 base_iterator : BaseIterator,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
932 start_time : ProcessTime,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
933 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
934
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
935 /// Data `U` with production time attached
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
936 #[derive(Copy, Clone, Debug, Serialize)]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
937 pub struct Timed<U> {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
938 pub cpu_time : Duration,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
939 //#[serde(flatten)]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
940 pub data : U
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
941 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
942
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
943 impl<T> LogRepr for Timed<T> where T : LogRepr {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
944 fn logrepr(&self) -> ColoredString {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
945 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
946 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
947 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
948
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
949
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
950 impl<V, BaseFactory> AlgIteratorFactory<V>
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
951 for TimingIteratorFactory<BaseFactory>
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
952 where BaseFactory : AlgIteratorFactory<V> {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
953 type State = BaseFactory::State;
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
954 type Iter<F, E> = TimingIterator<BaseFactory::Iter<F, E>>
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
955 where F : FnMut(&Self::State) -> Step<V, E>,
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
956 E : Error;
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
957 type Output = Timed<BaseFactory::Output>;
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
958
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
959 fn prepare<F, E>(self, step_fn : F) -> Self::Iter<F, E>
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
960 where F : FnMut(&Self::State) -> Step<V, E>,
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
961 E : Error {
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
962 TimingIterator {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
963 base_iterator : self.0.prepare(step_fn),
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
964 start_time : ProcessTime::now()
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
965 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
966 }
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 #[inline]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
969 fn is_quiet(&self) -> bool {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
970 self.0.is_quiet()
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
971 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
972 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
973
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
974 impl<BaseIterator> AlgIterator
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
975 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
976 where BaseIterator : AlgIterator {
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
977 type State = BaseIterator::State;
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
978 type Output = Timed<BaseIterator::Output>;
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
979 type Err = BaseIterator::Err;
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
980
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
981 #[inline]
3
20db884b7028 Allow step closure of AlgIterators to indicate succesfull termination or failure.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
982 fn step(&mut self) -> Step<Self::Output, Self::Err> {
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
983 match self.base_iterator.step() {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
984 Step::Result(data) => {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
985 Step::Result(Timed{
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
986 cpu_time : self.start_time.elapsed(),
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
987 data
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
988 })
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
989 },
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
990 Step::Quiet => Step::Quiet,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
991 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
992 Step::Failure(e) => Step::Failure(e),
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
993 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
994 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
995
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
996 #[inline]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
997 fn iteration(&self) -> usize {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
998 self.base_iterator.iteration()
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
999 }
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 #[inline]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1002 fn state(&self) -> Self::State {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1003 self.base_iterator.state()
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1004 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1005 }
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 // Tests
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1009 //
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1010
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1011 #[cfg(test)]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1012 mod tests {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1013 use super::*;
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1014 use crate::logger::Logger;
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1015 #[test]
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1016 fn iteration() {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1017 let options = AlgIteratorOptions{
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1018 max_iter : 10,
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1019 verbose_iter : Verbose::Every(3),
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1020 .. Default::default()
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1021 };
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1022
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1023 {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1024 let mut start = 1 as int;
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1025 options.iterate(|state| {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1026 start = start * 2;
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1027 state.if_verbose(|| start)
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1028 });
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1029 assert_eq!(start, (2 as int).pow(10));
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1030 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1031
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1032 {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1033 let mut start = 1 as int;
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1034 let mut log = Logger::new();
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1035 let factory = options.instantiate()
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1036 .with_iteration_number()
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1037 .into_log(&mut log);
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1038 factory.iterate(|state| {
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1039 start = start * 2;
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1040 state.if_verbose(|| start)
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1041 });
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1042 assert_eq!(start, (2 as int).pow(10));
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1043 assert_eq!(log.data()
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1044 .iter()
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1045 .map(|LogItem{ data : v, iter : _ }| v.clone())
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1046 .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
1047 (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
1048 .skip(2)
df3901ec2f5d Fix some unit tests after fundamental changes that made them invalid
Tuomo Valkonen <tuomov@iki.fi>
parents: 0
diff changeset
1049 .step_by(3)
0
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1050 .collect::<Vec<int>>())
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1051 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1052 }
9f27689eb130 Initialise new clean repository
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1053 }

mercurial