aGrUM  0.20.3
a C++ library for (probabilistic) graphical models
clusteredLayerGenerator_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 ClusteredLayerGenerator.
25  *
26  * @author Lionel TORTI and Pierre-Henri WUILLEMIN(@LIP6)
27  */
28 
29 namespace gum {
30  namespace prm {
31 
32  template < typename GUM_SCALAR >
33  PRM< GUM_SCALAR >* ClusteredLayerGenerator< GUM_SCALAR >::generate() {
34  if (_layers_.size() == 0) {
35  GUM_ERROR(OperationNotAllowed, "cannot generate a layered PRM<GUM_SCALAR> without layers")
36  }
37 
38  std::vector< MyData > l;
44  return factory.prm();
45  }
46 
47  template < typename GUM_SCALAR >
48  std::string
52 
53  for (Size i = 0; i < _domain_size_; ++i) {
55  sBuff << i;
57  }
58 
60  return name;
61  }
62 
63  template < typename GUM_SCALAR >
66  const std::string& type,
68  for (Size lvl = 0; lvl < _layers_.size(); ++lvl) {
72 
73  for (Size a = 0; a < _layers_[lvl].a; ++a) {
75  f.addAttribute(type, l[lvl].a.back());
76  }
77 
78  if (lvl) {
79  for (Size g = 0; g < _layers_[lvl].g; ++g) {
81  f.addAttribute("boolean", l[lvl].g.back());
82  }
83 
85  f.addReferenceSlot(l[lvl - 1].i, l[lvl].r, true);
86  }
87 
88  f.endInterface();
89  }
90  }
91 
92  template < typename GUM_SCALAR >
95  const std::string& type,
97  // double ratio = getClusterRatio() + RAND_MAX;
98  Set< std::string > i;
99 
100  for (Size lvl = 0; lvl < _layers_.size(); ++lvl) {
101  i.insert(l[lvl].i);
102 
103  for (Size c = 0; c < _layers_[lvl].c; ++c) {
104  // if (std::rand() < ratio)
105  _generateCluster_(f, type, l, lvl, i);
106  // else
107  // _generateClass_(f, type, l, lvl, i);
108  }
109 
110  i.erase(l[lvl].i);
111  }
112  }
113 
114  template < typename GUM_SCALAR >
116  PRMFactory< GUM_SCALAR >& f,
117  const std::string& type,
119  Size lvl,
120  Set< std::string >& i) {
121  Size size = 0;
122  GUM_SCALAR sum = 0.0;
124  std::vector< std::string >* v = 0;
125 
126  switch (std::rand() % 2) {
127  // Shape A->B
128  // v == [first, second, second.ref -> first]
129  case 0: {
130  v = new std::vector< std::string >();
131  _generateClass_(f, type, l, lvl, i);
132  first = l[lvl].c.back();
133  v->push_back(first);
135  f.startClass(v->back());
137  f.addReferenceSlot(first, v->back(), true);
138  DAG dag;
141 
142  // Adding aggregates
143  for (std::vector< std::string >::iterator g = l[lvl].g.begin(); g != l[lvl].g.end();
144  ++g) {
145  std::stringstream s;
146  s << v->back() << "." << l[lvl].a[std::rand() % l[lvl].a.size()];
147  std::vector< std::string > chain(1, s.str()), param(1, "1");
148  f.addAggregator(*g, "exists", chain, param);
149  }
150 
151  // Adding attributes
152  for (std::vector< std::string >::iterator a = l[lvl].a.begin(); a != l[lvl].a.end();
153  ++a) {
154  f.startAttribute(type, *a, true);
155  size = getDomainSize();
156 
157  for (const auto par: dag.parents(names.second(*a))) {
160  }
161 
163 
164  for (size_t norms = 0; norms < size; norms += getDomainSize()) {
165  sum = 0.0;
166 
167  for (size_t idx = 0; idx < getDomainSize(); ++idx) {
168  val[idx] = 1 + std::rand();
169  sum += val[idx];
170  }
171 
172  for (size_t idx = 0; idx < getDomainSize(); ++idx)
173  cpf[norms + idx] = val[idx] / sum;
174  }
175 
177  f.endAttribute();
178  }
179 
180  f.endClass();
181  break;
182  }
183 
184  // Shape A -> B -> C
185  // v == [first, second, second.ref -> first, third, third.ref -> second]
186  case 1: {
187  v = new std::vector< std::string >();
188  _generateClass_(f, type, l, lvl, i);
189  {
190  first = l[lvl].c.back();
191  v->push_back(first);
193  second = v->back();
196  f.addReferenceSlot(first, v->back(), true);
197  DAG dag;
200 
201  // Adding aggregates
202  for (std::vector< std::string >::iterator g = l[lvl].g.begin(); g != l[lvl].g.end();
203  ++g) {
204  std::stringstream s;
205  s << v->back() << "." << l[lvl].a[std::rand() % l[lvl].a.size()];
206  std::vector< std::string > chain(1, s.str()), param(1, "1");
207  f.addAggregator(*g, "exists", chain, param);
208  }
209 
210  // Adding attributes
211  for (std::vector< std::string >::iterator a = l[lvl].a.begin(); a != l[lvl].a.end();
212  ++a) {
213  f.startAttribute(type, *a, true);
214  size = getDomainSize();
215 
216  for (const auto par: dag.parents(names.second(*a))) {
219  }
220 
222 
223  for (size_t norms = 0; norms < size; norms += getDomainSize()) {
224  sum = 0.0;
225 
226  for (size_t idx = 0; idx < getDomainSize(); ++idx) {
227  val[idx] = 1 + std::rand();
228  sum += val[idx];
229  }
230 
231  for (size_t idx = 0; idx < getDomainSize(); ++idx)
232  cpf[norms + idx] = val[idx] / sum;
233  }
234 
236  f.endAttribute();
237  }
238 
239  f.endClass();
240  }
241  {
243  third = v->back();
244  f.startClass(third);
246  f.addReferenceSlot(second, v->back(), true);
247  DAG dag;
250 
251  // Adding aggregates
252  for (std::vector< std::string >::iterator g = l[lvl].g.begin(); g != l[lvl].g.end();
253  ++g) {
254  std::stringstream s;
255  s << v->back() << "." << l[lvl].a[std::rand() % l[lvl].a.size()];
256  std::vector< std::string > chain(1, s.str()), param(1, "1");
257  f.addAggregator(*g, "exists", chain, param);
258  }
259 
260  // Adding attributes
261  for (std::vector< std::string >::iterator a = l[lvl].a.begin(); a != l[lvl].a.end();
262  ++a) {
263  f.startAttribute(type, *a, true);
264  size = getDomainSize();
265 
266  for (const auto par: dag.parents(names.second(*a))) {
269  }
270 
272 
273  for (size_t norms = 0; norms < size; norms += getDomainSize()) {
274  sum = 0.0;
275 
276  for (size_t idx = 0; idx < getDomainSize(); ++idx) {
277  val[idx] = 1 + std::rand();
278  sum += val[idx];
279  }
280 
281  for (size_t idx = 0; idx < getDomainSize(); ++idx)
282  cpf[norms + idx] = val[idx] / sum;
283  }
284 
286  f.endAttribute();
287  }
288 
289  f.endClass();
290  }
291  break;
292  }
293 
294  default: {
295  GUM_ERROR(OperationNotAllowed, "unexpected value")
296  }
297  }
298 
300  }
301 
302  template < typename GUM_SCALAR >
304  PRMFactory< GUM_SCALAR >& f,
305  const std::string& type,
307  Size lvl,
308  Set< std::string >& i) {
309  Size size = 0;
310  GUM_SCALAR sum = 0.0;
312  f.startClass(l[lvl].c.back(), "", &i);
313 
314  if (lvl) f.addReferenceSlot(l[lvl - 1].i, l[lvl].r, true);
315 
316  DAG dag;
319 
320  // Adding aggregates
321  if (lvl) {
322  for (const auto agg: l[lvl].g) {
323  std::stringstream s;
324  s << l[lvl].r << "." << l[lvl - 1].a[std::rand() % l[lvl - 1].a.size()];
325  std::vector< std::string > chain(1, s.str()), param(1, "1");
326  f.addAggregator(agg, "exists", chain, param);
327  }
328  }
329 
330  // Adding attributes
331  for (const auto attr: l[lvl].a) {
332  f.startAttribute(type, attr, true);
333  size = getDomainSize();
334 
335  for (const auto par: dag.parents(names.second(attr))) {
338  }
339 
341 
342  for (size_t norms = 0; norms < size; norms += getDomainSize()) {
343  sum = 0.0;
344 
345  for (size_t idx = 0; idx < getDomainSize(); ++idx) {
346  val[idx] = 1 + std::rand();
347  sum += val[idx];
348  }
349 
350  for (size_t idx = 0; idx < getDomainSize(); ++idx)
351  cpf[norms + idx] = val[idx] / sum;
352  }
353 
355  f.endAttribute();
356  }
357 
358  f.endClass();
359  }
360 
361  template < typename GUM_SCALAR >
363  Size lvl,
364  DAG& dag,
366  std::vector< typename ClusteredLayerGenerator< GUM_SCALAR >::MyData >& l) {
368  std::vector< NodeId > nodes;
369  NodeId id = 0;
370 
371  if (lvl) {
372  for (std::vector< std::string >::iterator g = l[lvl].g.begin(); g != l[lvl].g.end(); ++g) {
373  id = dag.addNode();
374  names.insert(*g, id);
375  nodes.push_back(id);
376  }
377  }
378 
379  for (std::vector< std::string >::iterator a = l[lvl].a.begin(); a != l[lvl].a.end(); ++a) {
380  id = dag.addNode();
381  names.insert(*a, id);
382 
383  for (std::vector< NodeId >::iterator prnt = nodes.begin(); prnt != nodes.end(); ++prnt)
384  if (std::rand() < density) dag.addArc(*prnt, names.second(*a));
385 
386  nodes.push_back(id);
387  }
388 
389  // For each nodes with #parents > _max_parents_ we randomly remove parents
390  // until
391  // #parents <= _max_parents_
392  for (const auto node: dag.nodes()) {
393  if (dag.parents(node).size() > getMaxParents()) {
394  std::vector< NodeId > v;
395 
396  for (const auto par: dag.parents(node))
397  v.push_back(par);
398 
399  while (dag.parents(node).size() > getMaxParents()) {
400  size_t idx = std::rand() % v.size();
401  Arc arc(v[idx], node);
403  dag.eraseArc(arc);
404  v[idx] = v.back();
405  v.pop_back();
406  }
407  }
408  }
409  }
410 
411  template < typename GUM_SCALAR >
414  std::vector< typename ClusteredLayerGenerator< GUM_SCALAR >::MyData >& l) {
416  std::vector< std::vector< std::string > > o(_layers_.size());
418  std::vector< std::string >* v = 0;
419  size_t idx = 0;
420 
421  for (size_t lvl = 0; lvl < _layers_.size(); ++lvl) {
423 
424  for (size_t count = 0; count < _layers_[lvl].o; ++count) {
425  c = l[lvl].c[std::rand() % l[lvl].c.size()];
426 
427  if (_cluster_map_.exists(c)) {
428  v = _cluster_map_[c];
429 
430  switch (v->size()) {
431  case 3: {
435  factory.addInstance(v->at(1), second);
437  chain << second << "." << v->at(2);
439  break;
440  }
441 
442  case 5: {
446  factory.addInstance(v->at(1), second);
448  chain_1 << second << "." << v->at(2);
451  factory.addInstance(v->at(3), third);
452  chain_2 << third << "." << v->at(4);
454  break;
455  }
456 
457  default: {
458  GUM_ERROR(OperationNotAllowed, "unexpected vector size")
459  }
460  }
461 
462  // _cluster_map_.erase(c);
463  // delete v;
464  name = first;
465  } else {
468  }
469 
470  o[lvl].push_back(name);
471 
472  if (lvl) {
474  chain << name << "." << l[lvl].r;
475  std::vector< std::string > ref2add;
476 
477  for (std::vector< std::string >::iterator iter = o[lvl - 1].begin();
478  iter != o[lvl - 1].end();
479  ++iter)
480  if (std::rand() <= density) ref2add.push_back(*iter);
481 
482  if (ref2add.empty())
483  factory.setReferenceSlot(chain.str(), o[lvl - 1][std::rand() % o[lvl - 1].size()]);
484 
485  while (ref2add.size() > getMaxParents()) {
486  idx = std::rand() % ref2add.size();
487  ref2add[idx] = ref2add.back();
488  ref2add.pop_back();
489  }
490 
491  for (std::vector< std::string >::iterator iter = ref2add.begin(); iter != ref2add.end();
492  ++iter)
494  }
495  }
496  }
497 
498  factory.endSystem();
499  }
500 
501  template < typename GUM_SCALAR >
505  }
506 
507  template < typename GUM_SCALAR >
513  }
514 
515  template < typename GUM_SCALAR >
518  // typedef HashTable<std::string, std::vector<std::string>*>::iterator
519  // Iter;
520  // for (Iter iter = _cluster_map_.begin(); iter != _cluster_map_.end();
521  // ++iter)
522  // {
523  // delete *iter;
524  // }
525  }
526 
527  template < typename GUM_SCALAR >
533  return *this;
534  }
535 
536  template < typename GUM_SCALAR >
538  return _domain_size_;
539  }
540 
541  template < typename GUM_SCALAR >
543  _domain_size_ = s;
544  }
545 
546  template < typename GUM_SCALAR >
548  return _max_parents_;
549  }
550 
551  template < typename GUM_SCALAR >
553  _max_parents_ = s;
554  }
555 
556  template < typename GUM_SCALAR >
558  const std::vector< typename LayerGenerator< GUM_SCALAR >::LayerData >& v) {
559  _layers_ = v;
560  }
561 
562  template < typename GUM_SCALAR >
565  return _layers_;
566  }
567 
568  template < typename GUM_SCALAR >
569  INLINE const std::vector< typename LayerGenerator< GUM_SCALAR >::LayerData >&
571  return _layers_;
572  }
573 
574  template < typename GUM_SCALAR >
576  return _cluster_ratio_;
577  }
578 
579  template < typename GUM_SCALAR >
582  }
583 
584  } /* namespace prm */
585 } /* namespace gum */
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:643
ParamScopeData(const std::string &s, const PRMReferenceSlot< GUM_SCALAR > &ref, Idx d)