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