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