conflux/core/
state.rs

1use crate::core::FixedPointProblem;
2use instant;
3use num::traits::float::Float;
4use paste::item;
5use serde::{Deserialize, Serialize};
6
7#[derive(Clone, Debug, Serialize, Deserialize)]
8/// Struct to hold the iteration state
9pub struct State<O: FixedPointProblem> {
10    /// Current parameter vector
11    pub param: O::Param,
12    /// Previous parameter vector
13    pub prev_param: O::Param,
14    /// Current best parameter vector
15    pub best_param: O::Param,
16    /// Previous best parameter vector
17    pub prev_best_param: O::Param,
18    /// Current cost function
19    pub cost: O::Float,
20    /// Previous cost
21    pub prev_cost: O::Float,
22    /// Current best cost
23    pub best_cost: O::Float,
24    /// Previous best cost
25    pub prev_best_cost: O::Float,
26    /// Current iteration
27    pub iter: u64,
28    /// Iteration number of last best cost
29    pub last_best_iter: u64,
30    /// Maximum number of iterations
31    pub max_iters: u64,
32    /// Time required as yet
33    pub time: Option<instant::Duration>,
34    /// Termination reason
35    pub termination_reason: TerminationReason,
36}
37
38// macro_rules! setter {
39//     ($name:ident, $type:ty, $doc:tt) => {
40//         #[doc=$doc]
41//         pub fn $name(&mut self, $name: $type) -> &mut Self {
42//             self.$name = $name;
43//             self
44//         }
45//     };
46// }
47
48macro_rules! getter {
49    ($name:ident, $type:ty, $doc:tt) => {
50        item! {
51            #[doc=$doc]
52            pub fn [<get_ $name>](&self) -> $type {
53                self.$name.clone()
54            }
55        }
56    };
57}
58
59macro_rules! ogetter {
60    ($name:ident, $type:ty, $doc:tt) => {
61        item! {
62            #[doc=$doc]
63            pub fn [<get_ $name>](&self) -> Option<$type> {
64                self.$name.clone()
65            }
66        }
67    };
68}
69
70impl<O: FixedPointProblem> State<O> {
71    /// Generate a new initial State
72    pub fn new(param: O::Param) -> Self {
73        State {
74            param: param.clone(),
75            prev_param: param.clone(),
76            best_param: param.clone(),
77            prev_best_param: param,
78            cost: O::Float::infinity(),
79            prev_cost: O::Float::infinity(),
80            best_cost: O::Float::infinity(),
81            prev_best_cost: O::Float::infinity(),
82            iter: 0,
83            last_best_iter: 0,
84            max_iters: std::u64::MAX,
85            time: Some(instant::Duration::new(0, 0)),
86            termination_reason: TerminationReason::NotTerminated,
87        }
88    }
89
90    /// Verify whether the solution has terminated
91    pub fn terminated(&self) -> bool {
92        match self.termination_reason {
93            TerminationReason::NotTerminated => false,
94            TerminationReason::ToleranceBeaten => true,
95            TerminationReason::HitMaxIterations => true,
96        }
97    }
98
99    /// Set the termination reason
100    pub fn termination_reason(&mut self, reason: TerminationReason) {
101        self.termination_reason = reason;
102    }
103
104    getter!(param, O::Param, "Returns current parameter vector");
105}
106
107#[derive(Clone, Debug, Serialize, Deserialize)]
108/// Enum for termination conditions
109pub enum TerminationReason {
110    /// The iteration is in progress
111    NotTerminated,
112    /// The iteration has converged
113    ToleranceBeaten,
114    /// The maximum iterations have been reached
115    HitMaxIterations,
116}
117
118#[derive(Clone, Debug, Default)]
119/// Struct for the output of a mixing operation
120pub struct IterData<P: FixedPointProblem> {
121    /// The parameter at the current step
122    param: Option<P::Param>,
123    /// The associated cost ||f(x) - x||
124    cost: Option<P::Float>,
125}
126
127impl<P: FixedPointProblem> IterData<P> {
128    /// Creates a new iterdata struct
129    pub fn new() -> Self {
130        IterData {
131            param: None,
132            cost: None,
133        }
134    }
135
136    /// Factory method to set 'param' field
137    pub fn param(mut self, param: P::Param) -> Self {
138        self.param = Some(param);
139        self
140    }
141
142    /// Factory method to set 'cost' field
143    pub fn cost(mut self, cost: P::Float) -> Self {
144        self.cost = Some(cost);
145        self
146    }
147
148    ogetter!(param, P::Param, "Returns current parameter vector");
149    ogetter!(cost, P::Float, "Returns current cost");
150}