aGrUM
0.20.3
a C++ library for (probabilistic) graphical models
interfaceGraph_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 Inline implementation of gum::InterfaceGraph.
25
*
26
* @author Lionel TORTI and Pierre-Henri WUILLEMIN(@LIP6)
27
*/
28
29
namespace
gum
{
30
namespace
prm
{
31
namespace
gspan
{
32
33
// NodeData
34
35
template
<
typename
GUM_SCALAR >
36
INLINE NodeData<
GUM_SCALAR
>::
NodeData
() :
n
(0),
l
(0) {
37
GUM_CONSTRUCTOR
(
NodeData
);
38
}
39
40
template
<
typename
GUM_SCALAR
>
41
INLINE
NodeData
<
GUM_SCALAR
>::
NodeData
(
const
NodeData
<
GUM_SCALAR
>&
from
) :
42
n
(
from
.
n
),
l
(
from
.
l
) {
43
GUM_CONS_CPY
(
NodeData
);
44
}
45
46
template
<
typename
GUM_SCALAR
>
47
INLINE
NodeData
<
GUM_SCALAR
>::~
NodeData
() {
48
GUM_DESTRUCTOR
(
NodeData
);
49
}
50
51
template
<
typename
GUM_SCALAR
>
52
INLINE
bool
NodeData
<
GUM_SCALAR
>::
operator
==(
const
NodeData
<
GUM_SCALAR
>&
from
)
const
{
53
return
(
n
==
from
.
n
) && (
l
==
from
.
l
);
54
}
55
56
template
<
typename
GUM_SCALAR
>
57
INLINE
bool
NodeData
<
GUM_SCALAR
>::
operator
!=(
const
NodeData
<
GUM_SCALAR
>&
from
)
const
{
58
return
(
n
!=
from
.
n
) && (
l
!=
from
.
l
);
59
}
60
61
// EdgeData<GUM_SCALAR>
62
63
template
<
typename
GUM_SCALAR
>
64
INLINE
EdgeData
<
GUM_SCALAR
>::
EdgeData
() :
u
(0),
v
(0),
l
(0) {
65
GUM_CONSTRUCTOR
(
EdgeData
);
66
}
67
68
template
<
typename
GUM_SCALAR
>
69
INLINE
EdgeData
<
GUM_SCALAR
>::
EdgeData
(
const
EdgeData
<
GUM_SCALAR
>&
from
) :
70
u
(
from
.
u
),
v
(
from
.
v
),
l
(
from
.
l
) {
71
GUM_CONS_CPY
(
EdgeData
);
72
}
73
74
template
<
typename
GUM_SCALAR
>
75
INLINE
EdgeData
<
GUM_SCALAR
>::~
EdgeData
() {
76
GUM_DESTRUCTOR
(
EdgeData
);
77
}
78
79
template
<
typename
GUM_SCALAR
>
80
INLINE
bool
EdgeData
<
GUM_SCALAR
>::
operator
==(
const
EdgeData
<
GUM_SCALAR
>&
from
)
const
{
81
return
(
u
==
from
.
u
) && (
l_u
==
from
.
l_u
) && (
v
==
from
.
v
) && (
l_v
==
from
.
l_v
)
82
&& (
l
==
from
.
l
);
83
}
84
85
template
<
typename
GUM_SCALAR
>
86
INLINE
bool
EdgeData
<
GUM_SCALAR
>::
operator
!=(
const
EdgeData
<
GUM_SCALAR
>&
from
)
const
{
87
return
(
u
!=
from
.
u
) && (
l_u
!=
from
.
l_u
) && (
v
!=
from
.
v
) && (
l_v
!=
from
.
l_v
)
88
&& (
l
!=
from
.
l
);
89
}
90
91
// InterfaceGraph
92
93
template
<
typename
GUM_SCALAR
>
94
InterfaceGraph
<
GUM_SCALAR
>::
InterfaceGraph
(
const
PRMSystem
<
GUM_SCALAR
>&
sys
) :
95
_sys_
(&
sys
),
_labels_
(
new
Bijection
<
Idx
,
LabelData
* >()),
_counter_
(0),
96
_erase_flag_
(
true
) {
97
GUM_CONSTRUCTOR
(
InterfaceGraph
);
98
HashTable
<
std
::
string
,
LabelData
* >
label_map
;
99
100
// We need to add each instance in _graph_
101
for
(
auto
iter
=
sys
.
begin
();
iter
!=
sys
.
end
(); ++
iter
) {
102
NodeData
<
GUM_SCALAR
>*
node
=
new
NodeData
<
GUM_SCALAR
>();
103
node
->
n
=
iter
.
val
();
104
_label_
(
node
,
label_map
);
105
_graph_
.
addNodeWithId
(
iter
.
key
());
106
_idMap_
.
insert
(
node
->
n
,
iter
.
key
());
107
_nodes_
.
insert
(
iter
.
key
(),
node
);
108
}
109
110
NodeData
<
GUM_SCALAR
>*
u
=
nullptr
;
111
NodeData
<
GUM_SCALAR
>*
v
=
nullptr
;
112
113
for
(
const
auto
&
elt
:
_nodes_
) {
114
NodeData
<
GUM_SCALAR
>*
data
=
elt
.
second
;
115
116
for
(
const
auto
chain
:
data
->
n
->
type
().
slotChains
()) {
117
for
(
const
auto
inst
:
data
->
n
->
getInstances
(
chain
->
id
())) {
118
u
= (
_nodes_
[
_idMap_
[
inst
]]->
l
<
data
->
l
) ?
_nodes_
[
_idMap_
[
inst
]] :
data
;
119
v
= (
u
!=
data
) ?
data
:
_nodes_
[
_idMap_
[
inst
]];
120
121
if
(!
_graph_
.
existsEdge
(
_idMap_
[
u
->
n
],
_idMap_
[
v
->
n
])) {
122
EdgeData
<
GUM_SCALAR
>*
edge
=
new
EdgeData
<
GUM_SCALAR
>();
123
edge
->
u
=
u
->
n
;
124
edge
->
l_u
=
u
->
l
;
125
edge
->
v
=
v
->
n
;
126
edge
->
l_v
=
v
->
l
;
127
_label_
(
edge
,
label_map
);
128
_graph_
.
addEdge
(
_idMap_
[
u
->
n
],
_idMap_
[
v
->
n
]);
129
_edges_
.
insert
(
Edge
(
_idMap_
[
u
->
n
],
_idMap_
[
v
->
n
]),
edge
);
130
}
131
}
132
}
133
}
134
}
135
136
template
<
typename
GUM_SCALAR
>
137
InterfaceGraph
<
GUM_SCALAR
>::
InterfaceGraph
(
const
InterfaceGraph
<
GUM_SCALAR
>&
source
) :
138
_sys_
(
source
.
_sys_
),
_graph_
(
source
.
_graph_
),
_nodes_
(
source
.
_nodes_
),
139
_idMap_
(
source
.
_idMap_
),
_edges_
(
source
.
_edges_
),
140
_labels_
(
new
Bijection
<
Idx
,
LabelData
* >(*(
source
.
_labels_
))),
141
_nodeMap_
(
source
.
_nodeMap_
),
_edgeMap_
(
source
.
_edgeMap_
),
_counter_
(
source
.
_counter_
),
142
_erase_flag_
(
false
) {
143
GUM_CONS_CPY
(
InterfaceGraph
);
144
}
145
146
template
<
typename
GUM_SCALAR
>
147
InterfaceGraph
<
GUM_SCALAR
>::~
InterfaceGraph
() {
148
GUM_DESTRUCTOR
(
InterfaceGraph
);
149
150
if
(
_erase_flag_
) {
151
for
(
const
auto
&
elt
:
_nodes_
)
152
delete
elt
.
second
;
153
154
for
(
const
auto
&
elt
:
_edges_
)
155
delete
elt
.
second
;
156
157
for
(
const
auto
&
elt
:
_nodeMap_
) {
158
delete
elt
.
first
;
159
delete
elt
.
second
;
160
}
161
162
for
(
const
auto
&
elt
:
_edgeMap_
) {
163
delete
elt
.
first
;
164
delete
elt
.
second
;
165
}
166
}
167
168
delete
_labels_
;
169
}
170
171
template
<
typename
GUM_SCALAR
>
172
InterfaceGraph
<
GUM_SCALAR
>&
173
InterfaceGraph
<
GUM_SCALAR
>::
operator
=(
const
InterfaceGraph
<
GUM_SCALAR
>&
source
) {
174
GUM_ERROR
(
FatalError
,
"not implemented"
)
175
}
176
177
template
<
typename
GUM_SCALAR
>
178
void
InterfaceGraph
<
GUM_SCALAR
>::
_label_
(
NodeData
<
GUM_SCALAR
>*
node
,
179
HashTable
<
std
::
string
,
LabelData
* >&
label_map
) {
180
Size
size
=
Size
(1);
181
std
::
stringstream
sBuff
;
182
sBuff
<<
node
->
n
->
type
().
name
();
183
184
// First we search for multiple inputs
185
for
(
const
auto
chain
:
node
->
n
->
type
().
slotChains
()) {
186
if
(
chain
->
isMultiple
()) {
187
sBuff
<<
"-"
<<
node
->
n
->
getInstances
(
chain
->
id
()).
size
();
188
sBuff
<<
chain
->
name
();
189
size
*=
node
->
n
->
getInstances
(
chain
->
id
()).
size
()
190
*
chain
->
lastElt
().
type
().
variable
().
domainSize
();
191
}
else
{
192
size
*=
chain
->
lastElt
().
type
().
variable
().
domainSize
();
193
}
194
}
195
196
// Second we search for active outputs
197
for
(
const
auto
nn
:
node
->
n
->
type
().
containerDag
().
nodes
()) {
198
if
(
node
->
n
->
type
().
isOutputNode
(
node
->
n
->
type
().
get
(
nn
))) {
199
try
{
200
sBuff
<<
"-"
<<
node
->
n
->
getRefAttr
(
nn
).
size
() <<
node
->
n
->
get
(
nn
).
name
();
201
size
*=
node
->
n
->
get
(
nn
).
type
().
variable
().
domainSize
();
202
}
catch
(
NotFound
&) {
203
// (nn) is an inactive output node
204
}
205
}
206
}
207
208
// Label is ready
209
if
(!
label_map
.
exists
(
sBuff
.
str
())) {
210
LabelData
*
label
=
new
LabelData
();
211
label_map
.
insert
(
sBuff
.
str
(),
label
);
212
label
->
id
= ++
_counter_
;
213
label
->
tree_width
=
size
;
214
label
->
l
=
sBuff
.
str
();
215
_labels_
->
insert
(
label
->
id
,
label
);
216
_nodeMap_
.
insert
(
label
,
new
Set
<
NodeData
<
GUM_SCALAR
>* >());
217
}
218
219
node
->
l
=
label_map
[
sBuff
.
str
()];
220
_nodeMap_
[
node
->
l
]->
insert
(
node
);
221
}
222
223
template
<
typename
GUM_SCALAR
>
224
void
InterfaceGraph
<
GUM_SCALAR
>::
_label_
(
EdgeData
<
GUM_SCALAR
>*
edge
,
225
HashTable
<
std
::
string
,
LabelData
* >&
label_map
) {
226
Size
size
=
Size
(1);
227
std
::
stringstream
sBuff
;
228
sBuff
<<
edge
->
u
->
type
().
name
() <<
"-"
<<
edge
->
v
->
type
().
name
();
229
230
// First looking for edge->u output nodes in v
231
for
(
const
auto
chain
:
edge
->
u
->
type
().
slotChains
()) {
232
if
(
edge
->
u
->
getInstances
(
chain
->
id
()).
exists
(
edge
->
v
)) {
233
sBuff
<<
"-"
<<
edge
->
v
->
type
().
name
() <<
"."
<<
chain
->
lastElt
().
name
();
234
size
*=
chain
->
lastElt
().
type
().
variable
().
domainSize
();
235
}
236
}
237
238
// Second looking for edge->v output nodes in u
239
for
(
const
auto
chain
:
edge
->
v
->
type
().
slotChains
())
240
if
(
edge
->
v
->
getInstances
(
chain
->
id
()).
exists
(
edge
->
u
)) {
241
sBuff
<<
"-"
<<
edge
->
u
->
type
().
name
() <<
"."
<<
chain
->
lastElt
().
name
();
242
size
*=
chain
->
lastElt
().
type
().
variable
().
domainSize
();
243
}
244
245
// Label is ready
246
if
(!
label_map
.
exists
(
sBuff
.
str
())) {
247
LabelData
*
label
=
new
LabelData
();
248
label_map
.
insert
(
sBuff
.
str
(),
label
);
249
label
->
id
= ++
_counter_
;
250
label
->
l
=
sBuff
.
str
();
251
label
->
tree_width
=
size
;
252
_labels_
->
insert
(
label
->
id
,
label
);
253
_edgeMap_
.
insert
(
label
,
new
Set
<
EdgeData
<
GUM_SCALAR
>* >());
254
}
255
256
edge
->
l
=
label_map
[
sBuff
.
str
()];
257
_edgeMap_
[
edge
->
l
]->
insert
(
edge
);
258
}
259
260
template
<
typename
GUM_SCALAR
>
261
INLINE
UndiGraph
&
InterfaceGraph
<
GUM_SCALAR
>::
graph
() {
262
return
_graph_
;
263
}
264
265
template
<
typename
GUM_SCALAR
>
266
INLINE
const
UndiGraph
&
InterfaceGraph
<
GUM_SCALAR
>::
graph
()
const
{
267
return
_graph_
;
268
}
269
270
template
<
typename
GUM_SCALAR
>
271
INLINE
Bijection
<
Idx
,
LabelData
* >&
InterfaceGraph
<
GUM_SCALAR
>::
labels
() {
272
return
*
_labels_
;
273
}
274
275
template
<
typename
GUM_SCALAR
>
276
INLINE
const
Bijection
<
Idx
,
LabelData
* >&
InterfaceGraph
<
GUM_SCALAR
>::
labels
()
const
{
277
return
*
_labels_
;
278
}
279
280
template
<
typename
GUM_SCALAR
>
281
INLINE
Size
InterfaceGraph
<
GUM_SCALAR
>::
size
(
const
LabelData
*
l
)
const
{
282
try
{
283
return
_nodeMap_
[
const_cast
<
LabelData
* >(
l
)]->
size
();
284
}
catch
(
NotFound
&) {
return
_edgeMap_
[
const_cast
<
LabelData
* >(
l
)]->
size
(); }
285
}
286
287
template
<
typename
GUM_SCALAR
>
288
INLINE
Set
<
NodeData
<
GUM_SCALAR
>* >&
289
InterfaceGraph
<
GUM_SCALAR
>::
nodes
(
const
LabelData
*
l
) {
290
return
*(
_nodeMap_
[
const_cast
<
LabelData
* >(
l
)]);
291
}
292
293
template
<
typename
GUM_SCALAR
>
294
INLINE
const
Set
<
NodeData
<
GUM_SCALAR
>* >&
295
InterfaceGraph
<
GUM_SCALAR
>::
nodes
(
const
LabelData
*
l
)
const
{
296
return
*(
_nodeMap_
[
const_cast
<
LabelData
* >(
l
)]);
297
}
298
299
template
<
typename
GUM_SCALAR
>
300
INLINE
Set
<
EdgeData
<
GUM_SCALAR
>* >&
301
InterfaceGraph
<
GUM_SCALAR
>::
edges
(
const
LabelData
*
l
) {
302
return
*(
_edgeMap_
[
const_cast
<
LabelData
* >(
l
)]);
303
}
304
305
template
<
typename
GUM_SCALAR
>
306
INLINE
const
Set
<
EdgeData
<
GUM_SCALAR
>* >&
307
InterfaceGraph
<
GUM_SCALAR
>::
edges
(
const
LabelData
*
l
)
const
{
308
return
*(
_edgeMap_
[
const_cast
<
LabelData
* >(
l
)]);
309
}
310
311
template
<
typename
GUM_SCALAR
>
312
INLINE
LabelData
*
InterfaceGraph
<
GUM_SCALAR
>::
label
(
Idx
id
) {
313
return
_labels_
->
second
(
id
);
314
}
315
316
template
<
typename
GUM_SCALAR
>
317
INLINE
NodeId
InterfaceGraph
<
GUM_SCALAR
>::
id
(
const
PRMInstance
<
GUM_SCALAR
>&
i
)
const
{
318
return
_idMap_
[
const_cast
<
PRMInstance
<
GUM_SCALAR
>* >(&
i
)];
319
}
320
321
template
<
typename
GUM_SCALAR
>
322
INLINE
NodeId
InterfaceGraph
<
GUM_SCALAR
>::
id
(
const
PRMInstance
<
GUM_SCALAR
>*
i
)
const
{
323
return
_idMap_
[
const_cast
<
PRMInstance
<
GUM_SCALAR
>* >(
i
)];
324
}
325
326
template
<
typename
GUM_SCALAR
>
327
INLINE
NodeData
<
GUM_SCALAR
>&
328
InterfaceGraph
<
GUM_SCALAR
>::
node
(
const
PRMInstance
<
GUM_SCALAR
>*
i
) {
329
return
node
(
id
(
i
));
330
}
331
332
template
<
typename
GUM_SCALAR
>
333
INLINE
const
NodeData
<
GUM_SCALAR
>&
334
InterfaceGraph
<
GUM_SCALAR
>::
node
(
const
PRMInstance
<
GUM_SCALAR
>*
i
)
const
{
335
return
node
(
id
(
i
));
336
}
337
338
template
<
typename
GUM_SCALAR
>
339
INLINE
NodeData
<
GUM_SCALAR
>&
InterfaceGraph
<
GUM_SCALAR
>::
node
(
NodeId
id
) {
340
return
*(
_nodes_
[
id
]);
341
}
342
343
template
<
typename
GUM_SCALAR
>
344
INLINE
const
NodeData
<
GUM_SCALAR
>&
InterfaceGraph
<
GUM_SCALAR
>::
node
(
NodeId
id
)
const
{
345
return
*(
_nodes_
[
id
]);
346
}
347
348
template
<
typename
GUM_SCALAR
>
349
INLINE
EdgeData
<
GUM_SCALAR
>&
InterfaceGraph
<
GUM_SCALAR
>::
edge
(
NodeId
u
,
NodeId
v
) {
350
try
{
351
return
*(
_edges_
[
Edge
(
u
,
v
)]);
352
}
catch
(
NotFound
&) {
return
*(
_edges_
[
Edge
(
v
,
u
)]); }
353
}
354
355
template
<
typename
GUM_SCALAR
>
356
INLINE
const
EdgeData
<
GUM_SCALAR
>&
InterfaceGraph
<
GUM_SCALAR
>::
edge
(
NodeId
u
,
357
NodeId
v
)
const
{
358
try
{
359
return
*(
_edges_
[
Edge
(
u
,
v
)]);
360
}
catch
(
NotFound
&) {
return
*(
_edges_
[
Edge
(
v
,
u
)]); }
361
}
362
363
template
<
typename
GUM_SCALAR
>
364
INLINE
std
::
ostream
&
operator
<<(
std
::
ostream
&
out
,
const
NodeData
<
GUM_SCALAR
>&
data
) {
365
out
<<
data
.
n
->
name
() <<
"("
<<
data
.
l
->
l
<<
")"
;
366
return
out
;
367
}
368
369
template
<
typename
GUM_SCALAR
>
370
INLINE
std
::
ostream
&
operator
<<(
std
::
ostream
&
out
,
const
EdgeData
<
GUM_SCALAR
>&
data
) {
371
out
<<
data
.
u
->
name
() <<
" -> "
<<
data
.
v
->
name
() <<
"("
<<
data
.
l
->
l
<<
")"
;
372
return
out
;
373
}
374
375
}
/* namespace gspan */
376
}
/* namespace prm */
377
}
/* namespace gum */
gum::Set::emplace
INLINE void emplace(Args &&... args)
Definition:
set_tpl.h:643
gum::prm::ParamScopeData::ParamScopeData
ParamScopeData(const std::string &s, const PRMReferenceSlot< GUM_SCALAR > &ref, Idx d)
Definition:
PRMClass_tpl.h:1032
gum::prm::gspan::operator<<
INLINE std::ostream & operator<<(std::ostream &out, const EdgeData< GUM_SCALAR > &data)
Print a EdgeData<GUM_SCALAR> in out.
Definition:
interfaceGraph_tpl.h:370