aGrUM
0.20.3
a C++ library for (probabilistic) graphical models
linearApproximationPolicy_tpl.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 Inlined implementation of gum::LienarApproxiationPolicy.
25
*
26
* @author Pierre-Henri WUILLEMIN(@LIP6) & Jean-Christophe Magnan
27
*
28
*/
29
30
// Help IDE parsers
31
#
include
<
agrum
/
tools
/
core
/
approximations
/
linearApproximationPolicy
.
h
>
32
33
namespace
gum
{
34
35
// Class constructor
36
template
<
typename
GUM_SCALAR >
37
LinearApproximationPolicy< GUM_SCALAR >::LinearApproximationPolicy(GUM_SCALAR low,
38
GUM_SCALAR high,
39
GUM_SCALAR eps) :
40
ApproximationPolicy< GUM_SCALAR >(),
41
lowLimit_(low), highLimit_(high), epsilon_(eps) {
42
if
(eps <= 0) { GUM_ERROR(OutOfBounds,
"Epsilon must be >0"
) }
43
44
computeNbInterval_();
45
}
46
47
// Copy constructor.
48
template
<
typename
GUM_SCALAR
>
49
LinearApproximationPolicy
<
GUM_SCALAR
>::
LinearApproximationPolicy
(
50
const
LinearApproximationPolicy
<
GUM_SCALAR
>*
md
) :
51
ApproximationPolicy
<
GUM_SCALAR
>(
md
),
52
epsilon_
(
md
->
epsilon_
),
nbInterval_
(
md
->
nbInterval_
) {}
53
54
55
// @brief Convert value to his approximation.
56
template
<
typename
GUM_SCALAR
>
57
INLINE
GUM_SCALAR
58
LinearApproximationPolicy
<
GUM_SCALAR
>::
fromExact
(
const
GUM_SCALAR
&
value
)
const
{
59
return
_decode_
(
GUM_SCALAR
(
encode
(
value
)));
60
}
61
62
// @brief Combine using addition with the given gum::ApproximationPolicy.
63
template
<
typename
GUM_SCALAR
>
64
INLINE
void
LinearApproximationPolicy
<
GUM_SCALAR
>::
combineAdd
(
65
const
ApproximationPolicy
<
GUM_SCALAR
>*
ap
) {
66
try
{
67
const
LinearApproximationPolicy
<
GUM_SCALAR
>*
lap
68
=
dynamic_cast
<
const
LinearApproximationPolicy
<
GUM_SCALAR
>* >(
ap
);
69
70
GUM_SCALAR
newHighLimit
=
lowLimit_
+
lap
->
lowLimit
();
71
GUM_SCALAR
newLowLimit
=
lowLimit_
+
lap
->
lowLimit
();
72
73
GUM_SCALAR
newVal
=
lowLimit_
+
lap
->
highLimit
();
74
75
if
(
newHighLimit
<
newVal
)
newHighLimit
=
newVal
;
76
77
if
(
newLowLimit
>
newVal
)
newLowLimit
=
newVal
;
78
79
newVal
=
highLimit_
+
lap
->
lowLimit
();
80
81
if
(
newHighLimit
<
newVal
)
newHighLimit
=
newVal
;
82
83
if
(
newLowLimit
>
newVal
)
newLowLimit
=
newVal
;
84
85
newVal
=
highLimit_
+
lap
->
highLimit
();
86
87
if
(
newHighLimit
<
newVal
)
newHighLimit
=
newVal
;
88
89
if
(
newLowLimit
>
newVal
)
newLowLimit
=
newVal
;
90
}
catch
(
const
std
::
bad_cast
&) {}
91
}
92
93
template
<
typename
GUM_SCALAR
>
94
INLINE
void
LinearApproximationPolicy
<
GUM_SCALAR
>::
combineSub
(
95
const
ApproximationPolicy
<
GUM_SCALAR
>*
ap
) {
96
try
{
97
const
LinearApproximationPolicy
<
GUM_SCALAR
>*
lap
98
=
dynamic_cast
<
const
LinearApproximationPolicy
<
GUM_SCALAR
>* >(
ap
);
99
100
GUM_SCALAR
newHighLimit
=
lowLimit_
-
lap
->
lowLimit
();
101
GUM_SCALAR
newLowLimit
=
lowLimit_
-
lap
->
lowLimit
();
102
103
GUM_SCALAR
newVal
=
lowLimit_
-
lap
->
highLimit
();
104
105
if
(
newHighLimit
<
newVal
)
newHighLimit
=
newVal
;
106
107
if
(
newLowLimit
>
newVal
)
newLowLimit
=
newVal
;
108
109
newVal
=
highLimit_
-
lap
->
lowLimit
();
110
111
if
(
newHighLimit
<
newVal
)
newHighLimit
=
newVal
;
112
113
if
(
newLowLimit
>
newVal
)
newLowLimit
=
newVal
;
114
115
newVal
=
highLimit_
-
lap
->
highLimit
();
116
117
if
(
newHighLimit
<
newVal
)
newHighLimit
=
newVal
;
118
119
if
(
newLowLimit
>
newVal
)
newLowLimit
=
newVal
;
120
}
catch
(
const
std
::
bad_cast
&) {}
121
}
122
123
template
<
typename
GUM_SCALAR
>
124
INLINE
void
LinearApproximationPolicy
<
GUM_SCALAR
>::
combineMult
(
125
const
ApproximationPolicy
<
GUM_SCALAR
>*
ap
) {
126
try
{
127
const
LinearApproximationPolicy
<
GUM_SCALAR
>*
lap
128
=
dynamic_cast
<
const
LinearApproximationPolicy
<
GUM_SCALAR
>* >(
ap
);
129
130
GUM_SCALAR
newHighLimit
=
lowLimit_
*
lap
->
lowLimit
();
131
GUM_SCALAR
newLowLimit
=
lowLimit_
*
lap
->
lowLimit
();
132
133
GUM_SCALAR
newVal
=
lowLimit_
*
lap
->
highLimit
();
134
135
if
(
newHighLimit
<
newVal
)
newHighLimit
=
newVal
;
136
137
if
(
newLowLimit
>
newVal
)
newLowLimit
=
newVal
;
138
139
newVal
=
highLimit_
*
lap
->
lowLimit
();
140
141
if
(
newHighLimit
<
newVal
)
newHighLimit
=
newVal
;
142
143
if
(
newLowLimit
>
newVal
)
newLowLimit
=
newVal
;
144
145
newVal
=
highLimit_
*
lap
->
highLimit
();
146
147
if
(
newHighLimit
<
newVal
)
newHighLimit
=
newVal
;
148
149
if
(
newLowLimit
>
newVal
)
newLowLimit
=
newVal
;
150
}
catch
(
const
std
::
bad_cast
&) {}
151
}
152
153
template
<
typename
GUM_SCALAR
>
154
INLINE
void
LinearApproximationPolicy
<
GUM_SCALAR
>::
combineDiv
(
155
const
ApproximationPolicy
<
GUM_SCALAR
>*
ap
) {
156
try
{
157
const
LinearApproximationPolicy
<
GUM_SCALAR
>*
lap
158
=
dynamic_cast
<
const
LinearApproximationPolicy
<
GUM_SCALAR
>* >(
ap
);
159
160
GUM_SCALAR
newHighLimit
=
lowLimit_
/
lap
->
lowLimit
();
161
GUM_SCALAR
newLowLimit
=
lowLimit_
/
lap
->
lowLimit
();
162
163
GUM_SCALAR
newVal
=
lowLimit_
/
lap
->
highLimit
();
164
165
if
(
newHighLimit
<
newVal
)
newHighLimit
=
newVal
;
166
167
if
(
newLowLimit
>
newVal
)
newLowLimit
=
newVal
;
168
169
newVal
=
highLimit_
/
lap
->
lowLimit
();
170
171
if
(
newHighLimit
<
newVal
)
newHighLimit
=
newVal
;
172
173
if
(
newLowLimit
>
newVal
)
newLowLimit
=
newVal
;
174
175
newVal
=
highLimit_
/
lap
->
highLimit
();
176
177
if
(
newHighLimit
<
newVal
)
newHighLimit
=
newVal
;
178
179
if
(
newLowLimit
>
newVal
)
newLowLimit
=
newVal
;
180
}
catch
(
const
std
::
bad_cast
&) {}
181
}
182
183
template
<
typename
GUM_SCALAR
>
184
INLINE
void
LinearApproximationPolicy
<
GUM_SCALAR
>::
combineMax
(
185
const
ApproximationPolicy
<
GUM_SCALAR
>*
ap
) {
186
try
{
187
const
LinearApproximationPolicy
<
GUM_SCALAR
>*
lap
188
=
dynamic_cast
<
const
LinearApproximationPolicy
<
GUM_SCALAR
>* >(
ap
);
189
190
GUM_SCALAR
newHighLimit
=
lowLimit_
>
lap
->
lowLimit
() ?
lowLimit_
:
lap
->
lowLimit
();
191
GUM_SCALAR
newLowLimit
=
lowLimit_
>
lap
->
lowLimit
() ?
lowLimit_
:
lap
->
lowLimit
();
192
193
GUM_SCALAR
newVal
=
lowLimit_
>
lap
->
highLimit
() ?
lowLimit_
:
lap
->
highLimit
();
194
195
if
(
newHighLimit
<
newVal
)
newHighLimit
=
newVal
;
196
197
if
(
newLowLimit
>
newVal
)
newLowLimit
=
newVal
;
198
199
newVal
=
highLimit_
>
lap
->
lowLimit
() ?
highLimit_
:
lap
->
lowLimit
();
200
201
if
(
newHighLimit
<
newVal
)
newHighLimit
=
newVal
;
202
203
if
(
newLowLimit
>
newVal
)
newLowLimit
=
newVal
;
204
205
newVal
=
highLimit_
>
lap
->
highLimit
() ?
highLimit_
:
lap
->
highLimit
();
206
207
if
(
newHighLimit
<
newVal
)
newHighLimit
=
newVal
;
208
209
if
(
newLowLimit
>
newVal
)
newLowLimit
=
newVal
;
210
}
catch
(
const
std
::
bad_cast
&) {}
211
}
212
213
template
<
typename
GUM_SCALAR
>
214
INLINE
void
LinearApproximationPolicy
<
GUM_SCALAR
>::
combineMin
(
215
const
ApproximationPolicy
<
GUM_SCALAR
>*
ap
) {
216
try
{
217
const
LinearApproximationPolicy
<
GUM_SCALAR
>*
lap
218
=
dynamic_cast
<
const
LinearApproximationPolicy
<
GUM_SCALAR
>* >(
ap
);
219
220
GUM_SCALAR
newHighLimit
=
lowLimit_
<
lap
->
lowLimit
() ?
lowLimit_
:
lap
->
lowLimit
();
221
GUM_SCALAR
newLowLimit
=
lowLimit_
<
lap
->
lowLimit
() ?
lowLimit_
:
lap
->
lowLimit
();
222
223
GUM_SCALAR
newVal
=
lowLimit_
<
lap
->
highLimit
() ?
lowLimit_
:
lap
->
highLimit
();
224
225
if
(
newHighLimit
<
newVal
)
newHighLimit
=
newVal
;
226
227
if
(
newLowLimit
>
newVal
)
newLowLimit
=
newVal
;
228
229
newVal
=
highLimit_
<
lap
->
lowLimit
() ?
highLimit_
:
lap
->
lowLimit
();
230
231
if
(
newHighLimit
<
newVal
)
newHighLimit
=
newVal
;
232
233
if
(
newLowLimit
>
newVal
)
newLowLimit
=
newVal
;
234
235
newVal
=
highLimit_
<
lap
->
highLimit
() ?
highLimit_
:
lap
->
highLimit
();
236
237
if
(
newHighLimit
<
newVal
)
newHighLimit
=
newVal
;
238
239
if
(
newLowLimit
>
newVal
)
newLowLimit
=
newVal
;
240
}
catch
(
const
std
::
bad_cast
&) {}
241
}
242
243
// Convert value to his approximation. This method is slower than @ref
244
// fromExact since it verifies the bounds
245
template
<
typename
GUM_SCALAR
>
246
INLINE
GUM_SCALAR
247
LinearApproximationPolicy
<
GUM_SCALAR
>::
safeFromExact
(
const
GUM_SCALAR
&
value
) {
248
if
(
value
>
this
->
highLimit_
) {
249
GUM_ERROR
(
OutOfUpperBound
,
"Value asked is higher than high limit"
)
250
}
251
252
if
(
value
<
this
->
lowLimit_
) {
253
GUM_ERROR
(
OutOfLowerBound
,
"Value asked is lower than low limit"
)
254
}
255
256
return
fromExact
(
value
);
257
}
258
259
// Convert value to approximation representation
260
template
<
typename
GUM_SCALAR
>
261
INLINE
Idx
LinearApproximationPolicy
<
GUM_SCALAR
>::
encode
(
const
GUM_SCALAR
&
value
)
const
{
262
// we keep the bounds checked in debug mode
263
#
ifdef
GUM_DEBUG_MODE
264
if
(
value
>
this
->
highLimit_
) {
265
GUM_ERROR
(
OutOfUpperBound
,
266
"Value asked is higher than High limit : not in ("
<<
this
->
lowLimit_
<<
"-"
267
<<
this
->
highLimit_
<<
")"
)
268
}
269
270
if
(
value
<
this
->
lowLimit_
) {
271
GUM_ERROR
(
OutOfLowerBound
,
272
"Value asked is lower than low limit : not in ("
<<
this
->
lowLimit_
<<
"-"
273
<<
this
->
highLimit_
<<
")"
)
274
}
275
276
#
endif
// GUM_DEBUG_MODE
277
return
_encode_
(
value
);
278
}
279
280
// Convert approximation representation to value
281
template
<
typename
GUM_SCALAR
>
282
INLINE
GUM_SCALAR
LinearApproximationPolicy
<
GUM_SCALAR
>::
decode
(
Idx
representation
)
const
{
283
if
(
representation
>
nbInterval_
) {
284
GUM_ERROR
(
OutOfUpperBound
,
"Interval Number asked is higher than total number of interval"
)
285
}
286
287
return
_decode_
(
GUM_SCALAR
(
representation
));
288
}
289
290
// Sets approximation factor
291
template
<
typename
GUM_SCALAR
>
292
INLINE
void
LinearApproximationPolicy
<
GUM_SCALAR
>::
setEpsilon
(
const
GUM_SCALAR
&
e
) {
293
epsilon_
=
e
;
294
computeNbInterval_
();
295
}
296
297
// set bounds in a whole
298
template
<
typename
GUM_SCALAR
>
299
INLINE
void
LinearApproximationPolicy
<
GUM_SCALAR
>::
setLimits
(
const
GUM_SCALAR
&
newLowLimit
,
300
const
GUM_SCALAR
&
newHighLimit
) {
301
if
(
newLowLimit
>
newHighLimit
) {
302
GUM_ERROR
(
OutOfBounds
,
"Asked low value is higher than asked high value"
)
303
}
304
305
lowLimit_
=
newLowLimit
;
306
highLimit_
=
newHighLimit
;
307
computeNbInterval_
();
308
}
309
310
// Sets lowest possible value
311
template
<
typename
GUM_SCALAR
>
312
INLINE
void
LinearApproximationPolicy
<
GUM_SCALAR
>::
setLowLimit
(
const
GUM_SCALAR
&
newLowLimit
) {
313
if
(
newLowLimit
>
this
->
highLimit_
) {
314
GUM_ERROR
(
OutOfUpperBound
,
"Value asked is higher than High limit"
)
315
}
316
317
lowLimit_
=
newLowLimit
;
318
319
computeNbInterval_
();
320
}
321
322
// Gets lowest possible value
323
template
<
typename
GUM_SCALAR
>
324
INLINE
const
GUM_SCALAR
&
LinearApproximationPolicy
<
GUM_SCALAR
>::
lowLimit
()
const
{
325
return
lowLimit_
;
326
}
327
328
// Sets Highest possible value
329
template
<
typename
GUM_SCALAR
>
330
INLINE
void
331
LinearApproximationPolicy
<
GUM_SCALAR
>::
setHighLimit
(
const
GUM_SCALAR
&
newHighLimit
) {
332
if
(
newHighLimit
<
this
->
lowLimit_
) {
333
GUM_ERROR
(
OutOfLowerBound
,
"Value asked is lower than low limit"
)
334
}
335
336
highLimit_
=
newHighLimit
;
337
338
computeNbInterval_
();
339
}
340
341
// Gets Highest possible value
342
template
<
typename
GUM_SCALAR
>
343
INLINE
const
GUM_SCALAR
&
LinearApproximationPolicy
<
GUM_SCALAR
>::
highLimit
()
const
{
344
return
highLimit_
;
345
}
346
347
// Concretely computes the approximate representation
348
template
<
typename
GUM_SCALAR
>
349
INLINE
Idx
LinearApproximationPolicy
<
GUM_SCALAR
>::
_encode_
(
const
GUM_SCALAR
&
value
)
const
{
350
if
(
value
<=
this
->
lowLimit_
)
return
0;
351
352
if
(
value
>=
this
->
highLimit_
)
return
nbInterval_
;
353
354
return
1 +
Idx
(((
value
-
this
->
lowLimit_
) /
this
->
epsilon_
));
355
}
356
357
// Concretely computes the approximate value from representation
358
template
<
typename
GUM_SCALAR
>
359
INLINE
GUM_SCALAR
360
LinearApproximationPolicy
<
GUM_SCALAR
>::
_decode_
(
const
GUM_SCALAR
&
representation
)
const
{
361
if
(
representation
== 0)
return
this
->
lowLimit_
;
362
363
if
(
representation
==
nbInterval_
)
return
this
->
highLimit_
;
364
365
return
(
GUM_SCALAR
)(((
representation
*
this
->
epsilon_
) - (
this
->
epsilon_
/ 2))
366
+
this
->
lowLimit_
);
367
}
368
369
// get the number of interval
370
template
<
typename
GUM_SCALAR
>
371
INLINE
void
LinearApproximationPolicy
<
GUM_SCALAR
>::
computeNbInterval_
() {
372
nbInterval_
= 1 +
Idx
((
this
->
highLimit_
-
this
->
lowLimit_
) /
this
->
epsilon_
);
373
}
374
}
// namespace gum
gum::Set::emplace
INLINE void emplace(Args &&... args)
Definition:
set_tpl.h:643