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) {
37  "cannot generate a layered PRM<GUM_SCALAR> without layers");
38  }
39 
40  std::vector< MyData > l;
46  return factory.prm();
47  }
48 
49  template < typename GUM_SCALAR >
54 
55  for (Size i = 0; i < domain_size__; ++i) {
57  sBuff << i;
59  }
60 
62  return name;
63  }
64 
65  template < typename GUM_SCALAR >
68  const std::string& type,
69  std::vector< typename LayerGenerator< GUM_SCALAR >::MyData >& l) {
70  for (Size lvl = 0; lvl < layers__.size(); ++lvl) {
74 
75  for (Size a = 0; a < layers__[lvl].a; ++a) {
76  l[lvl].a.push_back(
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(
85  f.addAttribute("boolean", l[lvl].g.back());
86  }
87 
89  f.addReferenceSlot(l[lvl - 1].i, l[lvl].r, true);
90  }
91 
92  f.endInterface();
93  }
94  }
95 
96  template < typename GUM_SCALAR >
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) {
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;
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))) {
140  size *= f.retrieveClass(l[lvl].c.back())
141  .get(names.first(par))
142  .type()
143  ->domainSize();
144  }
145 
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 
161  f.endAttribute();
162  }
163 
164  f.endClass();
165  }
166 
167  i.erase(l[lvl].i);
168  }
169  }
170 
171  template < typename GUM_SCALAR >
173  Size lvl,
174  DAG& dag,
176  std::vector< typename LayerGenerator< GUM_SCALAR >::MyData >& l) {
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);
213  dag.eraseArc(arc);
214  v[idx] = v.back();
215  v.pop_back();
216  }
217  }
218  }
219  }
220 
221  template < typename GUM_SCALAR >
224  std::vector< typename LayerGenerator< GUM_SCALAR >::MyData >& l) {
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) {
232 
233  for (size_t count = 0; count < layers__[lvl].o; ++count) {
235  factory.addInstance(l[lvl].c[std::rand() % l[lvl].c.size()], name);
236  o[lvl].push_back(name);
237 
238  if (lvl) {
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())
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)
263  }
264  }
265  }
266 
267  factory.endSystem();
268  }
269 
270  template < typename GUM_SCALAR >
274  }
275 
276  template < typename GUM_SCALAR >
278  const LayerGenerator< GUM_SCALAR >& source) :
282  }
283 
284  template < typename GUM_SCALAR >
287  }
288 
289  template < typename GUM_SCALAR >
291  const LayerGenerator< GUM_SCALAR >& source) {
295  return *this;
296  }
297 
298  template < typename GUM_SCALAR >
300  return domain_size__;
301  }
302 
303  template < typename GUM_SCALAR >
305  domain_size__ = s;
306  }
307 
308  template < typename GUM_SCALAR >
310  return max_parents__;
311  }
312 
313  template < typename GUM_SCALAR >
315  max_parents__ = s;
316  }
317 
318  template < typename GUM_SCALAR >
320  const std::vector< typename LayerGenerator< GUM_SCALAR >::LayerData >& v) {
321  layers__ = v;
322  }
323 
324  template < typename GUM_SCALAR >
327  return layers__;
328  }
329 
330  template < typename GUM_SCALAR >
331  INLINE const std::vector< typename LayerGenerator< GUM_SCALAR >::LayerData >&
333  return layers__;
334  }
335 
336  } /* namespace prm */
337 } /* namespace gum */
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:669
ParamScopeData(const std::string &s, const PRMReferenceSlot< GUM_SCALAR > &ref, Idx d)