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