aGrUM
0.21.0
a C++ library for (probabilistic) graphical models
layerGenerator_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 LayerGenerator.
25
*
26
* @author Lionel TORTI and Pierre-Henri WUILLEMIN(@LIP6)
27
*/
28
#
include
<
agrum
/
PRM
/
generator
/
layerGenerator
.
h
>
29
30
namespace
gum
{
31
namespace
prm
{
32
33
template
<
typename
GUM_SCALAR >
34
PRM< GUM_SCALAR >* LayerGenerator<
GUM_SCALAR
>::
generate
() {
35
if
(
_layers_
.
size
() == 0) {
36
GUM_ERROR
(
OperationNotAllowed
,
"cannot generate a layered PRM<GUM_SCALAR> without layers"
)
37
}
38
39
std
::
vector
<
MyData
>
l
;
40
PRMFactory
<
GUM_SCALAR
>
factory
;
41
std
::
string
type
=
_generateType_
(
factory
);
42
_generateInterfaces_
(
factory
,
type
,
l
);
43
_generateClasses_
(
factory
,
type
,
l
);
44
_generateSystem_
(
factory
,
l
);
45
return
factory
.
prm
();
46
}
47
48
template
<
typename
GUM_SCALAR
>
49
std
::
string
LayerGenerator
<
GUM_SCALAR
>::
_generateType_
(
PRMFactory
<
GUM_SCALAR
>&
factory
) {
50
std
::
string
name
=
this
->
name_gen_
.
nextName
(
PRMObject
::
prm_type
::
TYPE
);
51
factory
.
startDiscreteType
(
name
);
52
53
for
(
Size
i
= 0;
i
<
_domain_size_
; ++
i
) {
54
std
::
stringstream
sBuff
;
55
sBuff
<<
i
;
56
factory
.
addLabel
(
sBuff
.
str
());
57
}
58
59
factory
.
endDiscreteType
();
60
return
name
;
61
}
62
63
template
<
typename
GUM_SCALAR
>
64
void
LayerGenerator
<
GUM_SCALAR
>::
_generateInterfaces_
(
65
PRMFactory
<
GUM_SCALAR
>&
f
,
66
const
std
::
string
&
type
,
67
std
::
vector
<
typename
LayerGenerator
<
GUM_SCALAR
>::
MyData
>&
l
) {
68
for
(
Size
lvl
= 0;
lvl
<
_layers_
.
size
(); ++
lvl
) {
69
l
.
push_back
(
LayerGenerator
<
GUM_SCALAR
>::
MyData
());
70
l
[
lvl
].
i
=
this
->
name_gen_
.
nextName
(
PRMObject
::
prm_type
::
PRM_INTERFACE
);
71
f
.
startInterface
(
l
[
lvl
].
i
);
72
73
for
(
Size
a
= 0;
a
<
_layers_
[
lvl
].
a
; ++
a
) {
74
l
[
lvl
].
a
.
push_back
(
this
->
name_gen_
.
nextName
(
PRMObject
::
prm_type
::
CLASS_ELT
));
75
f
.
addAttribute
(
type
,
l
[
lvl
].
a
.
back
());
76
}
77
78
if
(
lvl
) {
79
for
(
Size
g
= 0;
g
<
_layers_
[
lvl
].
g
; ++
g
) {
80
l
[
lvl
].
g
.
push_back
(
this
->
name_gen_
.
nextName
(
PRMObject
::
prm_type
::
CLASS_ELT
));
81
f
.
addAttribute
(
"boolean"
,
l
[
lvl
].
g
.
back
());
82
}
83
84
l
[
lvl
].
r
=
this
->
name_gen_
.
nextName
(
PRMObject
::
prm_type
::
CLASS_ELT
);
85
f
.
addReferenceSlot
(
l
[
lvl
- 1].
i
,
l
[
lvl
].
r
,
true
);
86
}
87
88
f
.
endInterface
();
89
}
90
}
91
92
template
<
typename
GUM_SCALAR
>
93
void
LayerGenerator
<
GUM_SCALAR
>::
_generateClasses_
(
94
PRMFactory
<
GUM_SCALAR
>&
f
,
95
const
std
::
string
&
type
,
96
std
::
vector
<
typename
LayerGenerator
<
GUM_SCALAR
>::
MyData
>&
l
) {
97
Size
size
= 0;
98
GUM_SCALAR
sum
= 0.0;
99
Set
<
std
::
string
>
i
;
100
101
for
(
Size
lvl
= 0;
lvl
<
_layers_
.
size
(); ++
lvl
) {
102
i
.
insert
(
l
[
lvl
].
i
);
103
104
for
(
Size
c
= 0;
c
<
_layers_
[
lvl
].
c
; ++
c
) {
105
l
[
lvl
].
c
.
push_back
(
this
->
name_gen_
.
nextName
(
PRMObject
::
prm_type
::
CLASS
));
106
f
.
startClass
(
l
[
lvl
].
c
.
back
(),
""
, &
i
);
107
108
if
(
lvl
)
f
.
addReferenceSlot
(
l
[
lvl
- 1].
i
,
l
[
lvl
].
r
,
true
);
109
110
DAG
dag
;
111
Bijection
<
std
::
string
,
NodeId
>
names
;
112
_generateClassDag_
(
lvl
,
dag
,
names
,
l
);
113
114
// Adding aggregates
115
if
(
lvl
) {
116
for
(
std
::
vector
<
std
::
string
>::
iterator
g
=
l
[
lvl
].
g
.
begin
();
g
!=
l
[
lvl
].
g
.
end
();
117
++
g
) {
118
std
::
stringstream
s
;
119
s
<<
l
[
lvl
].
r
<<
"."
<<
l
[
lvl
- 1].
a
[
std
::
rand
() %
l
[
lvl
- 1].
a
.
size
()];
120
std
::
vector
<
std
::
string
>
chain
(1,
s
.
str
()),
param
(1,
"1"
);
121
f
.
addAggregator
(*
g
,
"exists"
,
chain
,
param
);
122
}
123
}
124
125
// Adding attributes
126
for
(
std
::
vector
<
std
::
string
>::
iterator
a
=
l
[
lvl
].
a
.
begin
();
a
!=
l
[
lvl
].
a
.
end
();
127
++
a
) {
128
f
.
startAttribute
(
type
, *
a
,
true
);
129
size
=
getDomainSize
();
130
131
for
(
const
auto
par
:
dag
.
parents
(
names
.
second
(*
a
))) {
132
f
.
addParent
(
names
.
first
(
par
));
133
size
*=
f
.
retrieveClass
(
l
[
lvl
].
c
.
back
()).
get
(
names
.
first
(
par
)).
type
()->
domainSize
();
134
}
135
136
std
::
vector
<
GUM_SCALAR
>
cpf
(
size
),
val
(
getDomainSize
());
137
138
for
(
size_t
norms
= 0;
norms
<
size
;
norms
+=
getDomainSize
()) {
139
sum
= 0.0;
140
141
for
(
size_t
idx
= 0;
idx
<
getDomainSize
(); ++
idx
) {
142
val
[
idx
] = 1 +
std
::
rand
();
143
sum
+=
val
[
idx
];
144
}
145
146
for
(
size_t
idx
= 0;
idx
<
getDomainSize
(); ++
idx
)
147
cpf
[
norms
+
idx
] =
val
[
idx
] /
sum
;
148
}
149
150
f
.
setRawCPFByLines
(
cpf
);
151
f
.
endAttribute
();
152
}
153
154
f
.
endClass
();
155
}
156
157
i
.
erase
(
l
[
lvl
].
i
);
158
}
159
}
160
161
template
<
typename
GUM_SCALAR
>
162
void
LayerGenerator
<
GUM_SCALAR
>::
_generateClassDag_
(
163
Size
lvl
,
164
DAG
&
dag
,
165
Bijection
<
std
::
string
,
NodeId
>&
names
,
166
std
::
vector
<
typename
LayerGenerator
<
GUM_SCALAR
>::
MyData
>&
l
) {
167
float
density
=
_layers_
[
lvl
].
inner_density
*
RAND_MAX
;
168
std
::
vector
<
NodeId
>
nodes
;
169
NodeId
id
= 0;
170
171
if
(
lvl
) {
172
for
(
const
auto
&
agg
:
l
[
lvl
].
g
) {
173
id
=
dag
.
addNode
();
174
names
.
insert
(
agg
,
id
);
175
nodes
.
push_back
(
id
);
176
}
177
}
178
179
for
(
const
auto
&
attr
:
l
[
lvl
].
a
) {
180
id
=
dag
.
addNode
();
181
names
.
insert
(
attr
,
id
);
182
183
for
(
const
auto
node
:
nodes
)
184
if
(
std
::
rand
() <
density
)
dag
.
addArc
(
node
,
names
.
second
(
attr
));
185
186
nodes
.
push_back
(
id
);
187
}
188
189
// For each nodes with #parents > _max_parents_ we randomly remove parents
190
// until
191
// #parents <= _max_parents_
192
for
(
const
auto
node
:
dag
.
nodes
()) {
193
if
(
dag
.
parents
(
node
).
size
() >
getMaxParents
()) {
194
std
::
vector
<
NodeId
>
v
;
195
196
for
(
const
auto
par
:
dag
.
parents
(
node
))
197
v
.
push_back
(
par
);
198
199
while
(
dag
.
parents
(
node
).
size
() >
getMaxParents
()) {
200
size_t
idx
=
std
::
rand
() %
v
.
size
();
201
Arc
arc
(
v
[
idx
],
node
);
202
GUM_ASSERT
(
dag
.
existsArc
(
arc
));
203
dag
.
eraseArc
(
arc
);
204
v
[
idx
] =
v
.
back
();
205
v
.
pop_back
();
206
}
207
}
208
}
209
}
210
211
template
<
typename
GUM_SCALAR
>
212
void
LayerGenerator
<
GUM_SCALAR
>::
_generateSystem_
(
213
PRMFactory
<
GUM_SCALAR
>&
factory
,
214
std
::
vector
<
typename
LayerGenerator
<
GUM_SCALAR
>::
MyData
>&
l
) {
215
factory
.
startSystem
(
this
->
name_gen_
.
nextName
(
PRMObject
::
prm_type
::
SYSTEM
));
216
std
::
vector
<
std
::
vector
<
std
::
string
> >
o
(
_layers_
.
size
());
217
std
::
string
name
;
218
size_t
idx
= 0;
219
220
for
(
size_t
lvl
= 0;
lvl
<
_layers_
.
size
(); ++
lvl
) {
221
float
density
=
_layers_
[
lvl
].
outter_density
*
RAND_MAX
;
222
223
for
(
size_t
count
= 0;
count
<
_layers_
[
lvl
].
o
; ++
count
) {
224
name
=
this
->
name_gen_
.
nextName
(
PRMObject
::
prm_type
::
PRM_INTERFACE
);
225
factory
.
addInstance
(
l
[
lvl
].
c
[
std
::
rand
() %
l
[
lvl
].
c
.
size
()],
name
);
226
o
[
lvl
].
push_back
(
name
);
227
228
if
(
lvl
) {
229
std
::
stringstream
chain
;
230
chain
<<
name
<<
"."
<<
l
[
lvl
].
r
;
231
std
::
vector
<
std
::
string
>
ref2add
;
232
233
for
(
std
::
vector
<
std
::
string
>::
iterator
iter
=
o
[
lvl
- 1].
begin
();
234
iter
!=
o
[
lvl
- 1].
end
();
235
++
iter
)
236
if
(
std
::
rand
() <=
density
)
ref2add
.
push_back
(*
iter
);
237
238
if
(
ref2add
.
empty
())
239
factory
.
setReferenceSlot
(
chain
.
str
(),
o
[
lvl
- 1][
std
::
rand
() %
o
[
lvl
- 1].
size
()]);
240
241
while
(
ref2add
.
size
() >
getMaxParents
()) {
242
idx
=
std
::
rand
() %
ref2add
.
size
();
243
ref2add
[
idx
] =
ref2add
.
back
();
244
ref2add
.
pop_back
();
245
}
246
247
for
(
std
::
vector
<
std
::
string
>::
iterator
iter
=
ref2add
.
begin
();
iter
!=
ref2add
.
end
();
248
++
iter
)
249
factory
.
setReferenceSlot
(
chain
.
str
(), *
iter
);
250
}
251
}
252
}
253
254
factory
.
endSystem
();
255
}
256
257
template
<
typename
GUM_SCALAR
>
258
INLINE
LayerGenerator
<
GUM_SCALAR
>::
LayerGenerator
() :
259
_layers_
(),
_domain_size_
(2),
_max_parents_
(
INT_MAX
) {
260
GUM_CONSTRUCTOR
(
LayerGenerator
);
261
}
262
263
template
<
typename
GUM_SCALAR
>
264
INLINE
265
LayerGenerator
<
GUM_SCALAR
>::
LayerGenerator
(
const
LayerGenerator
<
GUM_SCALAR
>&
source
) :
266
_layers_
(
source
.
_layers_
),
267
_domain_size_
(
source
.
_domain_size_
),
_max_parents_
(
source
.
_max_parents_
) {
268
GUM_CONS_CPY
(
LayerGenerator
);
269
}
270
271
template
<
typename
GUM_SCALAR
>
272
INLINE
LayerGenerator
<
GUM_SCALAR
>::~
LayerGenerator
() {
273
GUM_DESTRUCTOR
(
LayerGenerator
);
274
}
275
276
template
<
typename
GUM_SCALAR
>
277
INLINE
LayerGenerator
<
GUM_SCALAR
>&
278
LayerGenerator
<
GUM_SCALAR
>::
operator
=(
const
LayerGenerator
<
GUM_SCALAR
>&
source
) {
279
_layers_
=
source
.
_layers_
;
280
_domain_size_
=
source
.
_domain_size_
;
281
_max_parents_
=
source
.
_max_parents_
;
282
return
*
this
;
283
}
284
285
template
<
typename
GUM_SCALAR
>
286
INLINE
Size
LayerGenerator
<
GUM_SCALAR
>::
getDomainSize
()
const
{
287
return
_domain_size_
;
288
}
289
290
template
<
typename
GUM_SCALAR
>
291
INLINE
void
LayerGenerator
<
GUM_SCALAR
>::
setDomainSize
(
Size
s
) {
292
_domain_size_
=
s
;
293
}
294
295
template
<
typename
GUM_SCALAR
>
296
INLINE
Size
LayerGenerator
<
GUM_SCALAR
>::
getMaxParents
()
const
{
297
return
_max_parents_
;
298
}
299
300
template
<
typename
GUM_SCALAR
>
301
INLINE
void
LayerGenerator
<
GUM_SCALAR
>::
setMaxParents
(
Size
s
) {
302
_max_parents_
=
s
;
303
}
304
305
template
<
typename
GUM_SCALAR
>
306
INLINE
void
LayerGenerator
<
GUM_SCALAR
>::
setLayers
(
307
const
std
::
vector
<
typename
LayerGenerator
<
GUM_SCALAR
>::
LayerData
>&
v
) {
308
_layers_
=
v
;
309
}
310
311
template
<
typename
GUM_SCALAR
>
312
INLINE
std
::
vector
<
typename
LayerGenerator
<
GUM_SCALAR
>::
LayerData
>&
313
LayerGenerator
<
GUM_SCALAR
>::
getLayer
() {
314
return
_layers_
;
315
}
316
317
template
<
typename
GUM_SCALAR
>
318
INLINE
const
std
::
vector
<
typename
LayerGenerator
<
GUM_SCALAR
>::
LayerData
>&
319
LayerGenerator
<
GUM_SCALAR
>::
getLayer
()
const
{
320
return
_layers_
;
321
}
322
323
}
/* namespace prm */
324
}
/* 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