aGrUM 2.3.2
a C++ library for (probabilistic) graphical models
approximationScheme_inl.h
Go to the documentation of this file.
1/****************************************************************************
2 * This file is part of the aGrUM/pyAgrum library. *
3 * *
4 * Copyright (c) 2005-2025 by *
5 * - Pierre-Henri WUILLEMIN(_at_LIP6) *
6 * - Christophe GONZALES(_at_AMU) *
7 * *
8 * The aGrUM/pyAgrum library is free software; you can redistribute it *
9 * and/or modify it under the terms of either : *
10 * *
11 * - the GNU Lesser General Public License as published by *
12 * the Free Software Foundation, either version 3 of the License, *
13 * or (at your option) any later version, *
14 * - the MIT license (MIT), *
15 * - or both in dual license, as here. *
16 * *
17 * (see https://agrum.gitlab.io/articles/dual-licenses-lgplv3mit.html) *
18 * *
19 * This aGrUM/pyAgrum library is distributed in the hope that it will be *
20 * useful, but WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
21 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES MERCHANTABILITY or FITNESS *
22 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
25 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR *
26 * OTHER DEALINGS IN THE SOFTWARE. *
27 * *
28 * See LICENCES for more details. *
29 * *
30 * SPDX-FileCopyrightText: Copyright 2005-2025 *
31 * - Pierre-Henri WUILLEMIN(_at_LIP6) *
32 * - Christophe GONZALES(_at_AMU) *
33 * SPDX-License-Identifier: LGPL-3.0-or-later OR MIT *
34 * *
35 * Contact : info_at_agrum_dot_org *
36 * homepage : http://agrum.gitlab.io *
37 * gitlab : https://gitlab.com/agrumery/agrum *
38 * *
39 ****************************************************************************/
40#pragma once
41
42
54
55#include <agrum/agrum.h>
56// To help IDE parser
58
59namespace gum {
60
61 // Given that we approximate f(t), stopping criterion on |f(t+1)-f(t)| If
62 // the criterion was disabled it will be enabled
63 INLINE void ApproximationScheme::setEpsilon(double eps) {
64 if (eps < 0.) { GUM_ERROR(OutOfBounds, "eps should be >=0") }
65
66 eps_ = eps;
67 enabled_eps_ = true;
68 }
69
70 // Get the value of epsilon
71 INLINE double ApproximationScheme::epsilon() const { return eps_; }
72
73 // Disable stopping criterion on epsilon
75
76 // Enable stopping criterion on epsilon
78
79 // @return true if stopping criterion on epsilon is enabled, false
80 // otherwise
82
83 // Given that we approximate f(t), stopping criterion on d/dt(|f(t+1)-f(t)|)
84 INLINE void ApproximationScheme::setMinEpsilonRate(double rate) {
85 if (rate < 0) { GUM_ERROR(OutOfBounds, "rate should be >=0") }
86
87 min_rate_eps_ = rate;
89 }
90
91 // Get the value of the minimal epsilon rate
92 INLINE double ApproximationScheme::minEpsilonRate() const { return min_rate_eps_; }
93
94 // Disable stopping criterion on epsilon rate
96
97 // Enable stopping criterion on epsilon rate
99
100 // @return true if stopping criterion on epsilon rate is enabled, false
101 // otherwise
103
104 // stopping criterion on number of iterations
106 if (max < 1) { GUM_ERROR(OutOfBounds, "max should be >=1") }
107 max_iter_ = max;
108 enabled_max_iter_ = true;
109 }
110
111 // @return the criterion on number of iterations
112 INLINE Size ApproximationScheme::maxIter() const { return max_iter_; }
113
114 // Disable stopping criterion on max iterations
116
117 // Enable stopping criterion on max iterations
119
120 // @return true if stopping criterion on max iterations is enabled, false
121 // otherwise
123
124 // stopping criterion on timeout (in seconds)
125 // If the criterion was disabled it will be enabled
126 INLINE void ApproximationScheme::setMaxTime(double timeout) {
127 if (timeout <= 0.) { GUM_ERROR(OutOfBounds, "timeout should be >0.") }
128 max_time_ = timeout;
129 enabled_max_time_ = true;
130 }
131
132 // returns the timeout (in seconds)
133 INLINE double ApproximationScheme::maxTime() const { return max_time_; }
134
135 // get the current running time in second (double)
136 INLINE double ApproximationScheme::currentTime() const { return timer_.step(); }
137
138 // Disable stopping criterion on timeout
140
141 // Enable stopping criterion on timeout
143
144 // @return true if stopping criterion on timeout is enabled, false
145 // otherwise
147
148 // how many samples between 2 stopping isEnableds
150 if (p < 1) { GUM_ERROR(OutOfBounds, "p should be >=1") }
151
152 period_size_ = p;
154
156
157 // verbosity
159
160 INLINE bool ApproximationScheme::verbosity() const { return verbosity_; }
161
162 // history
167
168 // @throw OperationNotAllowed if scheme not performed
171 GUM_ERROR(OperationNotAllowed, "state of the approximation scheme is undefined")
172 }
173
174 return current_step_;
175 }
176
177 // @throw OperationNotAllowed if scheme not performed or verbosity=false
178 INLINE const std::vector< double >& ApproximationScheme::history() const {
180 GUM_ERROR(OperationNotAllowed, "state of the approximation scheme is udefined")
181 }
182
183 if (!verbosity()) GUM_ERROR(OperationNotAllowed, "No history when verbosity=false")
184
185 return history_;
186 }
187
188 // initialise the scheme
191 current_step_ = 0;
193 history_.clear();
194 timer_.reset();
195 }
196
197 // @return true if we are at the beginning of a period (compute error is
198 // mandatory)
200 if (current_step_ < burn_in_) { return false; }
202 if (period_size_ == 1) { return true; }
203
204 return ((current_step_ - burn_in_) % period_size_ == 0);
205 }
206
207 // update the scheme w.r.t the new error and incr steps
208 INLINE void ApproximationScheme::updateApproximationScheme(unsigned int incr) {
209 current_step_ += incr;
210 }
213 if (burn_in_ > current_step_) {
214 return burn_in_ - current_step_;
215 } else {
216 return 0;
218 }
219
220 // stop approximation scheme by user request.
224 }
225 }
226
227 // update the scheme w.r.t the new error. Test the stopping criterions that
228 // are enabled
230 // For coherence, we fix the time used in the method
231
232 double timer_step = timer_.step();
233
234 if (enabled_max_time_) {
235 if (timer_step > max_time_) {
237 return false;
238 }
239 }
240
241 if (!startOfPeriod()) { return true; }
242
244 GUM_ERROR(
246 "state of the approximation scheme is not correct : " << messageApproximationScheme());
247 }
248
249 if (verbosity()) { history_.push_back(error); }
250
252 if (current_step_ > max_iter_) {
254 return false;
255 }
256 }
259 current_epsilon_ = error; // eps rate isEnabled needs it so affectation was
260 // moved from eps isEnabled below
261
262 if (enabled_eps_) {
265 return false;
266 }
267 }
269 if (last_epsilon_ >= 0.) {
270 if (current_epsilon_ > .0) {
271 // ! current_epsilon_ can be 0. AND epsilon
272 // isEnabled can be disabled !
274 }
275 // limit with current eps ---> 0 is | 1 - ( last_eps / 0 ) | --->
276 // infinity the else means a return false if we isEnabled the rate below,
277 // as we would have returned false if epsilon isEnabled was enabled
278 else {
280 }
281
285 return false;
286 }
287 }
288 }
291 if (onProgress.hasListener()) {
293 }
294
295 return true;
296 } else {
297 return false;
298 }
299 }
300
302 if (new_state == ApproximationSchemeSTATE::Continue) { return; }
303
304 if (new_state == ApproximationSchemeSTATE::Undefined) { return; }
305
306 current_state_ = new_state;
307 timer_.pause();
308
309 if (onStop.hasListener()) { GUM_EMIT1(onStop, messageApproximationScheme()); }
310 }
311
312} // namespace gum
This file contains general scheme for iteratively convergent algorithms.
Size remainingBurnIn() const
Returns the remaining burn in.
void updateApproximationScheme(unsigned int incr=1)
Update the scheme w.r.t the new error and increment steps.
Size current_step_
The current step.
double current_epsilon_
Current epsilon.
bool isEnabledEpsilon() const override
Returns true if stopping criterion on epsilon is enabled, false otherwise.
double eps_
Threshold for convergence.
void setMaxIter(Size max) override
Stopping criterion on number of iterations.
void disableMaxTime() override
Disable stopping criterion on timeout.
void setMaxTime(double timeout) override
Stopping criterion on timeout.
void enableMaxIter() override
Enable stopping criterion on max iterations.
double minEpsilonRate() const override
Returns the value of the minimal epsilon rate.
void setMinEpsilonRate(double rate) override
Given that we approximate f(t), stopping criterion on d/dt(|f(t+1)-f(t)|).
void disableEpsilon() override
Disable stopping criterion on epsilon.
bool enabled_max_time_
If true, the timeout is enabled.
Size max_iter_
The maximum iterations.
bool enabled_eps_
If true, the threshold convergence is enabled.
ApproximationSchemeSTATE current_state_
The current state.
double min_rate_eps_
Threshold for the epsilon rate.
double epsilon() const override
Returns the value of epsilon.
void setPeriodSize(Size p) override
How many samples between two stopping is enable.
bool isEnabledMaxTime() const override
Returns true if stopping criterion on timeout is enabled, false otherwise.
double current_rate_
Current rate.
ApproximationSchemeSTATE stateApproximationScheme() const override
Returns the approximation scheme state.
void enableEpsilon() override
Enable stopping criterion on epsilon.
Size period_size_
Checking criteria frequency.
double currentTime() const override
Returns the current running time in second.
bool isEnabledMinEpsilonRate() const override
Returns true if stopping criterion on epsilon rate is enabled, false otherwise.
bool startOfPeriod() const
Returns true if we are at the beginning of a period (compute error is mandatory).
bool enabled_max_iter_
If true, the maximum iterations stopping criterion is enabled.
double maxTime() const override
Returns the timeout (in seconds).
void disableMinEpsilonRate() override
Disable stopping criterion on epsilon rate.
Size periodSize() const override
Returns the period size.
void enableMaxTime() override
Enable stopping criterion on timeout.
ApproximationScheme(bool verbosity=false)
void initApproximationScheme()
Initialise the scheme.
Size nbrIterations() const override
Returns the number of iterations.
const std::vector< double > & history() const override
Returns the scheme history.
void stopScheme_(ApproximationSchemeSTATE new_state)
Stop the scheme given a new state.
Size maxIter() const override
Returns the criterion on number of iterations.
void stopApproximationScheme()
Stop the approximation scheme.
void enableMinEpsilonRate() override
Enable stopping criterion on epsilon rate.
bool verbosity() const override
Returns true if verbosity is enabled.
bool isEnabledMaxIter() const override
Returns true if stopping criterion on max iterations is enabled, false otherwise.
bool continueApproximationScheme(double error)
Update the scheme w.r.t the new error.
void disableMaxIter() override
Disable stopping criterion on max iterations.
Size burn_in_
Number of iterations before checking stopping criteria.
void setVerbosity(bool v) override
Set the verbosity on (true) or off (false).
bool enabled_min_rate_eps_
If true, the minimal threshold for epsilon rate is enabled.
void setEpsilon(double eps) override
Given that we approximate f(t), stopping criterion on |f(t+1)-f(t)|.
ApproximationSchemeSTATE
The different state of an approximation scheme.
std::string messageApproximationScheme() const
Returns the approximation scheme message.
Exception : operation not allowed.
Exception : out of bound.
#define GUM_ERROR(type, msg)
Definition exceptions.h:72
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Definition types.h:74
gum is the global namespace for all aGrUM entities
Definition agrum.h:46
#define GUM_EMIT1(signal, arg1)
Definition signaler1.h:61
#define GUM_EMIT3(signal, arg1, arg2, arg3)
Definition signaler3.h:61