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