aGrUM 2.3.2
a C++ library for (probabilistic) graphical models
layerGenerator_tpl.h
Go to the documentation of this file.
1/****************************************************************************
2 * This file is part of the aGrUM/pyAgrum library. *
3 * *
4 * Copyright (c) 2005-2025 by *
5 * - Pierre-Henri WUILLEMIN(_at_LIP6) *
6 * - Christophe GONZALES(_at_AMU) *
7 * *
8 * The aGrUM/pyAgrum library is free software; you can redistribute it *
9 * and/or modify it under the terms of either : *
10 * *
11 * - the GNU Lesser General Public License as published by *
12 * the Free Software Foundation, either version 3 of the License, *
13 * or (at your option) any later version, *
14 * - the MIT license (MIT), *
15 * - or both in dual license, as here. *
16 * *
17 * (see https://agrum.gitlab.io/articles/dual-licenses-lgplv3mit.html) *
18 * *
19 * This aGrUM/pyAgrum library is distributed in the hope that it will be *
20 * useful, but WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
21 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES MERCHANTABILITY or FITNESS *
22 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
25 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR *
26 * OTHER DEALINGS IN THE SOFTWARE. *
27 * *
28 * See LICENCES for more details. *
29 * *
30 * SPDX-FileCopyrightText: Copyright 2005-2025 *
31 * - Pierre-Henri WUILLEMIN(_at_LIP6) *
32 * - Christophe GONZALES(_at_AMU) *
33 * SPDX-License-Identifier: LGPL-3.0-or-later OR MIT *
34 * *
35 * Contact : info_at_agrum_dot_org *
36 * homepage : http://agrum.gitlab.io *
37 * gitlab : https://gitlab.com/agrumery/agrum *
38 * *
39 ****************************************************************************/
40#pragma once
41
42
50
51namespace gum {
52 namespace prm {
53
54 template < typename GUM_SCALAR >
56 if (_layers_.size() == 0) {
57 GUM_ERROR(OperationNotAllowed, "cannot generate a layered PRM<GUM_SCALAR> without layers")
58 }
59
60 std::vector< MyData > l;
62 std::string type = _generateType_(factory);
63 _generateInterfaces_(factory, type, l);
64 _generateClasses_(factory, type, l);
65 _generateSystem_(factory, l);
66 return factory.prm();
67 }
68
69 template < typename GUM_SCALAR >
71 std::string name = this->name_gen_.nextName(PRMObject::prm_type::TYPE);
72 factory.startDiscreteType(name);
73
74 for (Size i = 0; i < _domain_size_; ++i) {
75 std::stringstream sBuff;
76 sBuff << i;
77 factory.addLabel(sBuff.str());
78 }
79
80 factory.endDiscreteType();
81 return name;
82 }
83
84 template < typename GUM_SCALAR >
87 const std::string& type,
88 std::vector< typename LayerGenerator< GUM_SCALAR >::MyData >& l) {
89 for (Size lvl = 0; lvl < _layers_.size(); ++lvl) {
91 l[lvl].i = this->name_gen_.nextName(PRMObject::prm_type::PRM_INTERFACE);
92 f.startInterface(l[lvl].i);
93
94 for (Size a = 0; a < _layers_[lvl].a; ++a) {
95 l[lvl].a.push_back(this->name_gen_.nextName(PRMObject::prm_type::CLASS_ELT));
96 f.addAttribute(type, l[lvl].a.back());
97 }
98
99 if (lvl) {
100 for (Size g = 0; g < _layers_[lvl].g; ++g) {
101 l[lvl].g.push_back(this->name_gen_.nextName(PRMObject::prm_type::CLASS_ELT));
102 f.addAttribute("boolean", l[lvl].g.back());
103 }
104
105 l[lvl].r = this->name_gen_.nextName(PRMObject::prm_type::CLASS_ELT);
106 f.addReferenceSlot(l[lvl - 1].i, l[lvl].r, true);
107 }
108
109 f.endInterface();
110 }
111 }
112
113 template < typename GUM_SCALAR >
116 const std::string& type,
117 std::vector< typename LayerGenerator< GUM_SCALAR >::MyData >& l) {
118 Size size = 0;
119 GUM_SCALAR sum = 0.0;
121
122 for (Size lvl = 0; lvl < _layers_.size(); ++lvl) {
123 i.insert(l[lvl].i);
124
125 for (Size c = 0; c < _layers_[lvl].c; ++c) {
126 l[lvl].c.push_back(this->name_gen_.nextName(PRMObject::prm_type::CLASS));
127 f.startClass(l[lvl].c.back(), "", &i);
128
129 if (lvl) f.addReferenceSlot(l[lvl - 1].i, l[lvl].r, true);
130
131 DAG dag;
133 _generateClassDag_(lvl, dag, names, l);
134
135 // Adding aggregates
136 if (lvl) {
137 for (std::vector< std::string >::iterator g = l[lvl].g.begin(); g != l[lvl].g.end();
138 ++g) {
139 std::stringstream s;
140 s << l[lvl].r << "." << l[lvl - 1].a[randomValue(l[lvl - 1].a.size())];
141 std::vector< std::string > chain(1, s.str()), param(1, "1");
142 f.addAggregator(*g, "exists", chain, param);
143 }
144 }
145
146 // Adding attributes
147 for (std::vector< std::string >::iterator a = l[lvl].a.begin(); a != l[lvl].a.end();
148 ++a) {
149 f.startAttribute(type, *a, true);
150 size = getDomainSize();
151
152 for (const auto par: dag.parents(names.second(*a))) {
153 f.addParent(names.first(par));
154 size *= f.retrieveClass(l[lvl].c.back()).get(names.first(par)).type()->domainSize();
155 }
156
157 std::vector< GUM_SCALAR > cpf(size), val(getDomainSize());
158
159 for (size_t norms = 0; norms < size; norms += getDomainSize()) {
160 sum = 0.0;
161
162 for (size_t idx = 0; idx < getDomainSize(); ++idx) {
163 val[idx] = 1 + std::rand();
164 sum += val[idx];
165 }
166
167 for (size_t idx = 0; idx < getDomainSize(); ++idx)
168 cpf[norms + idx] = val[idx] / sum;
169 }
170
171 f.setRawCPFByLines(cpf);
172 f.endAttribute();
173 }
174
175 f.endClass();
176 }
177
178 i.erase(l[lvl].i);
179 }
180 }
181
182 template < typename GUM_SCALAR >
184 Size lvl,
185 DAG& dag,
187 std::vector< typename LayerGenerator< GUM_SCALAR >::MyData >& l) {
188 float density = _layers_[lvl].inner_density;
189 std::vector< NodeId > nodes;
190 NodeId id = 0;
191
192 if (lvl) {
193 for (const auto& agg: l[lvl].g) {
194 id = dag.addNode();
195 names.insert(agg, id);
196 nodes.push_back(id);
197 }
198 }
199
200 for (const auto& attr: l[lvl].a) {
201 id = dag.addNode();
202 names.insert(attr, id);
203
204 for (const auto node: nodes)
205 if (randomProba() < density) dag.addArc(node, names.second(attr));
206
207 nodes.push_back(id);
208 }
209
210 // For each nodes with #parents > _max_parents_ we randomly remove parents
211 // until
212 // #parents <= _max_parents_
213 for (const auto node: dag.nodes()) {
214 if (dag.parents(node).size() > getMaxParents()) {
215 std::vector< NodeId > v;
216
217 for (const auto par: dag.parents(node))
218 v.push_back(par);
219
220 while (dag.parents(node).size() > getMaxParents()) {
221 size_t idx = randomValue(v.size());
222 Arc arc(v[idx], node);
223 GUM_ASSERT(dag.existsArc(arc));
224 dag.eraseArc(arc);
225 v[idx] = v.back();
226 v.pop_back();
227 }
228 }
229 }
230 }
231
232 template < typename GUM_SCALAR >
235 std::vector< typename LayerGenerator< GUM_SCALAR >::MyData >& l) {
236 factory.startSystem(this->name_gen_.nextName(PRMObject::prm_type::SYSTEM));
237 std::vector< std::vector< std::string > > o(_layers_.size());
238 std::string name;
239 size_t idx = 0;
240
241 for (size_t lvl = 0; lvl < _layers_.size(); ++lvl) {
242 float density = _layers_[lvl].outter_density;
243
244 for (size_t count = 0; count < _layers_[lvl].o; ++count) {
245 name = this->name_gen_.nextName(PRMObject::prm_type::PRM_INTERFACE);
246 factory.addInstance(l[lvl].c[randomValue(l[lvl].c.size())], name);
247 o[lvl].push_back(name);
248
249 if (lvl) {
250 std::stringstream chain;
251 chain << name << "." << l[lvl].r;
252 std::vector< std::string > ref2add;
253
254 for (std::vector< std::string >::iterator iter = o[lvl - 1].begin();
255 iter != o[lvl - 1].end();
256 ++iter)
257 if (randomProba() <= density) ref2add.push_back(*iter);
258
259 if (ref2add.empty())
260 factory.setReferenceSlot(chain.str(), o[lvl - 1][randomValue(o[lvl - 1].size())]);
261
262 while (ref2add.size() > getMaxParents()) {
263 idx = randomValue(ref2add.size());
264 ref2add[idx] = ref2add.back();
265 ref2add.pop_back();
266 }
267
268 for (std::vector< std::string >::iterator iter = ref2add.begin(); iter != ref2add.end();
269 ++iter)
270 factory.setReferenceSlot(chain.str(), *iter);
271 }
272 }
273 }
274
275 factory.endSystem();
276 }
277
278 template < typename GUM_SCALAR >
280 _layers_(), _domain_size_(2), _max_parents_(INT_MAX) {
281 GUM_CONSTRUCTOR(LayerGenerator);
282 }
283
284 template < typename GUM_SCALAR >
285 INLINE
291
292 template < typename GUM_SCALAR >
296
297 template < typename GUM_SCALAR >
305
306 template < typename GUM_SCALAR >
310
311 template < typename GUM_SCALAR >
315
316 template < typename GUM_SCALAR >
320
321 template < typename GUM_SCALAR >
325
326 template < typename GUM_SCALAR >
328 const std::vector< typename LayerGenerator< GUM_SCALAR >::LayerData >& v) {
329 _layers_ = v;
330 }
331
332 template < typename GUM_SCALAR >
333 INLINE std::vector< typename LayerGenerator< GUM_SCALAR >::LayerData >&
337
338 template < typename GUM_SCALAR >
339 INLINE const std::vector< typename LayerGenerator< GUM_SCALAR >::LayerData >&
343
344 } /* namespace prm */
345} /* namespace gum */
bool existsArc(const Arc &arc) const
indicates whether a given arc exists
const NodeSet & parents(NodeId id) const
returns the set of nodes with arc ingoing to a given node
virtual void eraseArc(const Arc &arc)
removes an arc from the ArcGraphPart
The base class for all directed edges.
Base class for dag.
Definition DAG.h:121
void addArc(NodeId tail, NodeId head) final
insert a new arc into the directed graph
Definition DAG_inl.h:63
const NodeGraphPart & nodes() const
return *this as a NodeGraphPart
virtual NodeId addNode()
insert a new node and return its id
Exception : operation not allowed.
Size size() const noexcept
Returns the number of elements in the set.
Definition set_tpl.h:636
void insert(const Key &k)
Inserts a new element into the set.
Definition set_tpl.h:539
<agrum/PRM/generator/layerGenerator.h>
void _generateInterfaces_(PRMFactory< GUM_SCALAR > &f, const std::string &type, std::vector< MyData > &l)
void _generateClassDag_(Size lvl, DAG &dag, Bijection< std::string, NodeId > &names, std::vector< typename LayerGenerator::MyData > &l)
std::string _generateType_(PRMFactory< GUM_SCALAR > &f)
void _generateClasses_(PRMFactory< GUM_SCALAR > &f, const std::string &type, std::vector< typename LayerGenerator::MyData > &l)
Size getDomainSize() const
Returns the domain size of generated types.
virtual PRM< GUM_SCALAR > * generate()
Proceeds with the generation of the PRM<GUM_SCALAR>.
std::vector< LayerData > _layers_
void _generateSystem_(PRMFactory< GUM_SCALAR > &factory, std::vector< typename LayerGenerator::MyData > &l)
LayerGenerator & operator=(const LayerGenerator &source)
Copy operator.
void setDomainSize(Size s)
Set the domain size of generated types.
virtual ~LayerGenerator()
Destructor.
void setMaxParents(Size s)
Returns the max number of parents allowed for any attribute or aggregator.
std::vector< LayerData > & getLayer()
Returns the domain size of generated types.
Size getMaxParents() const
Returns the max number of parents allowed for any attribute or aggregator.
LayerGenerator()
Default constructor.
void setLayers(const std::vector< LayerData > &v)
Defines the structure of each layers.
Factory which builds a PRM<GUM_SCALAR>.
Definition PRMFactory.h:88
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.
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 addInstance(const std::string &type, const std::string &name) override
Add an instance to the model.
virtual void addParent(const std::string &name) override
Tells the factory that we add a parent to the current declared attribute.
void setRawCPFByLines(const std::vector< GUM_SCALAR > &array)
Gives the factory the CPF in its raw form.
virtual void endSystem() override
Tells the factory that we finished declaring a model.
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.
PRMClass< GUM_SCALAR > & retrieveClass(const std::string &name)
Returns a reference over a Class<GUM_SCALAR> given its name.
virtual void addReferenceSlot(const std::string &type, const std::string &name, bool isArray) override
Tells the factory that we started declaring a slot.
virtual void endAttribute() override
Tells the factory that we finished declaring an attribute.
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.
virtual void endClass(bool checkImplementations=true) override
Tells the factory that we finished a class declaration.
virtual void startSystem(const std::string &name) override
Tells the factory that we started declaring a model.
virtual void addAttribute(const std::string &type, const std::string &name) override
Add an attribute to an interface.
virtual void endInterface() override
Tells the factory that we finished an interface declaration.
virtual void startDiscreteType(const std::string &name, std::string super="") override
Start a discrete subtype declaration.
PRM< GUM_SCALAR > * prm() const
Returns a pointer on the PRM<GUM_SCALAR> created by this factory.
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 endDiscreteType() override
End the current discrete type declaration.
virtual void addLabel(const std::string &l, std::string ext="") override
Add a label to the current discrete type.
NameGenerator name_gen_
The name generator used by this class.
This class represents a Probabilistic Relational PRMSystem<GUM_SCALAR>.
Definition PRM.h:74
#define GUM_ERROR(type, msg)
Definition exceptions.h:72
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Definition types.h:74
Size NodeId
Type for node ids.
Idx randomValue(const Size max=2)
Returns a random Idx between 0 and max-1 included.
double randomProba()
Returns a random double between 0 and 1 included (i.e.
Headers of LayerGenerator.
namespace for all probabilistic relational models entities
Definition agrum.h:68
gum is the global namespace for all aGrUM entities
Definition agrum.h:46