Event.h
1 /*
2  * Medical Image Registration ToolKit (MIRTK)
3  *
4  * Copyright 2013-2015 Imperial College London
5  * Copyright 2013-2015 Andreas Schuh
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 
20 #ifndef MIRTK_Event_H
21 #define MIRTK_Event_H
22 
23 #include "mirtk/Stream.h"
24 
25 #include <functional>
26 
27 
28 namespace mirtk {
29 
30 
31 /// Events that can be observed
32 enum Event
33 {
34  // Generic
35  AnyEvent, ///< Any event
36  ModifiedEvent, ///< Observable has modified state/parameters
37  StatusEvent, ///< Status message given as event data (const char *)
38  LogEvent, ///< Log message given as event data (const char *)
39  InitEvent, ///< Before initialization of filter execution
40  StartEvent, ///< Start of filter execution (after initialization)
41  RestartEvent, ///< Restart of filter execution
42  EndEvent, ///< End of filter execution (before finalization)
43  FinishEvent, ///< After finalization of filter execution
44  IterationEvent, ///< Iteration with line search about to start
45  IterationStartEvent, ///< Iteration started
46  IterationEndEvent, ///< Iteration finished
47  // Observable
48  RegisteredEvent, ///< Observer has been registered
49  UnregisteredEvent, ///< Observer has been unregistered
50  // LineSearch
51  LineSearchStartEvent, ///< Line search started
52  LineSearchIterationStartEvent, ///< Line search iteration
53  LineSearchIterationEndEvent, ///< Line search iteration
54  LineSearchEndEvent, ///< Line search finished
55  AcceptedStepEvent, ///< Accepted objective function value
56  ///< Event data is the new value as double
57  RejectedStepEvent ///< Rejected objective function value
58  ///< Event data is the rejected value as double
59 };
60 
61 
62 /// Data of IterationStartEvent and IterationEndEvent
63 ///
64 /// This event data structure can further be used as iteration counter
65 /// directly to avoid the need for unnecessary duplicate counter.
66 ///
67 /// \code
68 /// irtkIteration iter(0, 10);
69 /// while (iter.Next()) {
70 /// Broadcast(IterationEvent, &iter);
71 /// // ...
72 /// }
73 /// \endcode
74 struct Iteration
75 {
76  int _Iter; ///< Iteration counter
77  int _Begin; ///< Start value of iteration counter
78  int _End; ///< End value of iteration counter
79  int _Inc; ///< Increment after each iteration
80 
81  Iteration() : _Iter(0), _Begin(0), _End(1), _Inc(1) {}
82 
83  Iteration(int b, int e, int s = 1)
84  : _Iter(b), _Begin(b), _End(e), _Inc((_End >= _Begin ? 1 : -1) * (s < 0 ? -s : s))
85  {
86  if (_Inc == 0) {
87  cerr << "Iteration::Iteration: Invalid increment value" << endl;
88  exit(1);
89  }
90  }
91 
92  bool Start() const { return _Iter == _Begin; }
93  bool End() const { return _Iter == _End; }
94  int Total() const { return (_End - _Begin) / _Inc; }
95  int Count() const { return (_Iter - _Begin) / _Inc; }
96  int Iter() const { return _Iter; }
97  void Reset() { _Iter = _Begin; }
98  void Break() { _Iter = _End; }
99 
100  int operator ++()
101  {
102  _Iter += _Inc;
103  if (_Inc > 0) {
104  if (_Iter > _End) _Iter = _End;
105  } else {
106  if (_Iter < _End) _Iter = _End;
107  }
108  return _Iter;
109  }
110 
111  int operator --()
112  {
113  _Iter -= _Inc;
114  if (_Inc > 0) {
115  if (_Iter < _Begin) _Iter = _Begin;
116  } else {
117  if (_Iter > _Begin) _Iter = _Begin;
118  }
119  return _Iter;
120  }
121 
122  bool Next()
123  {
124  if (_Iter != _End) {
125  _Iter += _Inc;
126  if (_Inc > 0) {
127  if (_Iter > _End) {
128  _Iter = _End;
129  return false;
130  }
131  } else {
132  if (_Iter < _End) {
133  _Iter = _End;
134  return false;
135  }
136  }
137  return true;
138  }
139  return false;
140  }
141 };
142 
143 /// Data of AcceptedStepEvent and RejectedStepEvent
145 {
146  const char *_Info; ///< Adjective detailing step for log output
147  double *_Direction; ///< Step direction (i.e., function gradient)
148  double _Current; ///< Current objective function value
149  double _Value; ///< Accepted/rejected function value
150  double _Length; ///< Accepted/rejected step length
151  double _TotalLength; ///< Accumulated length of accepted steps
152  double _MinLength; ///< Minimum allowed step length
153  double _MaxLength; ///< Maximum allowed step length
154  double _Unit; ///< Step length unit
155  double _Delta; ///< Maximum change of parameters (DoFs)
156  double _TotalDelta; ///< Accumulated change of parameters (DoFs)
157 
159  :
160  _Info(NULL), _Direction(NULL),
161  _Current(.0), _Value(.0), _Length(.0), _TotalLength(.0),
162  _MinLength(.0), _MaxLength(.0), _Unit(.0),
163  _Delta(.0), _TotalDelta(.0)
164  {}
165 };
166 
167 
168 } // namespace mirtk
169 
170 
171 namespace std {
172 
173 /// Compute hash value from Event enumeration value
174 template<>
175 struct hash<mirtk::Event> {
176  size_t operator()(const mirtk::Event &enum_value) const {
177  return std::hash<int>()(enum_value);
178  }
179 };
180 
181 
182 } // namespace std
183 
184 #endif // MIRTK_Event_H
double * _Direction
Step direction (i.e., function gradient)
Definition: Event.h:147
int _Inc
Increment after each iteration.
Definition: Event.h:79
Before initialization of filter execution.
Definition: Event.h:39
double _Unit
Step length unit.
Definition: Event.h:154
double _MinLength
Minimum allowed step length.
Definition: Event.h:152
Iteration started.
Definition: Event.h:45
double _Length
Accepted/rejected step length.
Definition: Event.h:150
Status message given as event data (const char *)
Definition: Event.h:37
STL namespace.
Start of filter execution (after initialization)
Definition: Event.h:40
Iteration finished.
Definition: Event.h:46
double _Value
Accepted/rejected function value.
Definition: Event.h:149
Log message given as event data (const char *)
Definition: Event.h:38
Any event.
Definition: Event.h:35
double _Current
Current objective function value.
Definition: Event.h:148
double _TotalLength
Accumulated length of accepted steps.
Definition: Event.h:151
Observable has modified state/parameters.
Definition: Event.h:36
Definition: IOConfig.h:41
Data of AcceptedStepEvent and RejectedStepEvent.
Definition: Event.h:144
Iteration with line search about to start.
Definition: Event.h:44
Line search started.
Definition: Event.h:51
Event
Events that can be observed.
Definition: Event.h:32
Line search iteration.
Definition: Event.h:52
Line search finished.
Definition: Event.h:54
Line search iteration.
Definition: Event.h:53
int _End
End value of iteration counter.
Definition: Event.h:78
double _MaxLength
Maximum allowed step length.
Definition: Event.h:153
const char * _Info
Adjective detailing step for log output.
Definition: Event.h:146
double _Delta
Maximum change of parameters (DoFs)
Definition: Event.h:155
End of filter execution (before finalization)
Definition: Event.h:42
Observer has been registered.
Definition: Event.h:48
int _Iter
Iteration counter.
Definition: Event.h:76
Observer has been unregistered.
Definition: Event.h:49
int _Begin
Start value of iteration counter.
Definition: Event.h:77
After finalization of filter execution.
Definition: Event.h:43
double _TotalDelta
Accumulated change of parameters (DoFs)
Definition: Event.h:156
Restart of filter execution.
Definition: Event.h:41