aGrUM
0.20.3
a C++ library for (probabilistic) graphical models
multiDimFunctionGraph_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 Template methods of MultiDimFunctionGraph.
25
*
26
* @author Pierre-Henri WUILLEMIN(@LIP6) & Christophe GONZALES(@AMU)
27
* @author Pierre-Henri WUILLEMIN(@LIP6) and Jean-Christophe MAGNAN and Christophe
28
* GONZALES(@AMU)
29
*/
30
#
include
<
agrum
/
tools
/
multidim
/
implementations
/
multiDimFunctionGraph
.
h
>
31
32
namespace
gum
{
33
34
// Default constructor.
35
template
<
typename
GUM_SCALAR,
template
<
class
>
class
TerminalNodePolicy >
36
INLINE MultiDimFunctionGraph<
GUM_SCALAR
,
TerminalNodePolicy
>::
MultiDimFunctionGraph
(
37
bool
isReduced
) :
38
MultiDimImplementation
<
GUM_SCALAR
>(),
39
_name_
(
"MultiDimFunctionGraph"
),
_tableName_
(
"NO NAME"
),
_model_
(500,
true
),
40
_manager_
(
nullptr
),
_root_
(0),
_internalNodeMap_
(500,
true
,
false
),
41
_var2NodeIdMap_
(500,
true
,
false
),
_isReduced_
(
isReduced
) {
42
GUM_CONSTRUCTOR
(
MultiDimFunctionGraph
);
43
_manager_
=
nullptr
;
44
// Pop up a first node so that id 0 is unavailable
45
_model_
.
addNode
();
46
}
47
48
// Copy constructor.
49
template
<
typename
GUM_SCALAR
,
template
<
class
>
class
TerminalNodePolicy
>
50
INLINE
MultiDimFunctionGraph
<
GUM_SCALAR
,
TerminalNodePolicy
>::
MultiDimFunctionGraph
(
51
const
MultiDimFunctionGraph
<
GUM_SCALAR
,
TerminalNodePolicy
>&
from
) :
52
MultiDimImplementation
<
GUM_SCALAR
>(),
53
_name_
(
"MultiDimFunctionGraph"
),
_tableName_
(
"No NAME"
),
_model_
(500,
true
),
54
_manager_
(
nullptr
),
_root_
(0),
_internalNodeMap_
(500,
true
,
false
),
55
_var2NodeIdMap_
(500,
true
,
false
),
_isReduced_
(
from
.
isReducedAndOrdered
()) {
56
GUM_CONS_CPY
(
MultiDimFunctionGraph
);
57
copy
(
from
);
58
}
59
60
// Copy Operator.
61
template
<
typename
GUM_SCALAR
,
template
<
class
>
class
TerminalNodePolicy
>
62
INLINE
MultiDimFunctionGraph
<
GUM_SCALAR
,
TerminalNodePolicy
>&
63
MultiDimFunctionGraph
<
GUM_SCALAR
,
TerminalNodePolicy
>::
operator
=(
64
const
MultiDimFunctionGraph
<
GUM_SCALAR
,
TerminalNodePolicy
>&
from
) {
65
copy
(
from
);
66
return
*
this
;
67
}
68
69
// Destructor.
70
template
<
typename
GUM_SCALAR
,
template
<
class
>
class
TerminalNodePolicy
>
71
INLINE
MultiDimFunctionGraph
<
GUM_SCALAR
,
TerminalNodePolicy
>::~
MultiDimFunctionGraph
() {
72
// Manager deletion
73
GUM_DESTRUCTOR
(
MultiDimFunctionGraph
);
74
if
(
_manager_
!=
nullptr
)
delete
_manager_
;
75
this
->
clear
();
76
}
77
78
template
<
typename
GUM_SCALAR
,
template
<
class
>
class
TerminalNodePolicy
>
79
INLINE
MultiDimContainer
<
GUM_SCALAR
>*
80
MultiDimFunctionGraph
<
GUM_SCALAR
,
TerminalNodePolicy
>::
newFactory
()
const
{
81
if
(
_isReduced_
)
82
return
MultiDimFunctionGraph
<
GUM_SCALAR
,
83
TerminalNodePolicy
>::
getReducedAndOrderedInstance
();
84
else
85
return
MultiDimFunctionGraph
<
GUM_SCALAR
,
TerminalNodePolicy
>::
getTreeInstance
();
86
}
87
88
template
<
typename
GUM_SCALAR
,
template
<
class
>
class
TerminalNodePolicy
>
89
INLINE
const
std
::
string
&
MultiDimFunctionGraph
<
GUM_SCALAR
,
TerminalNodePolicy
>::
name
()
const
{
90
return
_name_
;
91
}
92
93
template
<
typename
GUM_SCALAR
,
template
<
class
>
class
TerminalNodePolicy
>
94
INLINE
void
95
MultiDimFunctionGraph
<
GUM_SCALAR
,
TerminalNodePolicy
>::
set
(
const
Instantiation
&
i
,
96
const
GUM_SCALAR
&
value
)
const
{
97
GUM_ERROR
(
OperationNotAllowed
,
98
"Function Graph can't be edited so "
99
"easily.\nMultiDimFunctionGraphManager "
100
"provides the framework to edit a "
101
"Function Graph."
)
102
}
103
104
template
<
typename
GUM_SCALAR
,
template
<
class
>
class
TerminalNodePolicy
>
105
INLINE
void
106
MultiDimFunctionGraph
<
GUM_SCALAR
,
TerminalNodePolicy
>::
fill
(
const
GUM_SCALAR
&
d
)
const
{
107
GUM_ERROR
(
OperationNotAllowed
,
108
"Function Graph can't be edited so "
109
"easily.\nMultiDimFunctionGraphManager "
110
"provides the framework to edit a "
111
"Function Graph."
)
112
}
113
114
template
<
typename
GUM_SCALAR
,
template
<
class
>
class
TerminalNodePolicy
>
115
INLINE
void
MultiDimFunctionGraph
<
GUM_SCALAR
,
TerminalNodePolicy
>::
populate
(
116
const
std
::
vector
<
GUM_SCALAR
>&
v
)
const
{
117
GUM_ERROR
(
OperationNotAllowed
,
118
"Function Graph can't be edited so "
119
"easily.\nMultiDimFunctionGraphManager "
120
"provides the framework to editaa "
121
"Function Graph."
)
122
}
123
template
<
typename
GUM_SCALAR
,
template
<
class
>
class
TerminalNodePolicy
>
124
INLINE
void
MultiDimFunctionGraph
<
GUM_SCALAR
,
TerminalNodePolicy
>::
populate
(
125
std
::
initializer_list
<
GUM_SCALAR
>
l
)
const
{
126
GUM_ERROR
(
OperationNotAllowed
,
127
"Function Graph can't be edited so "
128
"easily.\nMultiDimFunctionGraphManager "
129
"provides the framework to edit a "
130
"Function Graph."
)
131
}
132
133
template
<
typename
GUM_SCALAR
,
template
<
class
>
class
TerminalNodePolicy
>
134
INLINE
void
135
MultiDimFunctionGraph
<
GUM_SCALAR
,
TerminalNodePolicy
>::
add
(
const
DiscreteVariable
&
v
) {
136
if
(!
this
->
variablesSequence
().
exists
(&
v
))
MultiDimImplementation
<
GUM_SCALAR
>::
add
(
v
);
137
138
if
(!
this
->
_var2NodeIdMap_
.
exists
(&
v
))
_var2NodeIdMap_
.
insert
(&
v
,
new
LinkedList
<
NodeId
>());
139
}
140
141
template
<
typename
GUM_SCALAR
,
template
<
class
>
class
TerminalNodePolicy
>
142
INLINE
void
143
MultiDimFunctionGraph
<
GUM_SCALAR
,
TerminalNodePolicy
>::
erase
(
const
DiscreteVariable
&
v
) {
144
if
(
this
->
_var2NodeIdMap_
.
exists
(&
v
)) {
145
while
(
_var2NodeIdMap_
[&
v
]->
list
() !=
nullptr
) {
146
manager
()->
eraseNode
(
_var2NodeIdMap_
[&
v
]->
list
()->
element
());
147
}
148
delete
_var2NodeIdMap_
[&
v
];
149
_var2NodeIdMap_
.
erase
(&
v
);
150
}
151
152
if
(
this
->
variablesSequence
().
exists
(&
v
))
MultiDimImplementation
<
GUM_SCALAR
>::
erase
(
v
);
153
}
154
155
template
<
typename
GUM_SCALAR
,
template
<
class
>
class
TerminalNodePolicy
>
156
INLINE
Size
MultiDimFunctionGraph
<
GUM_SCALAR
,
TerminalNodePolicy
>::
realSize
()
const
{
157
return
_internalNodeMap_
.
size
();
// + _valueMap_.size();
158
}
159
160
161
template
<
typename
GUM_SCALAR
,
template
<
class
>
class
TerminalNodePolicy
>
162
INLINE
void
MultiDimFunctionGraph
<
GUM_SCALAR
,
TerminalNodePolicy
>::
changeNotification
(
163
const
Instantiation
&
i
,
164
const
DiscreteVariable
*
const
var
,
165
Idx
oldval
,
166
Idx
newval
) {}
167
168
template
<
typename
GUM_SCALAR
,
template
<
class
>
class
TerminalNodePolicy
>
169
INLINE
void
MultiDimFunctionGraph
<
GUM_SCALAR
,
TerminalNodePolicy
>::
setFirstNotification
(
170
const
Instantiation
&
i
) {}
171
172
template
<
typename
GUM_SCALAR
,
template
<
class
>
class
TerminalNodePolicy
>
173
INLINE
void
MultiDimFunctionGraph
<
GUM_SCALAR
,
TerminalNodePolicy
>::
setLastNotification
(
174
const
Instantiation
&
i
) {}
175
176
template
<
typename
GUM_SCALAR
,
template
<
class
>
class
TerminalNodePolicy
>
177
INLINE
void
MultiDimFunctionGraph
<
GUM_SCALAR
,
TerminalNodePolicy
>::
setIncNotification
(
178
const
Instantiation
&
i
) {}
179
180
template
<
typename
GUM_SCALAR
,
template
<
class
>
class
TerminalNodePolicy
>
181
INLINE
void
MultiDimFunctionGraph
<
GUM_SCALAR
,
TerminalNodePolicy
>::
setDecNotification
(
182
const
Instantiation
&
i
) {}
183
184
template
<
typename
GUM_SCALAR
,
template
<
class
>
class
TerminalNodePolicy
>
185
INLINE
void
MultiDimFunctionGraph
<
GUM_SCALAR
,
TerminalNodePolicy
>::
setChangeNotification
(
186
const
Instantiation
&
i
) {}
187
188
template
<
typename
GUM_SCALAR
,
template
<
class
>
class
TerminalNodePolicy
>
189
INLINE
std
::
string
MultiDimFunctionGraph
<
GUM_SCALAR
,
TerminalNodePolicy
>::
toString
(
190
const
Instantiation
*
i
)
const
{
191
std
::
stringstream
sBuff
;
192
sBuff
<< (*
i
) <<
" = "
<<
this
->
get
(*
i
);
193
return
sBuff
.
str
();
194
}
195
196
template
<
typename
GUM_SCALAR
,
template
<
class
>
class
TerminalNodePolicy
>
197
INLINE
void
MultiDimFunctionGraph
<
GUM_SCALAR
,
TerminalNodePolicy
>::
copyFrom
(
198
const
MultiDimContainer
<
GUM_SCALAR
>&
src
,
199
Instantiation
*
p_i
)
const
{
200
GUM_ERROR
(
OperationNotAllowed
,
201
"You cannot copy another type of multiDim "
202
"into a MultiDimFunctionGraph."
);
203
}
204
205
template
<
typename
GUM_SCALAR
,
template
<
class
>
class
TerminalNodePolicy
>
206
INLINE
void
MultiDimFunctionGraph
<
GUM_SCALAR
,
TerminalNodePolicy
>::
copy
(
207
const
MultiDimContainer
<
GUM_SCALAR
>&
src
) {
208
GUM_ERROR
(
OperationNotAllowed
,
209
"You cannot copy another type of multiDim "
210
"into a MultiDimFunctionGraph."
);
211
}
212
213
template
<
typename
GUM_SCALAR
,
template
<
class
>
class
TerminalNodePolicy
>
214
INLINE
void
MultiDimFunctionGraph
<
GUM_SCALAR
,
TerminalNodePolicy
>::
copy
(
215
const
MultiDimFunctionGraph
<
GUM_SCALAR
,
TerminalNodePolicy
>&
src
) {
216
if
(
this
->
_isReduced_
!=
src
.
isReducedAndOrdered
())
217
GUM_ERROR
(
OperationNotAllowed
,
218
"Cannot copy a Reduced and Ordered "
219
"function graph into Tree function graph "
220
"(or vice-versa)."
)
221
222
this
->
clear
();
223
224
// New variables insertion
225
for
(
SequenceIteratorSafe
<
const
DiscreteVariable
* >
varIter
226
=
src
.
variablesSequence
().
beginSafe
();
227
varIter
!=
src
.
variablesSequence
().
endSafe
();
228
++
varIter
)
229
this
->
add
(**
varIter
);
230
231
std
::
vector
<
NodeId
>
lifo
;
232
Bijection
<
NodeId
,
NodeId
>
src2dest
;
233
234
if
(
src
.
isTerminalNode
(
src
.
root
()))
235
this
->
manager
()->
setRootNode
(
this
->
manager
()->
addTerminalNode
(
src
.
nodeValue
(
src
.
root
())));
236
else
{
237
this
->
manager
()->
setRootNode
(
238
this
->
manager
()->
addInternalNode
(
src
.
node
(
src
.
root
())->
nodeVar
()));
239
src2dest
.
insert
(
src
.
root
(),
this
->
root
());
240
lifo
.
push_back
(
src
.
root
());
241
}
242
243
// Depth-first exploration and copy
244
while
(!
lifo
.
empty
()) {
245
NodeId
currentSrcNodeId
=
lifo
.
back
();
246
lifo
.
pop_back
();
247
248
const
InternalNode
*
currentSrcNode
=
src
.
node
(
currentSrcNodeId
);
249
250
for
(
Idx
index
= 0;
index
<
currentSrcNode
->
nbSons
(); ++
index
) {
251
if
(!
src2dest
.
existsFirst
(
currentSrcNode
->
son
(
index
))) {
252
NodeId
srcSonNodeId
=
currentSrcNode
->
son
(
index
),
destSonNodeId
= 0;
253
if
(
src
.
isTerminalNode
(
srcSonNodeId
)) {
254
destSonNodeId
=
this
->
manager
()->
addTerminalNode
(
src
.
nodeValue
(
srcSonNodeId
));
255
}
else
{
256
destSonNodeId
=
this
->
manager
()->
addInternalNode
(
src
.
node
(
srcSonNodeId
)->
nodeVar
());
257
lifo
.
push_back
(
srcSonNodeId
);
258
}
259
src2dest
.
insert
(
srcSonNodeId
,
destSonNodeId
);
260
}
261
this
->
manager
()->
setSon
(
src2dest
.
second
(
currentSrcNodeId
),
262
index
,
263
src2dest
.
second
(
currentSrcNode
->
son
(
index
)));
264
}
265
}
266
267
manager
()->
clean
();
268
}
269
270
// Copies src diagrams structure into this diagrams.
271
template
<
typename
GUM_SCALAR
,
template
<
class
>
class
TerminalNodePolicy
>
272
INLINE
void
MultiDimFunctionGraph
<
GUM_SCALAR
,
TerminalNodePolicy
>::
copyAndReassign
(
273
const
MultiDimFunctionGraph
<
GUM_SCALAR
,
TerminalNodePolicy
>&
src
,
274
const
Bijection
<
const
DiscreteVariable
*,
const
DiscreteVariable
* >&
reassign
) {
275
if
(
this
->
_isReduced_
!=
src
.
isReducedAndOrdered
())
276
GUM_ERROR
(
OperationNotAllowed
,
277
"Cannot copy a Reduced and Ordered "
278
"function graph into Tree function graph "
279
"(or vice-versa)."
)
280
281
this
->
clear
();
282
283
// New variables insertion
284
for
(
SequenceIteratorSafe
<
const
DiscreteVariable
* >
varIter
285
=
src
.
variablesSequence
().
beginSafe
();
286
varIter
!=
src
.
variablesSequence
().
endSafe
();
287
++
varIter
) {
288
if
((*
varIter
)->
domainSize
() !=
reassign
.
second
(*
varIter
)->
domainSize
())
289
GUM_ERROR
(
InvalidArgument
,
290
"Var "
<< (*
varIter
)->
name
() <<
" and var "
<<
reassign
.
second
(*
varIter
)->
name
()
291
<<
" have different domain sizes ("
<< (*
varIter
)->
domainSize
()
292
<<
"!="
<<
reassign
.
second
(*
varIter
)->
domainSize
() <<
")"
)
293
this
->
add
(*(
reassign
.
second
(*
varIter
)));
294
}
295
296
std
::
vector
<
NodeId
>
lifo
;
297
Bijection
<
NodeId
,
NodeId
>
src2dest
;
298
299
if
(
src
.
isTerminalNode
(
src
.
root
())) {
300
this
->
manager
()->
setRootNode
(
this
->
manager
()->
addTerminalNode
(
src
.
nodeValue
(
src
.
root
())));
301
}
else
{
302
this
->
manager
()->
setRootNode
(
303
this
->
manager
()->
addInternalNode
(
reassign
.
second
(
src
.
node
(
src
.
root
())->
nodeVar
())));
304
src2dest
.
insert
(
src
.
root
(),
this
->
root
());
305
lifo
.
push_back
(
src
.
root
());
306
}
307
308
// Depth-first exploration and copy
309
while
(!
lifo
.
empty
()) {
310
NodeId
currentSrcNodeId
=
lifo
.
back
();
311
lifo
.
pop_back
();
312
313
const
InternalNode
*
currentSrcNode
=
src
.
node
(
currentSrcNodeId
);
314
315
for
(
Idx
index
= 0;
index
<
currentSrcNode
->
nbSons
(); ++
index
) {
316
if
(!
src2dest
.
existsFirst
(
currentSrcNode
->
son
(
index
))) {
317
NodeId
srcSonNodeId
=
currentSrcNode
->
son
(
index
),
destSonNodeId
= 0;
318
if
(
src
.
isTerminalNode
(
srcSonNodeId
)) {
319
destSonNodeId
=
this
->
manager
()->
addTerminalNode
(
src
.
nodeValue
(
srcSonNodeId
));
320
}
else
{
321
destSonNodeId
=
this
->
manager
()->
addInternalNode
(
322
reassign
.
second
(
src
.
node
(
srcSonNodeId
)->
nodeVar
()));
323
lifo
.
push_back
(
srcSonNodeId
);
324
}
325
src2dest
.
insert
(
srcSonNodeId
,
destSonNodeId
);
326
}
327
this
->
manager
()->
setSon
(
src2dest
.
second
(
currentSrcNodeId
),
328
index
,
329
src2dest
.
second
(
currentSrcNode
->
son
(
index
)));
330
}
331
}
332
333
manager
()->
clean
();
334
}
335
336
// Copies src diagrams and multiply every value by the given scalar.
337
template
<
typename
GUM_SCALAR
,
template
<
class
>
class
TerminalNodePolicy
>
338
INLINE
void
MultiDimFunctionGraph
<
GUM_SCALAR
,
TerminalNodePolicy
>::
copyAndMultiplyByScalar
(
339
const
MultiDimFunctionGraph
<
GUM_SCALAR
,
TerminalNodePolicy
>&
src
,
340
GUM_SCALAR
gamma
) {
341
if
(
this
->
_isReduced_
!=
src
.
isReducedAndOrdered
())
342
GUM_ERROR
(
OperationNotAllowed
,
343
"Cannot copy a Reduced and Ordered "
344
"function graph into Tree function graph "
345
"(or vice-versa)."
)
346
347
this
->
clear
();
348
349
// New variables insertion
350
for
(
SequenceIteratorSafe
<
const
DiscreteVariable
* >
varIter
351
=
src
.
variablesSequence
().
beginSafe
();
352
varIter
!=
src
.
variablesSequence
().
endSafe
();
353
++
varIter
)
354
this
->
add
(**
varIter
);
355
356
std
::
vector
<
NodeId
>
lifo
;
357
HashTable
<
NodeId
,
NodeId
>
src2dest
;
358
359
if
(
src
.
isTerminalNode
(
src
.
root
()))
360
this
->
manager
()->
setRootNode
(
361
this
->
manager
()->
addTerminalNode
(
gamma
*
src
.
nodeValue
(
src
.
root
())));
362
else
{
363
this
->
manager
()->
setRootNode
(
364
this
->
manager
()->
addInternalNode
(
src
.
node
(
src
.
root
())->
nodeVar
()));
365
src2dest
.
insert
(
src
.
root
(),
this
->
root
());
366
lifo
.
push_back
(
src
.
root
());
367
}
368
369
// Depth-first exploration an copy
370
while
(!
lifo
.
empty
()) {
371
NodeId
currentSrcNodeId
=
lifo
.
back
();
372
lifo
.
pop_back
();
373
374
const
InternalNode
*
currentSrcNode
=
src
.
node
(
currentSrcNodeId
);
375
376
for
(
Idx
index
= 0;
index
<
currentSrcNode
->
nbSons
(); ++
index
) {
377
if
(!
src2dest
.
exists
(
currentSrcNode
->
son
(
index
))) {
378
NodeId
srcSonNodeId
=
currentSrcNode
->
son
(
index
),
destSonNodeId
= 0;
379
if
(
src
.
isTerminalNode
(
srcSonNodeId
)) {
380
destSonNodeId
=
this
->
manager
()->
addTerminalNode
(
gamma
*
src
.
nodeValue
(
srcSonNodeId
));
381
}
else
{
382
destSonNodeId
=
this
->
manager
()->
addInternalNode
(
src
.
node
(
srcSonNodeId
)->
nodeVar
());
383
lifo
.
push_back
(
srcSonNodeId
);
384
}
385
src2dest
.
insert
(
srcSonNodeId
,
destSonNodeId
);
386
}
387
this
->
manager
()->
setSon
(
src2dest
[
currentSrcNodeId
],
388
index
,
389
src2dest
[
currentSrcNode
->
son
(
index
)]);
390
}
391
}
392
393
manager
()->
clean
();
394
}
395
396
// Clears the function graph
397
template
<
typename
GUM_SCALAR
,
template
<
class
>
class
TerminalNodePolicy
>
398
INLINE
void
MultiDimFunctionGraph
<
GUM_SCALAR
,
TerminalNodePolicy
>::
clear
() {
399
_model_
.
clear
();
400
// Always discard the nodeId 0
401
_model_
.
addNode
();
402
403
this
->
clearAllTerminalNodes
();
404
405
// Nodes cleaning
406
for
(
HashTableIterator
<
NodeId
,
InternalNode
* >
nodeIter
=
_internalNodeMap_
.
begin
();
407
nodeIter
!=
_internalNodeMap_
.
end
();
408
++
nodeIter
) {
409
delete
nodeIter
.
val
();
410
}
411
_internalNodeMap_
.
clear
();
412
413
// Cleaning the list of nodes for each variables
414
for
(
HashTableIterator
<
const
DiscreteVariable
*,
LinkedList
<
NodeId
>* >
varIter
415
=
_var2NodeIdMap_
.
begin
();
416
varIter
!=
_var2NodeIdMap_
.
end
();
417
++
varIter
) {
418
delete
varIter
.
val
();
419
}
420
_var2NodeIdMap_
.
clear
();
421
422
for
(
SequenceIteratorSafe
<
const
DiscreteVariable
* >
varIter
423
=
this
->
variablesSequence
().
rbeginSafe
();
424
varIter
!=
this
->
variablesSequence
().
rendSafe
();
425
--
varIter
) {
426
this
->
erase
(**
varIter
);
427
}
428
}
429
430
431
template
<
typename
GUM_SCALAR
,
template
<
class
>
class
TerminalNodePolicy
>
432
INLINE
std
::
string
433
MultiDimFunctionGraph
<
GUM_SCALAR
,
TerminalNodePolicy
>::
toDot
(
bool
withBackArcs
)
const
{
434
std
::
stringstream
output
;
435
std
::
stringstream
terminalStream
;
436
std
::
stringstream
nonTerminalStream
;
437
std
::
stringstream
arcstream
;
438
// std::stringstream defaultarcstream;
439
output
<<
std
::
endl
<<
"digraph \" "
<<
_tableName_
<<
"\" {"
<<
std
::
endl
;
440
441
terminalStream
<<
"node [shape = box];"
<<
std
::
endl
;
442
nonTerminalStream
<<
"node [shape = ellipse];"
<<
std
::
endl
;
443
std
::
string
tab
=
" "
;
444
445
for
(
NodeGraphPart
::
NodeIterator
nodeIter
=
_model_
.
begin
();
nodeIter
!=
_model_
.
end
();
446
++
nodeIter
)
447
if
(*
nodeIter
!= 0) {
448
if
(
this
->
isTerminalNode
((
NodeId
)*
nodeIter
))
449
terminalStream
<<
tab
<< *
nodeIter
<<
";"
<<
tab
<< *
nodeIter
<<
" [label=\""
<< *
nodeIter
450
<<
" - "
<<
std
::
setprecision
(30) <<
this
->
terminalNodeValue
(*
nodeIter
)
451
<<
"\"]"
452
<<
";"
<<
std
::
endl
;
453
else
{
454
InternalNode
*
currentNode
=
_internalNodeMap_
[*
nodeIter
];
455
nonTerminalStream
<<
tab
<< *
nodeIter
<<
";"
<<
tab
<< *
nodeIter
<<
" [label=\""
456
<< *
nodeIter
<<
" - "
<<
currentNode
->
nodeVar
()->
name
() <<
"\"]"
457
<<
";"
<<
std
::
endl
;
458
459
// if (arcMap_[*nodeIter] != NULL)
460
HashTable
<
NodeId
,
LinkedList
<
Idx
>* >
sonMap
;
461
for
(
Idx
sonIter
= 0;
sonIter
<
currentNode
->
nbSons
(); ++
sonIter
) {
462
if
(!
sonMap
.
exists
(
currentNode
->
son
(
sonIter
)))
463
sonMap
.
insert
(
currentNode
->
son
(
sonIter
),
new
LinkedList
<
Idx
>());
464
sonMap
[
currentNode
->
son
(
sonIter
)]->
addLink
(
sonIter
);
465
}
466
467
for
(
auto
sonIter
=
sonMap
.
beginSafe
();
sonIter
!=
sonMap
.
endSafe
(); ++
sonIter
) {
468
arcstream
<<
tab
<< *
nodeIter
<<
" -> "
<<
sonIter
.
key
() <<
" [label=\" "
;
469
Link
<
Idx
>*
modaIter
=
sonIter
.
val
()->
list
();
470
while
(
modaIter
) {
471
arcstream
<<
currentNode
->
nodeVar
()->
label
(
modaIter
->
element
()) <<
", "
;
472
modaIter
=
modaIter
->
nextLink
();
473
}
474
arcstream
<<
"\",color=\"#0000ff\"]"
475
<<
";"
<<
std
::
endl
;
476
delete
sonIter
.
val
();
477
}
478
479
if
(
withBackArcs
) {
480
Link
<
Parent
>*
parentIter
=
currentNode
->
parents
();
481
while
(
parentIter
!=
nullptr
) {
482
arcstream
<<
tab
<< *
nodeIter
<<
" -> "
<<
parentIter
->
element
().
parentId
483
<<
" [label=\""
<<
parentIter
->
element
().
modality
<<
"\",color=\"#ff0000\"]"
484
<<
";"
<<
std
::
endl
;
485
parentIter
=
parentIter
->
nextLink
();
486
}
487
}
488
}
489
}
490
491
output
<<
terminalStream
.
str
() <<
std
::
endl
492
<<
nonTerminalStream
.
str
() <<
std
::
endl
493
<<
arcstream
.
str
() <<
std
::
endl
494
<<
"}"
<<
std
::
endl
;
495
496
return
output
.
str
();
497
}
498
499
// Returns a const reference to the manager of this diagram
500
template
<
typename
GUM_SCALAR
,
template
<
class
>
class
TerminalNodePolicy
>
501
INLINE
const
NodeGraphPart
&
502
MultiDimFunctionGraph
<
GUM_SCALAR
,
TerminalNodePolicy
>::
model
()
const
{
503
return
_model_
;
504
}
505
506
// Returns a const reference to the manager of this diagram
507
template
<
typename
GUM_SCALAR
,
template
<
class
>
class
TerminalNodePolicy
>
508
INLINE
MultiDimFunctionGraphManager
<
GUM_SCALAR
,
TerminalNodePolicy
>*
509
MultiDimFunctionGraph
<
GUM_SCALAR
,
TerminalNodePolicy
>::
manager
() {
510
if
(
_manager_
==
nullptr
) {
511
if
(
_isReduced_
)
512
_manager_
=
new
MultiDimFunctionGraphROManager
<
GUM_SCALAR
,
TerminalNodePolicy
>(
this
);
513
else
514
_manager_
=
new
MultiDimFunctionGraphTreeManager
<
GUM_SCALAR
,
TerminalNodePolicy
>(
this
);
515
}
516
return
_manager_
;
517
}
518
519
// Returns the id of the root node from the diagram
520
template
<
typename
GUM_SCALAR
,
template
<
class
>
class
TerminalNodePolicy
>
521
INLINE
const
NodeId
&
MultiDimFunctionGraph
<
GUM_SCALAR
,
TerminalNodePolicy
>::
root
()
const
{
522
return
_root_
;
523
}
524
525
// Indicates if given node is terminal or not
526
template
<
typename
GUM_SCALAR
,
template
<
class
>
class
TerminalNodePolicy
>
527
INLINE
bool
MultiDimFunctionGraph
<
GUM_SCALAR
,
TerminalNodePolicy
>::
isTerminalNode
(
528
const
NodeId
&
node
)
const
{
529
return
this
->
existsTerminalNodeWithId
(
node
);
530
}
531
532
// Indicates if given node is terminal or not
533
template
<
typename
GUM_SCALAR
,
template
<
class
>
class
TerminalNodePolicy
>
534
INLINE
bool
MultiDimFunctionGraph
<
GUM_SCALAR
,
TerminalNodePolicy
>::
isInternalNode
(
535
const
NodeId
&
node
)
const
{
536
return
this
->
_internalNodeMap_
.
exists
(
node
);
537
}
538
539
// Returns value associated to given node.
540
template
<
typename
GUM_SCALAR
,
template
<
class
>
class
TerminalNodePolicy
>
541
INLINE
const
GUM_SCALAR
&
542
MultiDimFunctionGraph
<
GUM_SCALAR
,
TerminalNodePolicy
>::
nodeValue
(
NodeId
n
)
const
{
543
if
(!
isTerminalNode
(
n
))
544
GUM_ERROR
(
InvalidArgument
,
"Id "
<<
n
<<
" is not bound to any terminal node"
)
545
return
this
->
terminalNodeValue
(
n
);
546
}
547
548
// Returns internalNode structure associated to that nodeId
549
template
<
typename
GUM_SCALAR
,
template
<
class
>
class
TerminalNodePolicy
>
550
INLINE
const
InternalNode
*
551
MultiDimFunctionGraph
<
GUM_SCALAR
,
TerminalNodePolicy
>::
node
(
NodeId
n
)
const
{
552
if
(!
isInternalNode
(
n
))
553
GUM_ERROR
(
InvalidArgument
,
"Id "
<<
n
<<
" is not bound to any terminal node"
)
554
return
this
->
_internalNodeMap_
[
n
];
555
}
556
557
// Returns the list of node associated to given variable
558
template
<
typename
GUM_SCALAR
,
template
<
class
>
class
TerminalNodePolicy
>
559
INLINE
const
LinkedList
<
NodeId
>*
560
MultiDimFunctionGraph
<
GUM_SCALAR
,
TerminalNodePolicy
>::
varNodeListe
(
561
const
DiscreteVariable
*
var
)
const
{
562
if
(!
this
->
variablesSequence
().
exists
(
var
))
563
GUM_ERROR
(
InvalidArgument
,
564
"Var "
<<
var
->
name
() <<
" has not been inserted in the function graph"
)
565
return
_var2NodeIdMap_
[
var
];
566
}
567
568
// Returns the name of the table represented by this structure.
569
template
<
typename
GUM_SCALAR
,
template
<
class
>
class
TerminalNodePolicy
>
570
INLINE
const
std
::
string
&
571
MultiDimFunctionGraph
<
GUM_SCALAR
,
TerminalNodePolicy
>::
tableName
()
const
{
572
return
_tableName_
;
573
}
574
575
// Sets the name of the table represented by this structure.
576
template
<
typename
GUM_SCALAR
,
template
<
class
>
class
TerminalNodePolicy
>
577
INLINE
void
MultiDimFunctionGraph
<
GUM_SCALAR
,
TerminalNodePolicy
>::
setTableName
(
578
const
std
::
string
&
name
) {
579
_tableName_
=
name
;
580
}
581
582
// Returns true if this MultiDimFunctionGraph is reduced and Ordered.
583
template
<
typename
GUM_SCALAR
,
template
<
class
>
class
TerminalNodePolicy
>
584
INLINE
bool
MultiDimFunctionGraph
<
GUM_SCALAR
,
TerminalNodePolicy
>::
isReducedAndOrdered
()
const
{
585
return
_isReduced_
;
586
}
587
588
// Returns a reduced and ordered instance.
589
template
<
typename
GUM_SCALAR
,
template
<
class
>
class
TerminalNodePolicy
>
590
INLINE
MultiDimFunctionGraph
<
GUM_SCALAR
,
TerminalNodePolicy
>*
591
MultiDimFunctionGraph
<
GUM_SCALAR
,
TerminalNodePolicy
>::
getReducedAndOrderedInstance
() {
592
return
new
MultiDimFunctionGraph
<
GUM_SCALAR
,
TerminalNodePolicy
>();
593
}
594
595
// Returns an arborescent instance
596
template
<
typename
GUM_SCALAR
,
template
<
class
>
class
TerminalNodePolicy
>
597
INLINE
MultiDimFunctionGraph
<
GUM_SCALAR
,
TerminalNodePolicy
>*
598
MultiDimFunctionGraph
<
GUM_SCALAR
,
TerminalNodePolicy
>::
getTreeInstance
() {
599
return
new
MultiDimFunctionGraph
<
GUM_SCALAR
,
TerminalNodePolicy
>(
false
);
600
}
601
602
// Not implemented yet
603
template
<
typename
GUM_SCALAR
,
template
<
class
>
class
TerminalNodePolicy
>
604
INLINE
void
605
MultiDimFunctionGraph
<
GUM_SCALAR
,
TerminalNodePolicy
>::
replace_
(
const
DiscreteVariable
*
x
,
606
const
DiscreteVariable
*
y
) {
607
GUM_ERROR
(
OperationNotAllowed
,
"Not Implemented Yet"
)
608
}
609
610
template
<
typename
GUM_SCALAR
,
template
<
class
>
class
TerminalNodePolicy
>
611
INLINE
GUM_SCALAR
&
MultiDimFunctionGraph
<
GUM_SCALAR
,
TerminalNodePolicy
>::
get_
(
612
const
Instantiation
&
inst
)
const
{
613
GUM_ERROR
(
OperationNotAllowed
,
"You can't edit a function by other mean than the manager"
)
614
}
615
616
// Return a data, given a Instantiation.
617
template
<
typename
GUM_SCALAR
,
template
<
class
>
class
TerminalNodePolicy
>
618
INLINE
GUM_SCALAR
619
MultiDimFunctionGraph
<
GUM_SCALAR
,
TerminalNodePolicy
>::
get
(
const
Instantiation
&
inst
)
const
{
620
NodeId
currentNodeId
=
_root_
;
621
InternalNode
*
currentNode
=
nullptr
;
622
while
(!
isTerminalNode
(
currentNodeId
)) {
623
currentNode
=
_internalNodeMap_
[
currentNodeId
];
624
currentNodeId
=
currentNode
->
son
(
inst
.
val
(*(
currentNode
->
nodeVar
())));
625
}
626
return
this
->
terminalNodeValue
(
currentNodeId
);
627
}
628
629
}
// namespace gum
gum::Set::emplace
INLINE void emplace(Args &&... args)
Definition:
set_tpl.h:643