aGrUM  0.20.2
a C++ library for (probabilistic) graphical models
leafAggregator.cpp
Go to the documentation of this file.
1 /**
2  *
3  * Copyright 2005-2020 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 Sources for Leaf Aggregator class
25  *
26  * @author Pierre-Henri WUILLEMIN(@LIP6) and Jean-Christophe MAGNAN and Christophe
27  * GONZALES(@AMU)
28  */
29 // =======================================================
30 #include <agrum/tools/core/math/math_utils.h>
31 #include <agrum/FMDP/learning/datastructure/leaves/leafAggregator.h>
32 // =======================================================
33 
34 namespace gum {
35 
36  // ############################################################################
37  // Constructors / Destructors
38  // ############################################################################
39 
40  // ============================================================================
41  // Default constructor.
42  // ============================================================================
44  double similarityThreshold) :
48  initialContext__ = new FusionContext< true >(nullptr);
49  needsUpdate__ = false;
50  }
51 
52  // ============================================================================
53  // Default constructor.
54  // ============================================================================
56  removeContext__(0);
57 
58  delete initialContext__;
59 
63  ++leafIter) {
65  pairIter != leafIter.val()->endSafe();
66  ++pairIter) {
70  delete curPair;
71  }
72  delete leafIter.val();
73  }
74 
75 
77  }
78 
79  // ############################################################################
80  //
81  // ############################################################################
82 
83  // ============================================================================
84  //
85  // ============================================================================
87  Set< LeafPair* >* leafPairSet = new Set< LeafPair* >();
88  Set< LeafPair* > bag;
89 
90  // ****************************************************************************************
91  // Création et ajout des pairs de base (Feuille de base + nouvelle Feuille)
95  ++leafIter) {
96  // Création de la pair et ajout dans les listes de pair des feuilles de
97  // base
98  LeafPair* p = new LeafPair(l, leafIter.key());
100  leafPairSet->insert(p);
101  (leafIter.val())->insert(p);
102 
103  // Ajout de la nouvelle pair au tas initial
105 
106  bag.insert(p);
107  }
108 
109  // ****************************************************************************************
110  // Enregistrement de la nouvelle Feuille en tant que feuille de base
112 
113  // ****************************************************************************************
114  // Ajout de la feuille aux FusionContext
115 
116  for (SequenceIteratorSafe< FusionContext< false >* > fusIter
119  ++fusIter) {
120  // Ajout de la nouvelle pair composée de la feuille de FusIter et de la
121  // nouvelle feuille aux FusionContext suivant
123  pairIter != bag.endSafe();
124  ++pairIter) {
125  if ((*fusIter)->leaf()->contains((*pairIter)->secondLeaf()->id())) {
126  bag >> *pairIter;
127  continue;
128  }
129 
131  }
132 
134 
136  }
137 
138  needsUpdate__ = true;
139  }
140 
141 
142  // ============================================================================
143  //
144  // ============================================================================
146  // ***********************************************************************************
147  // First we update every base pair linked to that leaf
148  Set< LeafPair* > bag(*(leaf2Pair__[l]));
150  pairIter != bag.endSafe();
151  ++pairIter) {
154  }
155 
156  // **********************************************************************************
157  // The we have top update FusionContext pairs associated to that leaf
159  for (SequenceIteratorSafe< FusionContext< false >* > fusIter
162  ++fusIter) {
163  if ((*fusIter)->leaf()->contains(curLeaf->id())) {
164  bag.clear();
166  removeContext__(fusIter.pos() + 1);
167  bag = (*fusIter)->associatedPairs();
168  curLeaf = (*fusIter)->leaf();
169  continue;
170  }
171 
173  pairIter != bag.endSafe();
174  ++pairIter) {
175  if ((*fusIter)->leaf()->contains((*pairIter)->secondLeaf()->id())
176  || (*fusIter)->leaf()->contains((*pairIter)->firstLeaf()->id())) {
177  bag >> *pairIter;
178  continue;
179  }
180 
182  }
184  removeContext__(fusIter.pos() + 1);
186  }
187 
188  return needsUpdate__;
189  }
190 
191 
192  // ============================================================================
193  //
194  // ============================================================================
196  // ***********************************************************************************
197  // First we update every base pair linked to that leaf
198  Set< LeafPair* > bag(*(leaf2Pair__[l]));
200  pairIter != bag.endSafe();
201  ++pairIter) {
203  (*leaf2Pair__[(*pairIter)->otherLeaf(l)]) >> *pairIter;
204  }
205 
206  // **********************************************************************************
207  // The we have top update FusionContext pairs associated to that leaf
209  for (SequenceIteratorSafe< FusionContext< false >* > fusIter
212  ++fusIter) {
214  pairIter != bag.endSafe();
215  ++pairIter) {
216  if ((*fusIter)->leaf()->contains((*pairIter)->secondLeaf()->id())
217  || (*fusIter)->leaf()->contains((*pairIter)->firstLeaf()->id())) {
218  bag >> *pairIter;
219  continue;
220  }
221 
222  if ((*fusIter)->removePair(*pairIter)) {
223  removeContext__(fusIter.pos() + 1);
224  }
225  }
226 
229 
230  if ((*fusIter)->deassociateLeaf(l)) { removeContext__(fusIter.pos() + 1); }
231  }
232 
235  ++pairIter)
236  delete *pairIter;
237 
239  pairIter != leaf2Pair__[l]->endSafe();
240  ++pairIter)
241  delete *pairIter;
242  delete leaf2Pair__[l];
244 
245  needsUpdate__ = true;
246  }
247 
248 
249  // ============================================================================
250  //
251  // ============================================================================
256  if (!fusionSeq__.empty()) {
257  nextPair = fusionSeq__.back()->top();
258  pb = fusionSeq__.back()->beginPairs();
259  pe = fusionSeq__.back()->endPairs();
260  }
261 
262 
265  FusionContext< false >* newContext = new FusionContext< false >(newLeaf);
266 
267  for (pair_iterator pairIter = pb; pairIter != pe; ++pairIter) {
268  if (!newLeaf->contains(pairIter.key()->firstLeaf()->id())
269  && !newLeaf->contains(pairIter.key()->secondLeaf()->id()))
271  if (!newLeaf->contains(pairIter.key()->firstLeaf()->id())
274  if (!newLeaf->contains(pairIter.key()->secondLeaf()->id())
277  }
278 
280  nextPair = fusionSeq__.back()->top();
281  pb = fusionSeq__.back()->beginPairs();
282  pe = fusionSeq__.back()->endPairs();
283  }
284  needsUpdate__ = false;
285  }
286 
287 
290  for (SequenceIteratorSafe< FusionContext< false >* > fusIter
293  --fusIter) {
294  bool alreadyIn = false;
296  = retMap.beginSafe();
297  mapIter != retMap.endSafe();
298  ++mapIter)
299  if (mapIter.val()->contains((*fusIter)->leaf()->id())) {
300  alreadyIn = true;
301  break;
302  }
303  if (!alreadyIn) retMap.insert((*fusIter)->leaf()->id(), (*fusIter)->leaf());
304  }
305 
309  ++leafIter) {
311  = retMap.beginSafe();
312  mapIter != retMap.endSafe();
313  ++mapIter)
314  if (mapIter.val()->contains(leafIter.key()->id())) {
316  break;
317  }
318  if (!retMap.exists(leafIter.key()->id()))
320  }
321 
322  return retMap;
323  }
324 
325 
328  ss << "################\nTas Initial : " << std::endl
329  << initialContext__->toString() << std::endl;
330 
332  ++fusIter) {
333  ss << "################\nTas " << fusIter.pos() << " : " << std::endl
334  << (*fusIter)->toString();
335  }
336 
337  return ss.str();
338  }
339 
340  // ############################################################################
341  //
342  // ############################################################################
343 
344  // ============================================================================
345  //
346  // ============================================================================
348  for (Idx i = fusionSeq__.size() - 1; !fusionSeq__.empty() && i >= startingPos;
349  --i) {
351  delete fusionSeq__.atPos(i);
353  }
354 
355  needsUpdate__ = true;
356  }
357 
358 
359  // ============================================================================
360  //
361  // ============================================================================
363  bool res = initialContext__->addPair(p);
364  if (res) removeContext__(0);
365  }
366 
367 
368  // ============================================================================
369  //
370  // ============================================================================
372  bool res = initialContext__->updatePair(p);
373  if (res) removeContext__(0);
374  }
375 
376  // ============================================================================
377  //
378  // ============================================================================
380  bool res = initialContext__->removePair(p);
381  if (res) removeContext__(0);
382  }
383 
384 } // namespace gum
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:669