aGrUM  0.14.2
layerGenerator_tpl.h
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2005 by Christophe GONZALES and Pierre-Henri WUILLEMIN *
3  * {prenom.nom}_at_lip6.fr *
4  * *
5  * This program is free software; you can redistribute it and/or modify *
6  * it under the terms of the GNU General Public License as published by *
7  * the Free Software Foundation; either version 2 of the License, or *
8  * (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public License *
16  * along with this program; if not, write to the *
17  * Free Software Foundation, Inc., *
18  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19  ***************************************************************************/
27 
28 namespace gum {
29  namespace prm {
30 
31  template < typename GUM_SCALAR >
33  if (__layers.size() == 0) {
35  "cannot generate a layered PRM<GUM_SCALAR> without layers");
36  }
37 
38  std::vector< MyData > l;
40  std::string type = __generateType(factory);
41  __generateInterfaces(factory, type, l);
42  __generateClasses(factory, type, l);
43  __generateSystem(factory, l);
44  return factory.prm();
45  }
46 
47  template < typename GUM_SCALAR >
49  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 >
66  const std::string& type,
67  std::vector< typename LayerGenerator< GUM_SCALAR >::MyData >& l) {
68  for (Size lvl = 0; lvl < __layers.size(); ++lvl) {
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(
75  this->_name_gen.nextName(PRMObject::prm_type::CLASS_ELT));
76  f.addAttribute(type, l[lvl].a.back());
77  }
78 
79  if (lvl) {
80  for (Size g = 0; g < __layers[lvl].g; ++g) {
81  l[lvl].g.push_back(
82  this->_name_gen.nextName(PRMObject::prm_type::CLASS_ELT));
83  f.addAttribute("boolean", l[lvl].g.back());
84  }
85 
86  l[lvl].r = this->_name_gen.nextName(PRMObject::prm_type::CLASS_ELT);
87  f.addReferenceSlot(l[lvl - 1].i, l[lvl].r, true);
88  }
89 
90  f.endInterface();
91  }
92  }
93 
94  template < typename GUM_SCALAR >
97  const std::string& type,
98  std::vector< typename LayerGenerator< GUM_SCALAR >::MyData >& l) {
99  Size size = 0;
100  GUM_SCALAR sum = 0.0;
102 
103  for (Size lvl = 0; lvl < __layers.size(); ++lvl) {
104  i.insert(l[lvl].i);
105 
106  for (Size c = 0; c < __layers[lvl].c; ++c) {
107  l[lvl].c.push_back(this->_name_gen.nextName(PRMObject::prm_type::CLASS));
108  f.startClass(l[lvl].c.back(), "", &i);
109 
110  if (lvl) f.addReferenceSlot(l[lvl - 1].i, l[lvl].r, true);
111 
112  DAG dag;
114  __generateClassDag(lvl, dag, names, l);
115 
116  // Adding aggregates
117  if (lvl) {
118  for (std::vector< std::string >::iterator g = l[lvl].g.begin();
119  g != l[lvl].g.end();
120  ++g) {
121  std::stringstream s;
122  s << l[lvl].r << "."
123  << l[lvl - 1].a[std::rand() % l[lvl - 1].a.size()];
124  std::vector< std::string > chain(1, s.str()), param(1, "1");
125  f.addAggregator(*g, "exists", chain, param);
126  }
127  }
128 
129  // Adding attributes
130  for (std::vector< std::string >::iterator a = l[lvl].a.begin();
131  a != l[lvl].a.end();
132  ++a) {
133  f.startAttribute(type, *a, true);
134  size = getDomainSize();
135 
136  for (const auto par : dag.parents(names.second(*a))) {
137  f.addParent(names.first(par));
138  size *= f.retrieveClass(l[lvl].c.back())
139  .get(names.first(par))
140  .type()
141  ->domainSize();
142  }
143 
144  std::vector< GUM_SCALAR > cpf(size), val(getDomainSize());
145 
146  for (size_t norms = 0; norms < size; norms += getDomainSize()) {
147  sum = 0.0;
148 
149  for (size_t idx = 0; idx < getDomainSize(); ++idx) {
150  val[idx] = 1 + std::rand();
151  sum += val[idx];
152  }
153 
154  for (size_t idx = 0; idx < getDomainSize(); ++idx)
155  cpf[norms + idx] = val[idx] / sum;
156  }
157 
158  f.setRawCPFByLines(cpf);
159  f.endAttribute();
160  }
161 
162  f.endClass();
163  }
164 
165  i.erase(l[lvl].i);
166  }
167  }
168 
169  template < typename GUM_SCALAR >
171  Size lvl,
172  DAG& dag,
174  std::vector< typename LayerGenerator< GUM_SCALAR >::MyData >& l) {
175  float density = __layers[lvl].inner_density * RAND_MAX;
176  std::vector< NodeId > nodes;
177  NodeId id = 0;
178 
179  if (lvl) {
180  for (const auto agg : l[lvl].g) {
181  id = dag.addNode();
182  names.insert(agg, id);
183  nodes.push_back(id);
184  }
185  }
186 
187  for (const auto attr : l[lvl].a) {
188  id = dag.addNode();
189  names.insert(attr, id);
190 
191  for (const auto node : nodes)
192  if (std::rand() < density) dag.addArc(node, names.second(attr));
193 
194  nodes.push_back(id);
195  }
196 
197  // For each nodes with #parents > __max_parents we randomly remove parents
198  // until
199  // #parents <= __max_parents
200  for (const auto node : dag.nodes()) {
201  if (dag.parents(node).size() > getMaxParents()) {
202  std::vector< NodeId > v;
203 
204  for (const auto par : dag.parents(node))
205  v.push_back(par);
206 
207  while (dag.parents(node).size() > getMaxParents()) {
208  size_t idx = std::rand() % v.size();
209  Arc arc(v[idx], node);
210  GUM_ASSERT(dag.existsArc(arc));
211  dag.eraseArc(arc);
212  v[idx] = v.back();
213  v.pop_back();
214  }
215  }
216  }
217  }
218 
219  template < typename GUM_SCALAR >
221  PRMFactory< GUM_SCALAR >& factory,
222  std::vector< typename LayerGenerator< GUM_SCALAR >::MyData >& l) {
223  factory.startSystem(this->_name_gen.nextName(PRMObject::prm_type::SYSTEM));
224  std::vector< std::vector< std::string > > o(__layers.size());
225  std::string name;
226  size_t idx = 0;
227 
228  for (size_t lvl = 0; lvl < __layers.size(); ++lvl) {
229  float density = __layers[lvl].outter_density * RAND_MAX;
230 
231  for (size_t count = 0; count < __layers[lvl].o; ++count) {
232  name = this->_name_gen.nextName(PRMObject::prm_type::PRM_INTERFACE);
233  factory.addInstance(l[lvl].c[std::rand() % l[lvl].c.size()], name);
234  o[lvl].push_back(name);
235 
236  if (lvl) {
237  std::stringstream chain;
238  chain << name << "." << l[lvl].r;
239  std::vector< std::string > ref2add;
240 
241  for (std::vector< std::string >::iterator iter = o[lvl - 1].begin();
242  iter != o[lvl - 1].end();
243  ++iter)
244  if (std::rand() <= density) ref2add.push_back(*iter);
245 
246  if (ref2add.empty())
247  factory.setReferenceSlot(
248  chain.str(), o[lvl - 1][std::rand() % o[lvl - 1].size()]);
249 
250  while (ref2add.size() > getMaxParents()) {
251  idx = std::rand() % ref2add.size();
252  ref2add[idx] = ref2add.back();
253  ref2add.pop_back();
254  }
255 
256  for (std::vector< std::string >::iterator iter = ref2add.begin();
257  iter != ref2add.end();
258  ++iter)
259  factory.setReferenceSlot(chain.str(), *iter);
260  }
261  }
262  }
263 
264  factory.endSystem();
265  }
266 
267  template < typename GUM_SCALAR >
269  __layers(), __domain_size(2), __max_parents(INT_MAX) {
270  GUM_CONSTRUCTOR(LayerGenerator);
271  }
272 
273  template < typename GUM_SCALAR >
275  const LayerGenerator< GUM_SCALAR >& source) :
276  __layers(source.__layers),
278  GUM_CONS_CPY(LayerGenerator);
279  }
280 
281  template < typename GUM_SCALAR >
283  GUM_DESTRUCTOR(LayerGenerator);
284  }
285 
286  template < typename GUM_SCALAR >
289  __layers = source.__layers;
290  __domain_size = source.__domain_size;
291  __max_parents = source.__max_parents;
292  return *this;
293  }
294 
295  template < typename GUM_SCALAR >
297  return __domain_size;
298  }
299 
300  template < typename GUM_SCALAR >
302  __domain_size = s;
303  }
304 
305  template < typename GUM_SCALAR >
307  return __max_parents;
308  }
309 
310  template < typename GUM_SCALAR >
312  __max_parents = s;
313  }
314 
315  template < typename GUM_SCALAR >
317  const std::vector< typename LayerGenerator< GUM_SCALAR >::LayerData >& v) {
318  __layers = v;
319  }
320 
321  template < typename GUM_SCALAR >
322  INLINE std::vector< typename LayerGenerator< GUM_SCALAR >::LayerData >&
324  return __layers;
325  }
326 
327  template < typename GUM_SCALAR >
328  INLINE const std::vector< typename LayerGenerator< GUM_SCALAR >::LayerData >&
330  return __layers;
331  }
332 
333  } /* namespace prm */
334 } /* namespace gum */
void insert(const T1 &first, const T2 &second)
Inserts a new association in the gum::Bijection.
const T2 & second(const T1 &first) const
Returns the second value of a pair given its first value.
virtual void endInterface() override
Tells the factory that we finished an interface declaration.
virtual void addAggregator(const std::string &name, const std::string &agg_type, const std::vector< std::string > &chains, const std::vector< std::string > &params, std::string type="") override
Add an aggregator in the current declared class.
virtual void setReferenceSlot(const std::string &left_instance, const std::string &left_reference, const std::string &right_instance) override
Instantiate a reference in the current model.
const T1 & first(const T2 &second) const
Returns the first value of a pair given its second value.
virtual void addInstance(const std::string &type, const std::string &name) override
Add an instance to the model.
virtual void eraseArc(const Arc &arc)
removes an arc from the ArcGraphPart
Headers of LayerGenerator.
PRMClass< GUM_SCALAR > & retrieveClass(const std::string &name)
Returns a reference over a Class<GUM_SCALAR> given its name.
virtual void endAttribute() override
Tells the factory that we finished declaring an attribute.
virtual void startInterface(const std::string &i, const std::string &ext="", bool delayInheritance=false) override
Tells the factory that we start an interface declaration.
virtual void addReferenceSlot(const std::string &type, const std::string &name, bool isArray) override
Tells the factory that we started declaring a slot.
gum is the global namespace for all aGrUM entities
Definition: agrum.h:25
void __generateInterfaces(PRMFactory< GUM_SCALAR > &f, const std::string &type, std::vector< MyData > &l)
virtual void addAttribute(const std::string &type, const std::string &name) override
Add an attribute to an interface.
virtual NodeId addNode()
insert a new node and return its id
virtual void startClass(const std::string &c, const std::string &ext="", const Set< std::string > *implements=nullptr, bool delayInheritance=false) override
Tells the factory that we start a class declaration.
std::vector< LayerData > __layers
virtual void startSystem(const std::string &name) override
Tells the factory that we started declaring a model.
LayerGenerator()
Default constructor.
virtual void startAttribute(const std::string &type, const std::string &name, bool scalar_atttr=false) override
Tells the factory that we start an attribute declaration.
void __generateClasses(PRMFactory< GUM_SCALAR > &f, const std::string &type, std::vector< typename LayerGenerator::MyData > &l)
void setDomainSize(Size s)
Set the domain size of generated types.
Factory which builds a PRM<GUM_SCALAR>.
Definition: PRMType.h:47
Size getMaxParents() const
Returns the max number of parents allowed for any attribute or aggregator.
Size getDomainSize() const
Returns the domain size of generated types.
The base class for all directed edgesThis class is used as a basis for manipulating all directed edge...
const NodeSet & parents(const NodeId id) const
returns the set of nodes with arc ingoing to a given node
const NodeGraphPart & nodes() const
return *this as a NodeGraphPart
virtual void addArc(const NodeId tail, const NodeId head)
insert a new arc into the directed graph
Definition: DAG_inl.h:40
void __generateSystem(PRMFactory< GUM_SCALAR > &factory, std::vector< typename LayerGenerator::MyData > &l)
<agrum/PRM/generator/layerGenerator.h>
virtual void endClass(bool checkImplementations=true) override
Tells the factory that we finished a class declaration.
void setLayers(const std::vector< LayerData > &v)
Defines the structure of each layers.
virtual PRM< GUM_SCALAR > * generate()
Proceeds with the generation of the PRM<GUM_SCALAR>.
void setRawCPFByLines(const std::vector< GUM_SCALAR > &array)
Gives the factory the CPF in its raw form.
This class represents a Probabilistic Relational PRMSystem<GUM_SCALAR>.
Definition: PRM.h:63
virtual void startDiscreteType(const std::string &name, std::string super="") override
Start a discrete subtype declaration.
virtual ~LayerGenerator()
Destructor.
std::vector< LayerData > & getLayer()
Returns the domain size of generated types.
virtual void endDiscreteType() override
End the current discrete type declaration.
void setMaxParents(Size s)
Returns the max number of parents allowed for any attribute or aggregator.
virtual void addLabel(const std::string &l, std::string ext="") override
Add a label to the current discrete type.
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Definition: types.h:45
Size size() const noexcept
Returns the number of elements in the set.
Definition: set_tpl.h:698
virtual void endSystem() override
Tells the factory that we finished declaring a model.
Base class for dag.
Definition: DAG.h:99
bool existsArc(const Arc &arc) const
indicates whether a given arc exists
Size NodeId
Type for node ids.
Definition: graphElements.h:97
PRM< GUM_SCALAR > * prm() const
Returns a pointer on the PRM<GUM_SCALAR> created by this factory.
void insert(const Key &k)
Inserts a new element into the set.
Definition: set_tpl.h:610
LayerGenerator & operator=(const LayerGenerator &source)
Copy operator.
virtual void addParent(const std::string &name) override
Tells the factory that we add a parent to the current declared attribute.
#define GUM_ERROR(type, msg)
Definition: exceptions.h:52
void __generateClassDag(Size lvl, DAG &dag, Bijection< std::string, NodeId > &names, std::vector< typename LayerGenerator::MyData > &l)
std::string __generateType(PRMFactory< GUM_SCALAR > &f)