aGrUM  0.20.3
a C++ library for (probabilistic) graphical models
aggregatorDecomposition_tpl.h
Go to the documentation of this file.
1 /**
2  *
3  * Copyright 2005-2019 Pierre-Henri WUILLEMIN & Christophe GONZALES(@AMU)
4  * {prenom.nom}_at_lip6.fr
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 AggregatorDecomposition.
25  *
26  * @author Gaspard Ducamp
27  *
28  */
29 #include <agrum/BN/inference/tools/aggregatorDecomposition.h>
30 #include <typeinfo>
31 #include <list>
32 
33 namespace gum {
34 
35  template < typename GUM_SCALAR >
36  INLINE AggregatorDecomposition< GUM_SCALAR >::AggregatorDecomposition() {
37  _arity_ = 2;
39  }
40 
41  template < typename GUM_SCALAR >
44  }
45 
46  template < typename GUM_SCALAR >
49  for (NodeId node: bn.nodes().asNodeSet()) {
51  auto p = dynamic_cast< const gum::aggregator::MultiDimAggregator< GUM_SCALAR >* >(
52  bn.cpt(node).content());
53  if (p != nullptr && p->isDecomposable()) { decomposeAggregator_(bn, node); }
54  }
55  return bn;
56  }
57 
58  template < typename GUM_SCALAR >
61  const DiscreteVariable& var,
62  Idx value) {
63  if (toLower(aggType) == "min") {
64  return bn.addMIN(var);
65  } else if (toLower(aggType) == "max") {
66  return bn.addMAX(var);
67  } else if (toLower(aggType) == "count") {
68  return bn.addCOUNT(var, value);
69  } else if (toLower(aggType) == "exists") {
70  return bn.addEXISTS(var, value);
71  } else if (toLower(aggType) == "or") {
72  return bn.addOR(var);
73  } else if (toLower(aggType) == "and") {
74  return bn.addAND(var);
75  } else if (toLower(aggType) == "forall") {
76  return bn.addFORALL(var);
77  } else if (toLower(aggType) == "amplitude") {
78  return bn.addAMPLITUDE(var);
79  } else if (toLower(aggType) == "median") {
80  return bn.addMEDIAN(var);
81  } else if (toLower(aggType) == "sum") {
82  return bn.addSUM(var);
83  } else {
84  std::string msg = "Unknown aggregate: ";
87  }
88  }
89 
90  template < typename GUM_SCALAR >
94  auto p = static_cast< const gum::aggregator::MultiDimAggregator< GUM_SCALAR >* >(
97 
99 
100  std::list< NodeId > orderedParents = {};
101 
102  for (const auto& elt: parents) {
104  }
105 
107 
108  Set< NodeId > newAggs = Set< NodeId >();
110 
112  gum::Size q = 0;
113  gum::Size i = 0;
114 
115  long minVal = 0;
116  long maxVal = 0;
117 
118  int j = 1;
119 
123 
124  for (auto parent: parents) {
126  }
127 
128  /*
129  * We are constructing the new aggregator with a clone of the former
130  */
133 
134  // for(Set<NodeId>::iterator it = parents.begin(); it!= parents.end(); ++it){
135  for (auto it = orderedParents.begin(); it != orderedParents.end(); ++it) {
136  if (q < parents.size() - parents.size() % arity) {
137  if (i == arity) {
138  i = 0;
139  j++;
140 
141  if (newAgg->varType() == VarType::Labelized) {
143  } else if (newAgg->varType() == VarType::Range) {
144  static_cast< RangeVariable* >(newAgg)->setMinVal(minVal);
145  static_cast< RangeVariable* >(newAgg)->setMaxVal(maxVal);
147  } else {
148  GUM_ERROR(OperationNotAllowed, "Decomposition is not available for type : " + aggType)
149  }
150 
151  /*
152  * Adding arcs in the new node from its parents and adding thoses into
153  * the temporary potential
154  */
155  for (NodeId node: newAggParents) {
157  }
158 
159  /*
160  * Adding the new aggregator in t
161  */
163 
165 
166  minVal = 0;
167  maxVal = 0;
168 
170 
171  delete (newAgg);
175 
176  if (bn.variable(*it).varType() == VarType::Range) {
177  minVal += static_cast< const RangeVariable& >(bn.variable(*it)).minVal();
178  maxVal += static_cast< const RangeVariable& >(bn.variable(*it)).maxVal();
179  }
180 
182  i++;
183  } else {
184  if (bn.variable(*it).varType() == VarType::Range) {
185  minVal += static_cast< const RangeVariable& >(bn.variable(*it)).minVal();
186  maxVal += static_cast< const RangeVariable& >(bn.variable(*it)).maxVal();
187  }
188 
190  i++;
191  }
192  } else {
193  newAggs.insert(*it);
194  }
195  q++;
196  }
197 
198  if (newAgg->varType() == VarType::Labelized) {
200  } else if (newAgg->varType() == VarType::Range) {
201  static_cast< RangeVariable* >(newAgg)->setMinVal(minVal);
202  static_cast< RangeVariable* >(newAgg)->setMaxVal(maxVal);
204  } else {
205  GUM_ERROR(OperationNotAllowed, "Decomposition is not available for type : " + aggType)
206  }
207 
209 
210  for (NodeId node: newAggParents) {
212  }
213 
215 
216  for (auto agg: final) {
218  }
219 
220  delete (newAgg);
221  return bn;
222  }
223 
224  template < typename GUM_SCALAR >
226  Set< NodeId > nodes,
228  int& j) {
229  auto p = static_cast< const gum::aggregator::MultiDimAggregator< GUM_SCALAR >* >(
231 
234 
235  if (nodes.size() <= arity) {
236  return nodes;
237  } else {
239 
240  Set< NodeId > newAggs = Set< NodeId >();
241 
243 
244  std::list< NodeId > orderedParents = {};
245 
246  for (const auto& elt: nodes) {
248  }
249 
251 
252  gum::Size i = 0;
253  gum::Size q = 0;
254  long minVal = 0;
255  long maxVal = 0;
256 
257  j++;
258 
261 
264 
265  // for(Set<NodeId>::iterator it = nodes.begin(); it!= nodes.end(); ++it){
266  for (auto it = orderedParents.begin(); it != orderedParents.end(); ++it) {
267  if (q < nodes.size() - nodes.size() % arity) {
268  if (i == arity) {
269  i = 0;
270  j++;
271 
272  if (newAgg->varType() == VarType::Labelized) {
274  } else if (newAgg->varType() == VarType::Range) {
275  static_cast< RangeVariable* >(newAgg)->setMinVal(minVal);
276  static_cast< RangeVariable* >(newAgg)->setMaxVal(maxVal);
278  } else {
279  GUM_ERROR(OperationNotAllowed, "Decomposition is not available for type : " + aggType)
280  }
281 
282  for (NodeId node: newAggParents) {
284  }
285 
287 
289 
290  minVal = 0;
291  maxVal = 0;
292 
294 
295  delete (newAgg);
299 
300  if (bn.variable(*it).varType() == VarType::Range) {
301  minVal += static_cast< const RangeVariable& >(bn.variable(*it)).minVal();
302  maxVal += static_cast< const RangeVariable& >(bn.variable(*it)).maxVal();
303  }
304 
306  i++;
307  } else {
308  if (bn.variable(*it).varType() == VarType::Range) {
309  minVal += static_cast< const RangeVariable& >(bn.variable(*it)).minVal();
310  maxVal += static_cast< const RangeVariable& >(bn.variable(*it)).maxVal();
311  }
312 
314  i++;
315  }
316  } else {
317  newAggs.insert(*it);
318  }
319  q++;
320  }
321 
322  if (newAgg->varType() == VarType::Labelized) {
324  } else if (newAgg->varType() == VarType::Range) {
325  static_cast< RangeVariable* >(newAgg)->setMinVal(minVal);
326  static_cast< RangeVariable* >(newAgg)->setMaxVal(maxVal);
328  } else {
329  GUM_ERROR(OperationNotAllowed, "Decomposition is not available for type : " + aggType)
330  }
331 
333 
334  for (NodeId node: newAggParents) {
336  }
337 
338  delete (newAgg);
340  }
341  }
342 
343 
344  template < typename GUM_SCALAR >
346  if (arity < 2) { GUM_ERROR(OperationNotAllowed, "Maximum arity should be at least 2") }
347  _arity_ = arity;
348  }
349 
350  template < typename GUM_SCALAR >
352  return _arity_;
353  }
354 
355  template < typename GUM_SCALAR >
357  return "aggregator decomposition";
358  }
359 
360 } /* namespace gum */
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:643