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