aGrUM  0.18.1
a C++ library for (probabilistic) graphical models
aggregatorDecomposition_tpl.h
Go to the documentation of this file.
1 
31 #include <typeinfo>
32 #include <list>
33 
34 namespace gum {
35 
36  template < typename GUM_SCALAR >
38  arity__ = 2;
39  GUM_CONSTRUCTOR(AggregatorDecomposition);
40  }
41 
42  template < typename GUM_SCALAR >
44  GUM_DESTRUCTOR(AggregatorDecomposition);
45  }
46 
47  template < typename GUM_SCALAR >
51  for (NodeId node: bn.nodes().asNodeSet()) {
52  std::string description = bn.cpt(node).toString();
53  auto p =
55  bn.cpt(node).content());
56  if (p != nullptr && p->isDecomposable()) { decomposeAggregator_(bn, node); }
57  }
58  return bn;
59  }
60 
61  template < typename GUM_SCALAR >
64  std::string aggType,
65  const DiscreteVariable& var,
66  Idx value) {
67  if (toLower(aggType) == "min") {
68  return bn.addMIN(var);
69  } else if (toLower(aggType) == "max") {
70  return bn.addMAX(var);
71  } else if (toLower(aggType) == "count") {
72  return bn.addCOUNT(var, value);
73  } else if (toLower(aggType) == "exists") {
74  return bn.addEXISTS(var, value);
75  } else if (toLower(aggType) == "or") {
76  return bn.addOR(var);
77  } else if (toLower(aggType) == "and") {
78  return bn.addAND(var);
79  } else if (toLower(aggType) == "forall") {
80  return bn.addFORALL(var);
81  } else if (toLower(aggType) == "amplitude") {
82  return bn.addAMPLITUDE(var);
83  } else if (toLower(aggType) == "median") {
84  return bn.addMEDIAN(var);
85  } else if (toLower(aggType) == "sum") {
86  return bn.addSUM(var);
87  } else {
88  std::string msg = "Unknown aggregate: ";
89  msg.append(aggType);
90  GUM_ERROR(NotFound, msg);
91  }
92  }
93 
94  template < typename GUM_SCALAR >
97  BayesNet< GUM_SCALAR >& bn, NodeId initialAggregator) {
98  auto p =
100  bn.cpt(initialAggregator).content());
101  auto newAgg = bn.variable(initialAggregator).clone();
102 
103  Set< NodeId > parents = bn.parents(initialAggregator);
104 
105  std::list< NodeId > orderedParents = {};
106 
107  for (const auto& elt: parents) {
108  orderedParents.push_back(elt);
109  }
110 
111  orderedParents.sort();
112 
113  Set< NodeId > newAggs = Set< NodeId >();
114  List< NodeId > newAggParents;
115 
116  gum::Size arity = getMaximumArity();
117  gum::Size q = 0;
118  gum::Size i = 0;
119 
120  long minVal = 0;
121  long maxVal = 0;
122 
123  int j = 1;
124 
125  std::string newName = std::string(bn.variable(initialAggregator).name()) + "_"
126  + std::to_string(j);
127  std::string aggType = p->aggregatorName();
128 
129  for (auto parent: parents) {
130  bn.eraseArc(parent, initialAggregator);
131  }
132 
133  /*
134  * We are constructing the new aggregator with a clone of the former
135  */
136  newAgg->setName(newName);
137  newAgg->setDescription(aggType);
138 
139  // for(Set<NodeId>::iterator it = parents.begin(); it!= parents.end(); ++it){
140  for (auto it = orderedParents.begin(); it != orderedParents.end(); ++it) {
141  if (q < parents.size() - parents.size() % arity) {
142  if (i == arity) {
143  i = 0;
144  j++;
145 
146  if (newAgg->varType() == VarType::Labelized) {
147  addAggregator_(bn, aggType, *newAgg, p->domainSize());
148  } else if (newAgg->varType() == VarType::Range) {
149  static_cast< RangeVariable* >(newAgg)->setMinVal(minVal);
150  static_cast< RangeVariable* >(newAgg)->setMaxVal(maxVal);
151  addAggregator_(bn, aggType, *newAgg, 0);
152  } else {
154  "Decomposition is not available for type : " + aggType);
155  }
156 
157  /*
158  * Adding arcs in the new node from its parents and adding thoses into
159  * the temporary potential
160  */
161  for (NodeId node: newAggParents) {
162  bn.addArc(node, bn.idFromName(newName));
163  }
164 
165  /*
166  * Adding the new aggregator in t
167  */
168  newAggs.insert(bn.idFromName(newName));
169 
170  newAggParents.clear();
171 
172  minVal = 0;
173  maxVal = 0;
174 
175  newName = std::string(bn.variable(initialAggregator).name()) + "_"
176  + std::to_string(j);
177 
178  delete (newAgg);
179  newAgg = bn.variable(initialAggregator).clone();
180  newAgg->setName(newName);
181  newAgg->setDescription(aggType);
182 
183  if (bn.variable(*it).varType() == VarType::Range) {
184  minVal +=
185  static_cast< const RangeVariable& >(bn.variable(*it)).minVal();
186  maxVal +=
187  static_cast< const RangeVariable& >(bn.variable(*it)).maxVal();
188  }
189 
190  newAggParents.push_back(*it);
191  i++;
192  } else {
193  if (bn.variable(*it).varType() == VarType::Range) {
194  minVal +=
195  static_cast< const RangeVariable& >(bn.variable(*it)).minVal();
196  maxVal +=
197  static_cast< const RangeVariable& >(bn.variable(*it)).maxVal();
198  }
199 
200  newAggParents.push_back(*it);
201  i++;
202  }
203  } else {
204  newAggs.insert(*it);
205  }
206  q++;
207  }
208 
209  if (newAgg->varType() == VarType::Labelized) {
210  addAggregator_(bn, aggType, *newAgg, p->domainSize());
211  } else if (newAgg->varType() == VarType::Range) {
212  static_cast< RangeVariable* >(newAgg)->setMinVal(minVal);
213  static_cast< RangeVariable* >(newAgg)->setMaxVal(maxVal);
214  addAggregator_(bn, aggType, *newAgg, 0);
215  } else {
217  "Decomposition is not available for type : " + aggType);
218  }
219 
220  newAggs.insert(bn.idFromName(newName));
221 
222  for (NodeId node: newAggParents) {
223  bn.addArc(node, bn.idFromName(newName));
224  }
225 
226  Set< NodeId > final = addDepthLayer_(bn, newAggs, initialAggregator, j);
227 
228  for (auto agg: final) {
229  bn.addArc(agg, initialAggregator);
230  }
231 
232  delete (newAgg);
233  return bn;
234  }
235 
236  template < typename GUM_SCALAR >
239  Set< NodeId > nodes,
240  NodeId initialAggregator,
241  int& j) {
242  auto p =
244  bn.cpt(initialAggregator).content());
245 
246  gum::Size arity = getMaximumArity();
247  std::string aggType = p->aggregatorName();
248 
249  if (nodes.size() <= arity) {
250  return nodes;
251  } else {
252  auto newAgg = bn.variable(initialAggregator).clone();
253 
254  Set< NodeId > newAggs = Set< NodeId >();
255 
256  List< NodeId > newAggParents;
257 
258  std::list< NodeId > orderedParents = {};
259 
260  for (const auto& elt: nodes) {
261  orderedParents.push_back(elt);
262  }
263 
264  orderedParents.sort();
265 
266  gum::Size i = 0;
267  gum::Size q = 0;
268  long minVal = 0;
269  long maxVal = 0;
270 
271  j++;
272 
273  std::string newName = std::string(bn.variable(initialAggregator).name())
274  + "_" + std::to_string(j);
275 
276  newAgg->setName(newName);
277  newAgg->setDescription(aggType);
278 
279  // for(Set<NodeId>::iterator it = nodes.begin(); it!= nodes.end(); ++it){
280  for (auto it = orderedParents.begin(); it != orderedParents.end(); ++it) {
281  if (q < nodes.size() - nodes.size() % arity) {
282  if (i == arity) {
283  i = 0;
284  j++;
285 
286  if (newAgg->varType() == VarType::Labelized) {
287  addAggregator_(bn, aggType, *newAgg, p->domainSize());
288  } else if (newAgg->varType() == VarType::Range) {
289  static_cast< RangeVariable* >(newAgg)->setMinVal(minVal);
290  static_cast< RangeVariable* >(newAgg)->setMaxVal(maxVal);
291  addAggregator_(bn, aggType, *newAgg, 0);
292  } else {
294  "Decomposition is not available for type : " + aggType);
295  }
296 
297  for (NodeId node: newAggParents) {
298  bn.addArc(node, bn.idFromName(newName));
299  }
300 
301  newAggs.insert(bn.idFromName(newName));
302 
303  newAggParents.clear();
304 
305  minVal = 0;
306  maxVal = 0;
307 
308  newName = std::string(bn.variable(initialAggregator).name()) + "_"
309  + std::to_string(j);
310 
311  delete (newAgg);
312  newAgg = bn.variable(initialAggregator).clone();
313  newAgg->setName(newName);
314  newAgg->setDescription(aggType);
315 
316  if (bn.variable(*it).varType() == VarType::Range) {
317  minVal +=
318  static_cast< const RangeVariable& >(bn.variable(*it)).minVal();
319  maxVal +=
320  static_cast< const RangeVariable& >(bn.variable(*it)).maxVal();
321  }
322 
323  newAggParents.push_back(*it);
324  i++;
325  } else {
326  if (bn.variable(*it).varType() == VarType::Range) {
327  minVal +=
328  static_cast< const RangeVariable& >(bn.variable(*it)).minVal();
329  maxVal +=
330  static_cast< const RangeVariable& >(bn.variable(*it)).maxVal();
331  }
332 
333  newAggParents.push_back(*it);
334  i++;
335  }
336  } else {
337  newAggs.insert(*it);
338  }
339  q++;
340  }
341 
342  if (newAgg->varType() == VarType::Labelized) {
343  addAggregator_(bn, aggType, *newAgg, p->domainSize());
344  } else if (newAgg->varType() == VarType::Range) {
345  static_cast< RangeVariable* >(newAgg)->setMinVal(minVal);
346  static_cast< RangeVariable* >(newAgg)->setMaxVal(maxVal);
347  addAggregator_(bn, aggType, *newAgg, 0);
348  } else {
350  "Decomposition is not available for type : " + aggType);
351  }
352 
353  newAggs.insert(bn.idFromName(newName));
354 
355  for (NodeId node: newAggParents) {
356  bn.addArc(node, bn.idFromName(newName));
357  }
358 
359  delete (newAgg);
360  return addDepthLayer_(bn, newAggs, initialAggregator, j);
361  }
362  }
363 
364 
365  template < typename GUM_SCALAR >
366  INLINE void
368  if (arity < 2) {
369  GUM_ERROR(OperationNotAllowed, "Maximum arity should be at least 2");
370  }
371  arity__ = arity;
372  }
373 
374  template < typename GUM_SCALAR >
376  return arity__;
377  }
378 
379  template < typename GUM_SCALAR >
380  INLINE std::string AggregatorDecomposition< GUM_SCALAR >::name() const {
381  return "aggregator decomposition";
382  }
383 
384 } /* namespace gum */
void addArc(NodeId tail, NodeId head)
Add an arc in the BN, and update arc.head&#39;s CPT.
Definition: BayesNet_tpl.h:370
Class representing a Bayesian Network.
Definition: BayesNet.h:78
void setName(const std::string &theValue)
sets the name of the variable
NodeId addCOUNT(const DiscreteVariable &var, Idx value=1)
Others aggregators.
Definition: BayesNet_tpl.h:495
const DiscreteVariable & variable(NodeId id) const final
Returns a gum::DiscreteVariable given its gum::NodeId in the gum::BayesNet.
Definition: BayesNet_tpl.h:214
const NodeSet & parents(const NodeId id) const
returns the set of nodes with arc ingoing to a given node
Definition: DAGmodel_inl.h:55
AggregatorDecomposition()
Default constructor.
virtual DiscreteVariable * clone() const =0
Copy Factory.
virtual VarType varType() const =0
returns the varType of variable
NodeId addAMPLITUDE(const DiscreteVariable &var)
Others aggregators.
Definition: BayesNet_tpl.h:483
<agrum/BN/inference/tools/aggregatorDecomposition.h>
virtual ~AggregatorDecomposition()
Destructor.
NodeId addAND(const DiscreteVariable &var)
Add a variable, it&#39;s associate node and an AND implementation.
Definition: BayesNet_tpl.h:488
Base class for discrete random variable.
Generic doubly linked lists.
Definition: list.h:372
Copyright 2005-2020 Pierre-Henri WUILLEMIN() & Christophe GONZALES() info_at_agrum_dot_org.
Definition: agrum.h:25
NodeId addFORALL(const DiscreteVariable &var, Idx value=1)
Others aggregators.
Definition: BayesNet_tpl.h:509
<agrum/tools/multidim/aggregators/multiDimAggregator.h>
BayesNet< GUM_SCALAR > & decomposeAggregator_(BayesNet< GUM_SCALAR > &bn, NodeId node)
std::string to_string(const Formula &f)
Definition: formula_inl.h:499
const NodeGraphPart & nodes() const
Returns a constant reference to the dag of this Bayes Net.
Definition: DAGmodel_inl.h:70
std::string toLower(std::string str)
Returns the lowercase version of str.
NodeId addOR(const DiscreteVariable &var)
Add a variable, it&#39;s associate node and an OR implementation.
Definition: BayesNet_tpl.h:532
NodeSet asNodeSet() const
returns a copy of the set of nodes represented by the NodeGraphPart
Copyright 2005-2019 Pierre-Henri WUILLEMIN & Christophe GONZALES() {prenom.nom}_at_lip6.fr.
NodeId addEXISTS(const DiscreteVariable &var, Idx value=1)
Others aggregators.
Definition: BayesNet_tpl.h:501
Set< NodeId > addDepthLayer_(BayesNet< GUM_SCALAR > &bn, Set< NodeId > nodes, NodeId initialAggregator, int &j)
Defines a discrete random variable over an integer interval.
Definition: rangeVariable.h:54
const Potential< GUM_SCALAR > & cpt(NodeId varId) const final
Returns the CPT of a variable.
Definition: BayesNet_tpl.h:327
virtual Size domainSize() const override
Returns the product of the variables domain size.
BayesNet< GUM_SCALAR > & getDecomposedAggregator(BayesNet< GUM_SCALAR > &bn)
Default constructor.
NodeId addMAX(const DiscreteVariable &var)
Others aggregators.
Definition: BayesNet_tpl.h:517
Size Idx
Type for indexes.
Definition: types.h:53
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Definition: types.h:48
NodeId addMEDIAN(const DiscreteVariable &var)
Others aggregators.
Definition: BayesNet_tpl.h:522
NodeId idFromName(const std::string &name) const final
Returns a variable&#39;s id given its name in the gum::BayesNet.
Definition: BayesNet_tpl.h:315
Size size() const noexcept
Returns the number of elements in the set.
Definition: set_tpl.h:701
NodeId addSUM(const DiscreteVariable &var)
Others aggregators.
Definition: BayesNet_tpl.h:539
const std::string & name() const
returns the name of the variable
Size NodeId
Type for node ids.
Definition: graphElements.h:98
void insert(const Key &k)
Inserts a new element into the set.
Definition: set_tpl.h:613
#define GUM_ERROR(type, msg)
Definition: exceptions.h:55
NodeId addMIN(const DiscreteVariable &var)
Others aggregators.
Definition: BayesNet_tpl.h:527
NodeId addAggregator_(BayesNet< GUM_SCALAR > &bn, std::string aggType, const DiscreteVariable &var, Idx value)
void eraseArc(const Arc &arc)
Removes an arc in the BN, and update head&#39;s CTP.
Definition: BayesNet_tpl.h:393