aGrUM  0.20.3
a C++ library for (probabilistic) graphical models
gum::LeafAggregator Class Reference

<agrum/FMDP/learning/FunctionGraph/leafAggregator.h> More...

#include <leafAggregator.h>

+ Collaboration diagram for gum::LeafAggregator:

Public Member Functions

void update ()
 
bool needsUpdate ()
 
HashTable< NodeId, AbstractLeaf *> leavesMap ()
 
std::string toString ()
 
Constructor & destructor.
 LeafAggregator (NodeGraphPart *idSource, double similarityThreshold)
 Default constructor. More...
 
 ~LeafAggregator ()
 Default destructor. More...
 
Leaf Handling methods
void addLeaf (AbstractLeaf *)
 
bool updateLeaf (AbstractLeaf *)
 
void removeLeaf (AbstractLeaf *)
 
void begin ()
 
bool hasNext ()
 
double next ()
 

Detailed Description

<agrum/FMDP/learning/FunctionGraph/leafAggregator.h>

Gather together leaves with similar distributions

Definition at line 59 of file leafAggregator.h.

Constructor & Destructor Documentation

◆ LeafAggregator()

gum::LeafAggregator::LeafAggregator ( NodeGraphPart idSource,
double  similarityThreshold 
)

Default constructor.

Definition at line 43 of file leafAggregator.cpp.

References gum::Set< Key, Alloc >::emplace().

43  :
44  _leavesCpt_(idSource), _similarityThreshold_(similarityThreshold) {
45  GUM_CONSTRUCTOR(LeafAggregator);
47  _needsUpdate_ = false;
48  }
FusionContext< true > * _initialContext_
NodeGraphPart * _leavesCpt_
LeafAggregator(NodeGraphPart *idSource, double similarityThreshold)
Default constructor.
+ Here is the call graph for this function:

◆ ~LeafAggregator()

gum::LeafAggregator::~LeafAggregator ( )

Default destructor.

Definition at line 53 of file leafAggregator.cpp.

References gum::Set< Key, Alloc >::emplace().

53  {
54  _removeContext_(0);
55 
56  delete _initialContext_;
57 
58  for (HashTableIteratorSafe< AbstractLeaf*, Set< LeafPair* >* > leafIter
59  = _leaf2Pair_.beginSafe();
60  leafIter != _leaf2Pair_.endSafe();
61  ++leafIter) {
62  for (SetIteratorSafe< LeafPair* > pairIter = leafIter.val()->beginSafe();
63  pairIter != leafIter.val()->endSafe();
64  ++pairIter) {
65  LeafPair* curPair = *pairIter;
66  _leaf2Pair_[curPair->otherLeaf(leafIter.key())]->erase(*pairIter);
67  leafIter.val()->erase(curPair);
68  delete curPair;
69  }
70  delete leafIter.val();
71  }
72 
73 
74  GUM_DESTRUCTOR(LeafAggregator);
75  }
HashTable< AbstractLeaf *, Set< LeafPair *> *> _leaf2Pair_
FusionContext< true > * _initialContext_
LeafAggregator(NodeGraphPart *idSource, double similarityThreshold)
Default constructor.
+ Here is the call graph for this function:

Member Function Documentation

◆ _addInitialPair_()

void gum::LeafAggregator::_addInitialPair_ ( LeafPair p)
private

Definition at line 342 of file leafAggregator.cpp.

References gum::Set< Key, Alloc >::emplace().

342  {
343  bool res = _initialContext_->addPair(p);
344  if (res) _removeContext_(0);
345  }
FusionContext< true > * _initialContext_
bool addPair(LeafPair *p)
+ Here is the call graph for this function:

◆ _removeContext_()

void gum::LeafAggregator::_removeContext_ ( Idx  startingPos)
private

Definition at line 328 of file leafAggregator.cpp.

References gum::Set< Key, Alloc >::emplace().

328  {
329  for (Idx i = _fusionSeq_.size() - 1; !_fusionSeq_.empty() && i >= startingPos; --i) {
330  _leavesCpt_->eraseNode(_fusionSeq_.atPos(i)->leaf()->id());
331  delete _fusionSeq_.atPos(i);
332  _fusionSeq_.erase(_fusionSeq_.atPos(i));
333  }
334 
335  _needsUpdate_ = true;
336  }
Sequence< FusionContext< false > *> _fusionSeq_
NodeGraphPart * _leavesCpt_
virtual void eraseNode(const NodeId id)
erase the node with the given id
+ Here is the call graph for this function:

◆ _removeInitialPair_()

void gum::LeafAggregator::_removeInitialPair_ ( LeafPair p)
private

Definition at line 359 of file leafAggregator.cpp.

References gum::Set< Key, Alloc >::emplace().

359  {
360  bool res = _initialContext_->removePair(p);
361  if (res) _removeContext_(0);
362  }
bool removePair(LeafPair *p)
FusionContext< true > * _initialContext_
+ Here is the call graph for this function:

◆ _updateInitialPair_()

void gum::LeafAggregator::_updateInitialPair_ ( LeafPair p)
private

Definition at line 351 of file leafAggregator.cpp.

References gum::Set< Key, Alloc >::emplace().

351  {
352  bool res = _initialContext_->updatePair(p);
353  if (res) _removeContext_(0);
354  }
FusionContext< true > * _initialContext_
bool updatePair(LeafPair *p)
+ Here is the call graph for this function:

◆ addLeaf()

void gum::LeafAggregator::addLeaf ( AbstractLeaf l)

Definition at line 84 of file leafAggregator.cpp.

References gum::Set< Key, Alloc >::emplace().

84  {
85  Set< LeafPair* >* leafPairSet = new Set< LeafPair* >();
86  Set< LeafPair* > bag;
87 
88  // ****************************************************************************************
89  // Création et ajout des pairs de base (Feuille de base + nouvelle Feuille)
90  for (HashTableConstIteratorSafe< AbstractLeaf*, Set< LeafPair* >* > leafIter
91  = _leaf2Pair_.cbeginSafe();
92  leafIter != _leaf2Pair_.cendSafe();
93  ++leafIter) {
94  // Création de la pair et ajout dans les listes de pair des feuilles de
95  // base
96  LeafPair* p = new LeafPair(l, leafIter.key());
97  p->updateLikelyhood();
98  leafPairSet->insert(p);
99  (leafIter.val())->insert(p);
100 
101  // Ajout de la nouvelle pair au tas initial
102  _addInitialPair_(p);
103 
104  bag.insert(p);
105  }
106 
107  // ****************************************************************************************
108  // Enregistrement de la nouvelle Feuille en tant que feuille de base
109  _leaf2Pair_.insert(l, leafPairSet);
110 
111  // ****************************************************************************************
112  // Ajout de la feuille aux FusionContext
113 
114  for (SequenceIteratorSafe< FusionContext< false >* > fusIter = _fusionSeq_.beginSafe();
115  fusIter != _fusionSeq_.endSafe();
116  ++fusIter) {
117  // Ajout de la nouvelle pair composée de la feuille de FusIter et de la
118  // nouvelle feuille aux FusionContext suivant
119  for (SetIteratorSafe< LeafPair* > pairIter = bag.beginSafe(); pairIter != bag.endSafe();
120  ++pairIter) {
121  if ((*fusIter)->leaf()->contains((*pairIter)->secondLeaf()->id())) {
122  bag >> *pairIter;
123  continue;
124  }
125 
126  if ((*fusIter)->addPair(*pairIter)) _removeContext_(fusIter.pos() + 1);
127  }
128 
129  if ((*fusIter)->associateLeaf(l)) _removeContext_(fusIter.pos() + 1);
130 
131  bag << (*fusIter)->leafAssociatedPair(l);
132  }
133 
134  _needsUpdate_ = true;
135  }
HashTable< AbstractLeaf *, Set< LeafPair *> *> _leaf2Pair_
Sequence< FusionContext< false > *> _fusionSeq_
void _addInitialPair_(LeafPair *)
+ Here is the call graph for this function:

◆ begin()

void gum::LeafAggregator::begin ( )

◆ hasNext()

bool gum::LeafAggregator::hasNext ( )

◆ leavesMap()

HashTable< NodeId, AbstractLeaf *> gum::LeafAggregator::leavesMap ( )

Definition at line 274 of file leafAggregator.cpp.

References gum::Set< Key, Alloc >::emplace().

274  {
275  HashTable< NodeId, AbstractLeaf* > retMap;
276  for (SequenceIteratorSafe< FusionContext< false >* > fusIter = _fusionSeq_.rbeginSafe();
277  fusIter != _fusionSeq_.rendSafe();
278  --fusIter) {
279  bool alreadyIn = false;
280  for (HashTableIteratorSafe< NodeId, AbstractLeaf* > mapIter = retMap.beginSafe();
281  mapIter != retMap.endSafe();
282  ++mapIter)
283  if (mapIter.val()->contains((*fusIter)->leaf()->id())) {
284  alreadyIn = true;
285  break;
286  }
287  if (!alreadyIn) retMap.insert((*fusIter)->leaf()->id(), (*fusIter)->leaf());
288  }
289 
290  for (HashTableIteratorSafe< AbstractLeaf*, Set< LeafPair* >* > leafIter
291  = _leaf2Pair_.beginSafe();
292  leafIter != _leaf2Pair_.endSafe();
293  ++leafIter) {
294  for (HashTableIteratorSafe< NodeId, AbstractLeaf* > mapIter = retMap.beginSafe();
295  mapIter != retMap.endSafe();
296  ++mapIter)
297  if (mapIter.val()->contains(leafIter.key()->id())) {
298  retMap.insert(leafIter.key()->id(), mapIter.val());
299  break;
300  }
301  if (!retMap.exists(leafIter.key()->id())) retMap.insert(leafIter.key()->id(), leafIter.key());
302  }
303 
304  return retMap;
305  }
HashTable< AbstractLeaf *, Set< LeafPair *> *> _leaf2Pair_
Sequence< FusionContext< false > *> _fusionSeq_
+ Here is the call graph for this function:

◆ needsUpdate()

bool gum::LeafAggregator::needsUpdate ( )
inline

Definition at line 124 of file leafAggregator.h.

References _needsUpdate_.

124 { return _needsUpdate_; }

◆ next()

double gum::LeafAggregator::next ( )

◆ removeLeaf()

void gum::LeafAggregator::removeLeaf ( AbstractLeaf l)

Definition at line 186 of file leafAggregator.cpp.

References gum::Set< Key, Alloc >::emplace().

186  {
187  // ***********************************************************************************
188  // First we update every base pair linked to that leaf
189  Set< LeafPair* > bag(*(_leaf2Pair_[l]));
190  for (SetIteratorSafe< LeafPair* > pairIter = bag.beginSafe(); pairIter != bag.endSafe();
191  ++pairIter) {
192  _removeInitialPair_(*pairIter);
193  (*_leaf2Pair_[(*pairIter)->otherLeaf(l)]) >> *pairIter;
194  }
195 
196  // **********************************************************************************
197  // The we have top update FusionContext pairs associated to that leaf
198  Set< LeafPair* > toBeDeleted;
199  for (SequenceIteratorSafe< FusionContext< false >* > fusIter = _fusionSeq_.beginSafe();
200  fusIter != _fusionSeq_.endSafe();
201  ++fusIter) {
202  for (SetIteratorSafe< LeafPair* > pairIter = bag.beginSafe(); pairIter != bag.endSafe();
203  ++pairIter) {
204  if ((*fusIter)->leaf()->contains((*pairIter)->secondLeaf()->id())
205  || (*fusIter)->leaf()->contains((*pairIter)->firstLeaf()->id())) {
206  bag >> *pairIter;
207  continue;
208  }
209 
210  if ((*fusIter)->removePair(*pairIter)) { _removeContext_(fusIter.pos() + 1); }
211  }
212 
213  bag << (*fusIter)->leafAssociatedPair(l);
214  toBeDeleted << (*fusIter)->leafAssociatedPair(l);
215 
216  if ((*fusIter)->deassociateLeaf(l)) { _removeContext_(fusIter.pos() + 1); }
217  }
218 
219  for (SetIteratorSafe< LeafPair* > pairIter = toBeDeleted.beginSafe();
220  pairIter != toBeDeleted.endSafe();
221  ++pairIter)
222  delete *pairIter;
223 
224  for (SetIteratorSafe< LeafPair* > pairIter = _leaf2Pair_[l]->beginSafe();
225  pairIter != _leaf2Pair_[l]->endSafe();
226  ++pairIter)
227  delete *pairIter;
228  delete _leaf2Pair_[l];
229  _leaf2Pair_.erase(l);
230 
231  _needsUpdate_ = true;
232  }
HashTable< AbstractLeaf *, Set< LeafPair *> *> _leaf2Pair_
Sequence< FusionContext< false > *> _fusionSeq_
void _removeInitialPair_(LeafPair *)
+ Here is the call graph for this function:

◆ toString()

std::string gum::LeafAggregator::toString ( )

Definition at line 308 of file leafAggregator.cpp.

References gum::Set< Key, Alloc >::emplace().

308  {
309  std::stringstream ss;
310  ss << "################\nTas Initial : " << std::endl
311  << _initialContext_->toString() << std::endl;
312 
313  for (auto fusIter = _fusionSeq_.beginSafe(); fusIter != _fusionSeq_.endSafe(); ++fusIter) {
314  ss << "################\nTas " << fusIter.pos() << " : " << std::endl
315  << (*fusIter)->toString();
316  }
317 
318  return ss.str();
319  }
Sequence< FusionContext< false > *> _fusionSeq_
FusionContext< true > * _initialContext_
std::string toString()
+ Here is the call graph for this function:

◆ update()

void gum::LeafAggregator::update ( )

Definition at line 238 of file leafAggregator.cpp.

References gum::Set< Key, Alloc >::emplace().

238  {
239  LeafPair* nextPair = _initialContext_->top();
242  if (!_fusionSeq_.empty()) {
243  nextPair = _fusionSeq_.back()->top();
244  pb = _fusionSeq_.back()->beginPairs();
245  pe = _fusionSeq_.back()->endPairs();
246  }
247 
248 
249  while (nextPair && nextPair->likelyhood() < _similarityThreshold_) {
250  AbstractLeaf* newLeaf = nextPair->convert2Leaf(_leavesCpt_->addNode());
251  FusionContext< false >* newContext = new FusionContext< false >(newLeaf);
252 
253  for (pair_iterator pairIter = pb; pairIter != pe; ++pairIter) {
254  if (!newLeaf->contains(pairIter.key()->firstLeaf()->id())
255  && !newLeaf->contains(pairIter.key()->secondLeaf()->id()))
256  newContext->addPair(pairIter.key());
257  if (!newLeaf->contains(pairIter.key()->firstLeaf()->id())
258  && !newContext->containsAssociatedLeaf(pairIter.key()->firstLeaf()))
259  newContext->associateLeaf(pairIter.key()->firstLeaf());
260  if (!newLeaf->contains(pairIter.key()->secondLeaf()->id())
261  && !newContext->containsAssociatedLeaf(pairIter.key()->secondLeaf()))
262  newContext->associateLeaf(pairIter.key()->secondLeaf());
263  }
264 
265  _fusionSeq_.insert(newContext);
266  nextPair = _fusionSeq_.back()->top();
267  pb = _fusionSeq_.back()->beginPairs();
268  pe = _fusionSeq_.back()->endPairs();
269  }
270  _needsUpdate_ = false;
271  }
HashTableConstIteratorSafe< LeafPair *, std::vector< Size > > pair_iterator
Definition: fusionContext.h:52
pair_iterator endPairs()
Sequence< FusionContext< false > *> _fusionSeq_
virtual NodeId addNode()
insert a new node and return its id
FusionContext< true > * _initialContext_
NodeGraphPart * _leavesCpt_
bool addPair(LeafPair *p)
bool containsAssociatedLeaf(AbstractLeaf *l)
Definition: fusionContext.h:92
LeafPair * top()
bool associateLeaf(AbstractLeaf *l)
pair_iterator beginPairs()
+ Here is the call graph for this function:

◆ updateLeaf()

bool gum::LeafAggregator::updateLeaf ( AbstractLeaf l)

Definition at line 141 of file leafAggregator.cpp.

References gum::Set< Key, Alloc >::emplace().

141  {
142  // ***********************************************************************************
143  // First we update every base pair linked to that leaf
144  Set< LeafPair* > bag(*(_leaf2Pair_[l]));
145  for (SetIteratorSafe< LeafPair* > pairIter = bag.beginSafe(); pairIter != bag.endSafe();
146  ++pairIter) {
147  (*pairIter)->updateLikelyhood();
148  _updateInitialPair_(*pairIter);
149  }
150 
151  // **********************************************************************************
152  // The we have top update FusionContext pairs associated to that leaf
153  AbstractLeaf* curLeaf = l;
154  for (SequenceIteratorSafe< FusionContext< false >* > fusIter = _fusionSeq_.beginSafe();
155  fusIter != _fusionSeq_.endSafe();
156  ++fusIter) {
157  if ((*fusIter)->leaf()->contains(curLeaf->id())) {
158  bag.clear();
159  if ((*fusIter)->updateAllAssociatedLeaves()) _removeContext_(fusIter.pos() + 1);
160  bag = (*fusIter)->associatedPairs();
161  curLeaf = (*fusIter)->leaf();
162  continue;
163  }
164 
165  for (SetIteratorSafe< LeafPair* > pairIter = bag.beginSafe(); pairIter != bag.endSafe();
166  ++pairIter) {
167  if ((*fusIter)->leaf()->contains((*pairIter)->secondLeaf()->id())
168  || (*fusIter)->leaf()->contains((*pairIter)->firstLeaf()->id())) {
169  bag >> *pairIter;
170  continue;
171  }
172 
173  if ((*fusIter)->updatePair(*pairIter)) _removeContext_(fusIter.pos() + 1);
174  }
175  if ((*fusIter)->updateAssociatedLeaf(curLeaf)) _removeContext_(fusIter.pos() + 1);
176  bag << (*fusIter)->leafAssociatedPair(curLeaf);
177  }
178 
179  return _needsUpdate_;
180  }
HashTable< AbstractLeaf *, Set< LeafPair *> *> _leaf2Pair_
Sequence< FusionContext< false > *> _fusionSeq_
void _updateInitialPair_(LeafPair *)
+ Here is the call graph for this function:

Member Data Documentation

◆ _fusionSeq_

Sequence< FusionContext< false >* > gum::LeafAggregator::_fusionSeq_
private

Definition at line 136 of file leafAggregator.h.

◆ _initialContext_

FusionContext< true >* gum::LeafAggregator::_initialContext_
private

Definition at line 138 of file leafAggregator.h.

◆ _leaf2Pair_

HashTable< AbstractLeaf*, Set< LeafPair* >* > gum::LeafAggregator::_leaf2Pair_
private

Definition at line 140 of file leafAggregator.h.

◆ _leavesCpt_

NodeGraphPart* gum::LeafAggregator::_leavesCpt_
private

Definition at line 142 of file leafAggregator.h.

◆ _needsUpdate_

bool gum::LeafAggregator::_needsUpdate_
private

Definition at line 145 of file leafAggregator.h.

Referenced by needsUpdate().

◆ _similarityThreshold_

double gum::LeafAggregator::_similarityThreshold_
private

Definition at line 144 of file leafAggregator.h.


The documentation for this class was generated from the following files: