aGrUM  0.20.3
a C++ library for (probabilistic) graphical models
approximationScheme_inl.h
Go to the documentation of this file.
1 /**
2  *
3  * Copyright (c) 2005-2021 by Pierre-Henri WUILLEMIN(@LIP6) & Christophe GONZALES(@AMU)
4  * info_at_agrum_dot_org
5  *
6  * This library is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this library. If not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 
22 /**
23  * @file
24  * @brief Inline implementatioh of gum::ApproximationSettings.
25  *
26  * ApproximationSettings provides as well 2 signals :
27  * - onProgress(int pourcent,double error)
28  * - onStop(std::string message)
29  * @see gum::ApproximationListener for dedicated listener.
30  *
31  * @author Pierre-Henri WUILLEMIN(@LIP6)
32  */
33 
34 #include <agrum/agrum.h>
35 // To help IDE parser
36 #include <agrum/tools/core/approximations/approximationScheme.h>
37 
38 namespace gum {
39 
40  // Given that we approximate f(t), stopping criterion on |f(t+1)-f(t)| If
41  // the criterion was disabled it will be enabled
43  if (eps < 0.) { GUM_ERROR(OutOfLowerBound, "eps should be >=0") }
44 
45  eps_ = eps;
46  enabled_eps_ = true;
47  }
48 
49  // Get the value of epsilon
50  INLINE double ApproximationScheme::epsilon() const { return eps_; }
51 
52  // Disable stopping criterion on epsilon
54 
55  // Enable stopping criterion on epsilon
57 
58  // @return true if stopping criterion on epsilon is enabled, false
59  // otherwise
61 
62  // Given that we approximate f(t), stopping criterion on d/dt(|f(t+1)-f(t)|)
64  if (rate < 0) { GUM_ERROR(OutOfLowerBound, "rate should be >=0") }
65 
67  enabled_min_rate_eps_ = true;
68  }
69 
70  // Get the value of the minimal epsilon rate
72 
73  // Disable stopping criterion on epsilon rate
75 
76  // Enable stopping criterion on epsilon rate
78 
79  // @return true if stopping criterion on epsilon rate is enabled, false
80  // otherwise
82 
83  // stopping criterion on number of iterations
85  if (max < 1) { GUM_ERROR(OutOfLowerBound, "max should be >=1") }
86  max_iter_ = max;
87  enabled_max_iter_ = true;
88  }
89 
90  // @return the criterion on number of iterations
91  INLINE Size ApproximationScheme::maxIter() const { return max_iter_; }
92 
93  // Disable stopping criterion on max iterations
95 
96  // Enable stopping criterion on max iterations
98 
99  // @return true if stopping criterion on max iterations is enabled, false
100  // otherwise
102 
103  // stopping criterion on timeout (in seconds)
104  // If the criterion was disabled it will be enabled
106  if (timeout <= 0.) { GUM_ERROR(OutOfLowerBound, "timeout should be >0.") }
107  max_time_ = timeout;
108  enabled_max_time_ = true;
109  }
110 
111  // returns the timeout (in seconds)
112  INLINE double ApproximationScheme::maxTime() const { return max_time_; }
113 
114  // get the current running time in second (double)
115  INLINE double ApproximationScheme::currentTime() const { return timer_.step(); }
116 
117  // Disable stopping criterion on timeout
119 
120  // Enable stopping criterion on timeout
122 
123  // @return true if stopping criterion on timeout is enabled, false
124  // otherwise
126 
127  // how many samples between 2 stopping isEnableds
129  if (p < 1) { GUM_ERROR(OutOfLowerBound, "p should be >=1") }
130 
131  period_size_ = p;
132  }
133 
135 
136  // verbosity
138 
139  INLINE bool ApproximationScheme::verbosity() const { return verbosity_; }
140 
141  // history
144  return current_state_;
145  }
146 
147  // @throw OperationNotAllowed if scheme not performed
150  GUM_ERROR(OperationNotAllowed, "state of the approximation scheme is undefined")
151  }
152 
153  return current_step_;
154  }
155 
156  // @throw OperationNotAllowed if scheme not performed or verbosity=false
157  INLINE const std::vector< double >& ApproximationScheme::history() const {
159  GUM_ERROR(OperationNotAllowed, "state of the approximation scheme is udefined")
160  }
161 
162  if (verbosity() == false) { GUM_ERROR(OperationNotAllowed, "No history when verbosity=false") }
163 
164  return history_;
165  }
166 
167  // initialise the scheme
170  current_step_ = 0;
172  history_.clear();
173  timer_.reset();
174  }
175 
176  // @return true if we are at the beginning of a period (compute error is
177  // mandatory)
179  if (current_step_ < burn_in_) { return false; }
180 
181  if (period_size_ == 1) { return true; }
182 
183  return ((current_step_ - burn_in_) % period_size_ == 0);
184  }
185 
186  // update the scheme w.r.t the new error and incr steps
188  current_step_ += incr;
189  }
190 
192  if (burn_in_ > current_step_) {
193  return burn_in_ - current_step_;
194  } else {
195  return 0;
196  }
197  }
198 
199  // stop approximation scheme by user request.
203  }
204  }
205 
206  // update the scheme w.r.t the new error. Test the stopping criterions that
207  // are enabled
209  // For coherence, we fix the time used in the method
210 
211  double timer_step = timer_.step();
212 
213  if (enabled_max_time_) {
214  if (timer_step > max_time_) {
216  return false;
217  }
218  }
219 
220  if (!startOfPeriod()) { return true; }
221 
224  "state of the approximation scheme is not correct : "
226  }
227 
228  if (verbosity()) { history_.push_back(error); }
229 
230  if (enabled_max_iter_) {
231  if (current_step_ > max_iter_) {
233  return false;
234  }
235  }
236 
238  current_epsilon_ = error; // eps rate isEnabled needs it so affectation was
239  // moved from eps isEnabled below
240 
241  if (enabled_eps_) {
242  if (current_epsilon_ <= eps_) {
244  return false;
245  }
246  }
247 
248  if (last_epsilon_ >= 0.) {
249  if (current_epsilon_ > .0) {
250  // ! current_epsilon_ can be 0. AND epsilon
251  // isEnabled can be disabled !
253  }
254  // limit with current eps ---> 0 is | 1 - ( last_eps / 0 ) | --->
255  // infinity the else means a return false if we isEnabled the rate below,
256  // as we would have returned false if epsilon isEnabled was enabled
257  else {
259  }
260 
261  if (enabled_min_rate_eps_) {
262  if (current_rate_ <= min_rate_eps_) {
264  return false;
265  }
266  }
267  }
268 
270  if (onProgress.hasListener()) {
272  }
273 
274  return true;
275  } else {
276  return false;
277  }
278  }
279 
281  if (new_state == ApproximationSchemeSTATE::Continue) { return; }
282 
283  if (new_state == ApproximationSchemeSTATE::Undefined) { return; }
284 
286  timer_.pause();
287 
289  }
290 
291 } // namespace gum
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:643