aGrUM
0.20.2
a C++ library for (probabilistic) graphical models
O3SystemFactory_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 Implementation for the O3SystemFactory class.
25
*
26
* @author Christophe GONZALES(@AMU) and Pierre-Henri WUILLEMIN(@LIP6)
27
* @author Lionel TORTI
28
*/
29
30
#
include
<
agrum
/
PRM
/
o3prm
/
O3SystemFactory
.
h
>
31
32
namespace
gum
{
33
namespace
prm
{
34
namespace
o3prm
{
35
36
template
<
typename
GUM_SCALAR >
37
INLINE O3SystemFactory<
GUM_SCALAR
>::
O3SystemFactory
(
38
PRM
<
GUM_SCALAR
>&
prm
,
39
O3PRM
&
o3_prm
,
40
O3NameSolver
<
GUM_SCALAR
>&
solver
,
41
ErrorsContainer
&
errors
) :
42
prm__
(&
prm
),
43
o3_prm__
(&
o3_prm
),
solver__
(&
solver
),
errors__
(&
errors
) {
44
GUM_CONSTRUCTOR
(
O3SystemFactory
);
45
}
46
47
template
<
typename
GUM_SCALAR
>
48
INLINE
O3SystemFactory
<
GUM_SCALAR
>::
O3SystemFactory
(
49
const
O3SystemFactory
<
GUM_SCALAR
>&
src
) :
50
prm__
(
src
.
prm__
),
51
o3_prm__
(
src
.
o3_prm__
),
solver__
(
src
.
solver__
),
errors__
(
src
.
errors__
),
52
nameMap__
(
src
.
nameMap__
) {
53
GUM_CONS_CPY
(
O3SystemFactory
);
54
}
55
56
template
<
typename
GUM_SCALAR
>
57
INLINE
O3SystemFactory
<
GUM_SCALAR
>::
O3SystemFactory
(
58
O3SystemFactory
<
GUM_SCALAR
>&&
src
) :
59
prm__
(
std
::
move
(
src
.
prm__
)),
60
o3_prm__
(
std
::
move
(
src
.
o3_prm__
)),
solver__
(
std
::
move
(
src
.
solver__
)),
61
errors__
(
std
::
move
(
src
.
errors__
)),
nameMap__
(
std
::
move
(
src
.
nameMap__
)) {
62
GUM_CONS_MOV
(
O3SystemFactory
);
63
}
64
65
template
<
typename
GUM_SCALAR
>
66
INLINE
O3SystemFactory
<
GUM_SCALAR
>::~
O3SystemFactory
() {
67
GUM_DESTRUCTOR
(
O3SystemFactory
);
68
}
69
70
template
<
typename
GUM_SCALAR
>
71
INLINE
O3SystemFactory
<
GUM_SCALAR
>&
72
O3SystemFactory
<
GUM_SCALAR
>::
operator
=(
73
const
O3SystemFactory
<
GUM_SCALAR
>&
src
) {
74
if
(
this
== &
src
) {
return
*
this
; }
75
prm__
=
src
.
prm__
;
76
o3_prm__
=
src
.
o3_prm__
;
77
solver__
=
src
.
solver__
;
78
errors__
=
src
.
errors__
;
79
return
*
this
;
80
}
81
82
template
<
typename
GUM_SCALAR
>
83
INLINE
O3SystemFactory
<
GUM_SCALAR
>&
84
O3SystemFactory
<
GUM_SCALAR
>::
operator
=(
85
O3SystemFactory
<
GUM_SCALAR
>&&
src
) {
86
if
(
this
== &
src
) {
return
*
this
; }
87
prm__
=
std
::
move
(
src
.
prm__
);
88
o3_prm__
=
std
::
move
(
src
.
o3_prm__
);
89
solver__
=
std
::
move
(
src
.
solver__
);
90
errors__
=
std
::
move
(
src
.
errors__
);
91
return
*
this
;
92
}
93
94
template
<
typename
GUM_SCALAR
>
95
INLINE
void
O3SystemFactory
<
GUM_SCALAR
>::
build
() {
96
PRMFactory
<
GUM_SCALAR
>
factory
(
prm__
);
97
98
for
(
auto
&
sys
:
o3_prm__
->
systems
()) {
99
// Reseting name map for each system
100
nameMap__
=
HashTable
<
std
::
string
,
O3Instance
* >();
101
102
if
(
checkSystem__
(*
sys
)) {
103
factory
.
startSystem
(
sys
->
name
().
label
());
104
105
addInstances__
(
factory
, *
sys
);
106
addAssignments__
(
factory
, *
sys
);
107
addIncrements__
(
factory
, *
sys
);
108
109
try
{
110
factory
.
endSystem
();
111
}
catch
(
FatalError
&) {
112
O3PRM_SYSTEM_INSTANTIATION_FAILED
(*
sys
, *
errors__
);
113
}
114
}
115
}
116
}
117
118
template
<
typename
GUM_SCALAR
>
119
INLINE
void
O3SystemFactory
<
GUM_SCALAR
>::
addInstances__
(
120
PRMFactory
<
GUM_SCALAR
>&
factory
,
121
O3System
&
sys
) {
122
for
(
auto
&
i
:
sys
.
instances
()) {
123
if
(
i
.
parameters
().
size
() > 0) {
124
auto
params
=
HashTable
<
std
::
string
,
double
>();
125
for
(
auto
&
p
:
i
.
parameters
()) {
126
params
.
insert
(
p
.
name
().
label
(), (
double
)
p
.
value
().
value
());
127
}
128
factory
.
addInstance
(
i
.
type
().
label
(),
i
.
name
().
label
(),
params
);
129
130
}
else
{
131
if
(
i
.
size
().
value
() > 1) {
132
factory
.
addArray
(
i
.
type
().
label
(),
133
i
.
name
().
label
(),
134
i
.
size
().
value
());
135
}
else
{
136
factory
.
addInstance
(
i
.
type
().
label
(),
i
.
name
().
label
());
137
}
138
}
139
}
140
}
141
142
template
<
typename
GUM_SCALAR
>
143
INLINE
void
O3SystemFactory
<
GUM_SCALAR
>::
addAssignments__
(
144
PRMFactory
<
GUM_SCALAR
>&
factory
,
145
O3System
&
sys
) {
146
const
auto
&
real_sys
=
prm__
->
getSystem
(
sys
.
name
().
label
());
147
148
for
(
auto
&
ass
:
sys
.
assignments
()) {
149
auto
leftInstance
=
ass
.
leftInstance
().
label
();
150
auto
leftReference
=
ass
.
leftReference
().
label
();
151
auto
rightInstance
=
ass
.
rightInstance
().
label
();
152
153
if
(
ass
.
leftIndex
().
value
() > -1 &&
real_sys
.
isArray
(
leftInstance
)) {
154
std
::
stringstream
sBuff
;
155
sBuff
<<
leftInstance
<<
"["
<<
ass
.
leftIndex
().
value
() <<
"]"
;
156
leftInstance
=
sBuff
.
str
();
157
}
158
159
if
(
ass
.
rightIndex
().
value
() > -1 &&
real_sys
.
isArray
(
rightInstance
)) {
160
std
::
stringstream
sBuff
;
161
sBuff
<<
rightInstance
<<
"["
<<
ass
.
rightIndex
().
value
() <<
"]"
;
162
rightInstance
=
sBuff
.
str
();
163
}
164
165
factory
.
setReferenceSlot
(
leftInstance
,
leftReference
,
rightInstance
);
166
}
167
}
168
169
template
<
typename
GUM_SCALAR
>
170
INLINE
void
O3SystemFactory
<
GUM_SCALAR
>::
addIncrements__
(
171
PRMFactory
<
GUM_SCALAR
>&
factory
,
172
O3System
&
sys
) {
173
const
auto
&
real_sys
=
prm__
->
getSystem
(
sys
.
name
().
label
());
174
for
(
auto
&
inc
:
sys
.
increments
()) {
175
auto
leftInstance
=
inc
.
leftInstance
().
label
();
176
auto
leftReference
=
inc
.
leftReference
().
label
();
177
auto
rightInstance
=
inc
.
rightInstance
().
label
();
178
179
if
(
inc
.
leftIndex
().
value
() > -1 &&
real_sys
.
isArray
(
leftInstance
)) {
180
std
::
stringstream
sBuff
;
181
sBuff
<<
leftInstance
<<
"["
<<
inc
.
leftIndex
().
value
() <<
"]"
;
182
leftInstance
=
sBuff
.
str
();
183
}
184
185
if
(
inc
.
rightIndex
().
value
() > -1 &&
real_sys
.
isArray
(
rightInstance
)) {
186
std
::
stringstream
sBuff
;
187
sBuff
<<
rightInstance
<<
"["
<<
inc
.
rightIndex
().
value
() <<
"]"
;
188
rightInstance
=
sBuff
.
str
();
189
}
190
191
factory
.
setReferenceSlot
(
leftInstance
,
leftReference
,
rightInstance
);
192
}
193
}
194
195
template
<
typename
GUM_SCALAR
>
196
INLINE
bool
O3SystemFactory
<
GUM_SCALAR
>::
checkSystem__
(
O3System
&
sys
) {
197
if
(
checkInstance__
(
sys
) &&
checkAssignments__
(
sys
)
198
&&
checkIncrements__
(
sys
)) {
199
return
true
;
200
}
201
202
return
false
;
203
}
204
205
template
<
typename
GUM_SCALAR
>
206
INLINE
bool
O3SystemFactory
<
GUM_SCALAR
>::
checkInstance__
(
O3System
&
sys
) {
207
for
(
auto
&
i
:
sys
.
instances
()) {
208
if
(!
solver__
->
resolveClass
(
i
.
type
())) {
return
false
; }
209
210
const
auto
&
type
=
prm__
->
getClass
(
i
.
type
().
label
());
211
if
(
type
.
parameters
().
size
() > 0) {
212
if
(!
checkParameters__
(
type
,
i
)) {
return
false
; }
213
}
214
215
if
(
nameMap__
.
exists
(
i
.
name
().
label
())) {
216
O3PRM_SYSTEM_DUPLICATE_INSTANCE
(
i
, *
errors__
);
217
return
false
;
218
}
219
220
nameMap__
.
insert
(
i
.
name
().
label
(), &
i
);
221
}
222
223
return
true
;
224
}
225
226
template
<
typename
GUM_SCALAR
>
227
INLINE
bool
O3SystemFactory
<
GUM_SCALAR
>::
checkParameters__
(
228
const
PRMClass
<
GUM_SCALAR
>&
type
,
229
const
O3Instance
&
inst
) {
230
for
(
const
auto
&
param
:
inst
.
parameters
()) {
231
if
(!
type
.
exists
(
param
.
name
().
label
())) {
232
O3PRM_SYSTEM_PARAMETER_NOT_FOUND
(
param
, *
errors__
);
233
return
false
;
234
}
235
236
if
(!
PRMClassElement
<
GUM_SCALAR
>::
isParameter
(
237
type
.
get
(
param
.
name
().
label
()))) {
238
O3PRM_SYSTEM_NOT_A_PARAMETER
(
param
, *
errors__
);
239
return
false
;
240
}
241
242
const
auto
&
type_param
243
=
static_cast
<
const
PRMParameter
<
GUM_SCALAR
>& >(
244
type
.
get
(
param
.
name
().
label
()));
245
246
switch
(
type_param
.
valueType
()) {
247
case
PRMParameter
<
GUM_SCALAR
>::
ParameterType
::
INT
: {
248
if
(!
param
.
isInteger
()) {
249
O3PRM_SYSTEM_PARAMETER_NOT_INT
(
param
, *
errors__
);
250
return
false
;
251
}
252
break
;
253
}
254
255
case
PRMParameter
<
GUM_SCALAR
>::
ParameterType
::
REAL
: {
256
if
(
param
.
isInteger
()) {
257
O3PRM_SYSTEM_PARAMETER_NOT_FLOAT
(
param
, *
errors__
);
258
return
false
;
259
}
260
break
;
261
}
262
263
default
: {
264
GUM_ERROR
(
FatalError
,
"unknown parameter type"
);
265
}
266
}
267
}
268
return
true
;
269
}
270
271
template
<
typename
GUM_SCALAR
>
272
INLINE
bool
273
O3SystemFactory
<
GUM_SCALAR
>::
checkAssignments__
(
O3System
&
sys
) {
274
for
(
auto
&
ass
:
sys
.
assignments
()) {
275
// if ( ass.leftInstance().label() == ass.leftReference().label() ) {
276
// O3PRM_SYSTEM_INVALID_LEFT_VALUE( ass.leftInstance(), *errors__ );
277
// return false;
278
//}
279
280
if
(!
nameMap__
.
exists
(
ass
.
leftInstance
().
label
())) {
281
O3PRM_SYSTEM_INSTANCE_NOT_FOUND
(
ass
.
leftInstance
(), *
errors__
);
282
return
false
;
283
}
284
285
auto
i
=
nameMap__
[
ass
.
leftInstance
().
label
()];
286
const
auto
&
type
=
prm__
->
getClass
(
i
->
type
().
label
());
287
const
auto
&
ref
=
ass
.
leftReference
().
label
();
288
289
if
(!(
type
.
exists
(
ass
.
leftReference
().
label
())
290
&&
PRMClassElement
<
GUM_SCALAR
>::
isReferenceSlot
(
291
type
.
get
(
ref
)))) {
292
O3PRM_SYSTEM_REFERENCE_NOT_FOUND
(
ass
.
leftReference
(),
293
type
.
name
(),
294
*
errors__
);
295
return
false
;
296
}
297
298
const
auto
&
real_ref
299
=
static_cast
<
const
PRMReferenceSlot
<
GUM_SCALAR
>& >(
type
.
get
(
ref
));
300
301
if
(!
nameMap__
.
exists
(
ass
.
rightInstance
().
label
())) {
302
O3PRM_SYSTEM_INSTANCE_NOT_FOUND
(
ass
.
rightInstance
(), *
errors__
);
303
return
false
;
304
}
305
306
if
(
real_ref
.
isArray
()
307
&&
nameMap__
[
ass
.
rightInstance
().
label
()]->
size
().
value
() == 0) {
308
O3PRM_SYSTEM_NOT_AN_ARRAY
(
ass
.
rightInstance
(), *
errors__
);
309
return
false
;
310
}
311
312
if
((!
real_ref
.
isArray
())
313
&&
nameMap__
[
ass
.
rightInstance
().
label
()]->
size
().
value
() > 0
314
&&
ass
.
rightIndex
().
value
() == -1) {
315
O3PRM_SYSTEM_NOT_AN_ARRAY
(
ass
.
leftReference
(), *
errors__
);
316
return
false
;
317
}
318
}
319
return
true
;
320
}
321
322
template
<
typename
GUM_SCALAR
>
323
INLINE
bool
O3SystemFactory
<
GUM_SCALAR
>::
checkIncrements__
(
O3System
&
sys
) {
324
for
(
auto
&
inc
:
sys
.
increments
()) {
325
// if ( inc.leftInstance().label() == inc.leftReference().label() ) {
326
// O3PRM_SYSTEM_INVALID_LEFT_VALUE( inc.leftInstance(), *errors__ );
327
// return false;
328
//}
329
330
if
(!
nameMap__
.
exists
(
inc
.
leftInstance
().
label
())) {
331
O3PRM_SYSTEM_INSTANCE_NOT_FOUND
(
inc
.
leftInstance
(), *
errors__
);
332
return
false
;
333
}
334
335
auto
i
=
nameMap__
[
inc
.
leftInstance
().
label
()];
336
const
auto
&
type
=
prm__
->
getClass
(
i
->
type
().
label
());
337
const
auto
&
ref
=
inc
.
leftReference
().
label
();
338
339
if
(!(
type
.
exists
(
inc
.
leftReference
().
label
())
340
&&
PRMClassElement
<
GUM_SCALAR
>::
isReferenceSlot
(
341
type
.
get
(
ref
)))) {
342
O3PRM_SYSTEM_REFERENCE_NOT_FOUND
(
inc
.
leftReference
(),
343
type
.
name
(),
344
*
errors__
);
345
return
false
;
346
}
347
348
const
auto
&
real_ref
349
=
static_cast
<
const
PRMReferenceSlot
<
GUM_SCALAR
>& >(
type
.
get
(
ref
));
350
351
if
(!
real_ref
.
isArray
()) {
352
O3PRM_SYSTEM_NOT_AN_ARRAY
(
inc
.
leftReference
(), *
errors__
);
353
return
false
;
354
}
355
}
356
357
return
true
;
358
}
359
}
// namespace o3prm
360
}
// namespace prm
361
}
// namespace gum
gum::Set::emplace
INLINE void emplace(Args &&... args)
Definition:
set_tpl.h:669
gum::prm::o3prm
Definition:
O3prm.cpp:34
gum::prm::ParamScopeData::ParamScopeData
ParamScopeData(const std::string &s, const PRMReferenceSlot< GUM_SCALAR > &ref, Idx d)
Definition:
PRMClass_tpl.h:1101