aGrUM  0.20.3
a C++ library for (probabilistic) graphical models
gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy > Class Template Reference

Class used to perform Function Graph Operations. More...

#include <agrum/tools/multidim/patterns/multiDimFunctionGraphOperator.h>

+ Collaboration diagram for gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >:

Public Member Functions

Idx nbCall ()
 
Idx nbVarRetro ()
 
Idx sizeVarRetroDomain ()
 
Constructors / Destructors
 MultiDimFunctionGraphOperator (const MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > *DG1, const MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > *DG2)
 Default constructor. More...
 
 ~MultiDimFunctionGraphOperator ()
 Default destructor. More...
 
Main Method
MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * compute ()
 Computes and builds the Function Graph that is the result of the operation. More...
 

Detailed Description

template<typename GUM_SCALAR, template< typename > class FUNCTOR, template< typename > class TerminalNodePolicy = ExactTerminalNodePolicy>
class gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >

Class used to perform Function Graph Operations.

Definition at line 55 of file multiDimFunctionGraphOperator.h.

Constructor & Destructor Documentation

◆ MultiDimFunctionGraphOperator()

template<typename GUM_SCALAR , template< typename > class FUNCTOR, template< typename > class TerminalNodePolicy>
gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::MultiDimFunctionGraphOperator ( const MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > *  DG1,
const MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > *  DG2 
)

Default constructor.

Definition at line 41 of file multiDimFunctionGraphOperator_tpl.h.

43  :
44  _DG1_(DG1),
45  _DG2_(DG2), _function_(), _DG1InstantiationNeeded_(DG1->realSize(), true, false),
46  _DG2InstantiationNeeded_(DG2->realSize(), true, false) {
47  GUM_CONSTRUCTOR(MultiDimFunctionGraphOperator);
49  _nbVar_ = 0;
50  _default_ = nullptr;
51 
52  _nbCall_ = 0;
53  _nbVar_ = 0;
54  _sizeVarRetro_ = 1;
55  }
const MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * _DG1_
One of the two function graphs used for the operation.
HashTable< NodeId, short int *> _DG2InstantiationNeeded_
Table uses to know if a given node of second function graph has retrograde vrariables.
const MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * _DG2_
The other one.
short int * _default_
Just a comptuationnal trick.
Idx _nbVar_
The total number of variable implied in the operation.
const FUNCTOR< GUM_SCALAR > _function_
The function to be performed on the leaves.
MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * _rd_
The resulting function graph.
HashTable< NodeId, short int *> _DG1InstantiationNeeded_
Table uses to know if a given node of first function graph has retrograde vrariables.
MultiDimFunctionGraphOperator(const MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > *DG1, const MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > *DG2)
Default constructor.
static MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * getReducedAndOrderedInstance()
Returns a reduced and ordered instance.

◆ ~MultiDimFunctionGraphOperator()

template<typename GUM_SCALAR , template< typename > class FUNCTOR, template< typename > class TerminalNodePolicy>
gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::~MultiDimFunctionGraphOperator ( )

Default destructor.

Definition at line 63 of file multiDimFunctionGraphOperator_tpl.h.

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

63  {
64  GUM_DESTRUCTOR(MultiDimFunctionGraphOperator);
65 
66 
67  for (auto instIter = _DG1InstantiationNeeded_.beginSafe();
68  instIter != _DG1InstantiationNeeded_.endSafe();
69  ++instIter)
70  SOA_DEALLOCATE(instIter.val(), sizeof(short int) * _nbVar_);
71 
72  for (auto instIter = _DG2InstantiationNeeded_.beginSafe();
73  instIter != _DG2InstantiationNeeded_.endSafe();
74  ++instIter)
75  SOA_DEALLOCATE(instIter.val(), sizeof(short int) * _nbVar_);
76 
77  if (_nbVar_ != 0) SOA_DEALLOCATE(_default_, sizeof(short int) * _nbVar_);
78  }
const iterator_safe & endSafe() noexcept
Returns the safe iterator pointing to the end of the hashtable.
HashTable< NodeId, short int *> _DG2InstantiationNeeded_
Table uses to know if a given node of second function graph has retrograde vrariables.
#define SOA_DEALLOCATE(x, y)
short int * _default_
Just a comptuationnal trick.
Idx _nbVar_
The total number of variable implied in the operation.
iterator_safe beginSafe()
Returns the safe iterator pointing to the beginning of the hashtable.
HashTable< NodeId, short int *> _DG1InstantiationNeeded_
Table uses to know if a given node of first function graph has retrograde vrariables.
MultiDimFunctionGraphOperator(const MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > *DG1, const MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > *DG2)
Default constructor.
+ Here is the call graph for this function:

Member Function Documentation

◆ _compute_()

template<typename GUM_SCALAR , template< typename > class FUNCTOR, template< typename > class TerminalNodePolicy>
NodeId gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::_compute_ ( O4DGContext currentSituation,
Idx  lastInstVarPos 
)
private

The main recursion function.

Main recursion function, called every time we move on a node to determine what we have to do.

Definition at line 329 of file multiDimFunctionGraphOperator_tpl.h.

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

331  {
332  _nbCall_ += 1;
333 
334  NodeId newNode = 0;
335 
336 
337  // If both current nodes are terminal,
338  // we only have to compute the resulting value
339  if (_DG1_->isTerminalNode(currentSituation.DG1Node())
340  && _DG2_->isTerminalNode(currentSituation.DG2Node())) {
341  // We have to compute new valueand we insert a new node in diagram with
342  // this value, ...
343  return _rd_->manager()->addTerminalNode(
344  _function_(_DG1_->terminalNodeValue(currentSituation.DG1Node()),
345  _DG2_->terminalNodeValue(currentSituation.DG2Node())));
346  }
347 
348  // If not,
349  // we'll have to do some exploration
350 
351  // First we ensure that we hadn't already visit this pair of node under hte
352  // same circumstances
353 
354  short int* dg1NeededVar = _DG1InstantiationNeeded_.exists(currentSituation.DG1Node())
355  ? _DG1InstantiationNeeded_[currentSituation.DG1Node()]
356  : _default_;
357  Idx dg1CurrentVarPos
358  = _DG1_->isTerminalNode(currentSituation.DG1Node())
359  ? _nbVar_
360  : _rd_->variablesSequence().pos(_DG1_->node(currentSituation.DG1Node())->nodeVar());
361  short int* dg2NeededVar = _DG2InstantiationNeeded_.exists(currentSituation.DG2Node())
362  ? _DG2InstantiationNeeded_[currentSituation.DG2Node()]
363  : _default_;
364  Idx dg2CurrentVarPos
365  = _DG2_->isTerminalNode(currentSituation.DG2Node())
366  ? _nbVar_
367  : _rd_->variablesSequence().pos(_DG2_->node(currentSituation.DG2Node())->nodeVar());
368 
369  short int* instNeeded = static_cast< short int* >(SOA_ALLOCATE(sizeof(short int) * _nbVar_));
370  for (Idx i = 0; i < _nbVar_; i++)
371  instNeeded[i] = dg1NeededVar[i] + dg2NeededVar[i];
372 
373  double curSitKey = currentSituation.key(instNeeded);
374 
375  if (_explorationTable_.exists(curSitKey)) {
376  SOA_DEALLOCATE(instNeeded, sizeof(short int) * _nbVar_);
377  return _explorationTable_[curSitKey];
378  }
379 
380  // ====================================================
381 
382  NodeId origDG1 = currentSituation.DG1Node(), origDG2 = currentSituation.DG2Node();
383 
384  const MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy >* leaddg = nullptr;
385  NodeId leadNodeId = 0;
386  Idx leadVarPos = _rd_->variablesSequence().size();
387  typedef void (O4DGContext::*SetNodeFunction)(const NodeId&);
388  SetNodeFunction leadFunction = nullptr;
389 
390  bool sameVar = false;
391 
392  if (!_DG1_->isTerminalNode(currentSituation.DG1Node())) {
393  if (currentSituation.varModality(dg1CurrentVarPos) != 0) {
394  currentSituation.setDG1Node(_DG1_->node(currentSituation.DG1Node())
395  ->son(currentSituation.varModality(dg1CurrentVarPos) - 1));
396 
397  newNode = _compute_(currentSituation, lastInstVarPos);
398  _explorationTable_.insert(curSitKey, newNode);
399  currentSituation.setDG1Node(origDG1);
400  currentSituation.setDG2Node(origDG2);
401 
402  SOA_DEALLOCATE(instNeeded, sizeof(short int) * _nbVar_);
403 
404  return newNode;
405  }
406 
407  leaddg = _DG1_;
408  leadNodeId = currentSituation.DG1Node();
409  leadVarPos = dg1CurrentVarPos;
410  leadFunction = &O4DGContext::setDG1Node;
411  }
412 
413  if (!_DG2_->isTerminalNode(currentSituation.DG2Node())) {
414  if (currentSituation.varModality(dg2CurrentVarPos) != 0) {
415  currentSituation.setDG2Node(_DG2_->node(currentSituation.DG2Node())
416  ->son(currentSituation.varModality(dg2CurrentVarPos) - 1));
417 
418  newNode = _compute_(currentSituation, lastInstVarPos);
419  _explorationTable_.insert(curSitKey, newNode);
420  currentSituation.setDG1Node(origDG1);
421  currentSituation.setDG2Node(origDG2);
422 
423  SOA_DEALLOCATE(instNeeded, sizeof(short int) * _nbVar_);
424 
425  return newNode;
426  }
427 
428  if (leadVarPos == dg2CurrentVarPos) { sameVar = true; }
429 
430  if (leadVarPos > dg2CurrentVarPos) {
431  leaddg = _DG2_;
432  leadNodeId = currentSituation.DG2Node();
433  leadVarPos = dg2CurrentVarPos;
434  leadFunction = &O4DGContext::setDG2Node;
435  }
436  }
437 
438  // ====================================================
439 
440  // Before exploring nodes, we have to ensure that every anticipated
441  // exploration is done
442  for (Idx varPos = lastInstVarPos + 1; varPos < leadVarPos; ++varPos) {
443  if (instNeeded[varPos]) {
444  const DiscreteVariable* curVar = _rd_->variablesSequence().atPos(varPos);
445  NodeId* sonsIds
446  = static_cast< NodeId* >(SOA_ALLOCATE(sizeof(NodeId) * curVar->domainSize()));
447 
448  for (Idx modality = 0; modality < curVar->domainSize(); modality++) {
449  currentSituation.chgVarModality(varPos, modality + 1);
450 
451  sonsIds[modality] = _compute_(currentSituation, varPos);
452  }
453 
454  newNode = _rd_->manager()->addInternalNode(curVar, sonsIds);
455 
456  _explorationTable_.insert(curSitKey, newNode);
457  currentSituation.chgVarModality(varPos, 0);
458  currentSituation.setDG1Node(origDG1);
459  currentSituation.setDG2Node(origDG2);
460 
461  SOA_DEALLOCATE(instNeeded, sizeof(short int) * _nbVar_);
462 
463  return newNode;
464  }
465  }
466 
467  // ====================================================
468 
469  // If only one of the current node is terminal,
470  // we have to pursue deeper on the other diagram
471  if (sameVar) {
472  // If so - meaning it's the same variable - we have to go
473  // down on both
474  const InternalNode* dg1Node = _DG1_->node(origDG1);
475  const InternalNode* dg2Node = _DG2_->node(origDG2);
476 
477  const DiscreteVariable* curVar = dg1Node->nodeVar();
478  Idx varPos = _rd_->variablesSequence().pos(curVar);
479 
480  NodeId* sonsIds = static_cast< NodeId* >(SOA_ALLOCATE(sizeof(NodeId) * curVar->domainSize()));
481 
482  for (Idx modality = 0; modality < curVar->domainSize(); modality++) {
483  currentSituation.chgVarModality(varPos, modality + 1);
484  currentSituation.setDG1Node(dg1Node->son(modality));
485  currentSituation.setDG2Node(dg2Node->son(modality));
486 
487  sonsIds[modality] = _compute_(currentSituation, varPos);
488  }
489 
490  newNode = _rd_->manager()->addInternalNode(curVar, sonsIds);
491 
492  _explorationTable_.insert(curSitKey, newNode);
493  currentSituation.chgVarModality(varPos, 0);
494  currentSituation.setDG1Node(origDG1);
495  currentSituation.setDG2Node(origDG2);
496 
497  SOA_DEALLOCATE(instNeeded, sizeof(short int) * _nbVar_);
498 
499  return newNode;
500  }
501  // ====================================================
502  else {
503  const InternalNode* leaddgNode = leaddg->node(leadNodeId);
504 
505  const DiscreteVariable* curVar = leaddgNode->nodeVar();
506  NodeId* sonsIds = static_cast< NodeId* >(SOA_ALLOCATE(sizeof(NodeId) * curVar->domainSize()));
507 
508  for (Idx modality = 0; modality < curVar->domainSize(); modality++) {
509  currentSituation.chgVarModality(leadVarPos, modality + 1);
510  (currentSituation.*leadFunction)(leaddgNode->son(modality));
511 
512  sonsIds[modality] = _compute_(currentSituation, leadVarPos);
513  }
514 
515  newNode = _rd_->manager()->addInternalNode(curVar, sonsIds);
516 
517  _explorationTable_.insert(curSitKey, newNode);
518  currentSituation.chgVarModality(leadVarPos, 0);
519  currentSituation.setDG1Node(origDG1);
520  currentSituation.setDG2Node(origDG2);
521 
522  SOA_DEALLOCATE(instNeeded, sizeof(short int) * _nbVar_);
523 
524  return newNode;
525  }
526  }
NodeId _compute_(O4DGContext &currentSituation, Idx lastInstVarPos)
The main recursion function.
const MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * _DG1_
One of the two function graphs used for the operation.
HashTable< NodeId, short int *> _DG2InstantiationNeeded_
Table uses to know if a given node of second function graph has retrograde vrariables.
const MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * _DG2_
The other one.
#define SOA_DEALLOCATE(x, y)
bool exists(const Key &key) const
Checks whether there exists an element with a given key in the hashtable.
HashTable< double, NodeId > _explorationTable_
The hashtable used to know if two pair of nodes have already been visited.
short int * _default_
Just a comptuationnal trick.
void setDG1Node(const NodeId &)
Set DG1 diagram current explored Node.
Idx _nbVar_
The total number of variable implied in the operation.
const FUNCTOR< GUM_SCALAR > _function_
The function to be performed on the leaves.
MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * _rd_
The resulting function graph.
void setDG2Node(const NodeId &)
Set DG2 diagram current explored Node.
HashTable< NodeId, short int *> _DG1InstantiationNeeded_
Table uses to know if a given node of first function graph has retrograde vrariables.
value_type & insert(const Key &key, const Val &val)
Adds a new element (actually a copy of this element) into the hash table.
Size NodeId
Type for node ids.
Definition: graphElements.h:97
#define SOA_ALLOCATE(x)
+ Here is the call graph for this function:

◆ _distance_()

template<typename GUM_SCALAR , template< typename > class FUNCTOR, template< typename > class TerminalNodePolicy>
INLINE Idx gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::_distance_ ( const MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > *  d,
const DiscreteVariable from,
const DiscreteVariable to 
)
private

Heuristic methods to decide which of two retrograde variables should come first.

Definition at line 214 of file multiDimFunctionGraphOperator_tpl.h.

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

217  {
218  Idx posi = d->variablesSequence().pos(from);
219  Idx dist = 1;
220 
221  while (d->variablesSequence().atPos(posi) != to) {
222  dist *= (*(d->variablesSequence().atPos(posi))).domainSize();
223  posi++;
224  }
225 
226  return dist;
227  }
+ Here is the call graph for this function:

◆ _establishVarOrder_()

template<typename GUM_SCALAR , template< typename > class FUNCTOR, template< typename > class TerminalNodePolicy>
void gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::_establishVarOrder_ ( )
private

Computes an order for the final Decision graph that will minimize the number of re exploration.

Definition at line 121 of file multiDimFunctionGraphOperator_tpl.h.

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

121  {
122  SequenceIteratorSafe< const DiscreteVariable* > fite = _DG1_->variablesSequence().beginSafe();
123  SequenceIteratorSafe< const DiscreteVariable* > site = _DG2_->variablesSequence().beginSafe();
124 
125  while (fite != _DG1_->variablesSequence().endSafe()
126  && site != _DG2_->variablesSequence().endSafe()) {
127  // Test : if var from first order is already in final order
128  // we move onto the next one
129  if (_rd_->variablesSequence().exists(*fite)) {
130  ++fite;
131  continue;
132  }
133 
134  // Test : if var from second order is already in final order
135  // we move onto the next one
136  if (_rd_->variablesSequence().exists(*site)) {
137  ++site;
138  continue;
139  }
140 
141  // Test : is current var of the first order present in the second order.
142  // if not we add it to final order
143  if (!_DG2_->variablesSequence().exists(*fite)) {
144  _rd_->add(**fite);
145  ++fite;
146  continue;
147  }
148 
149  // Test : is current var of the second order present in the first order.
150  // if not we add it to final order
151  if (!_DG1_->variablesSequence().exists(*site)) {
152  _rd_->add(**site);
153  ++site;
154  continue;
155  }
156 
157  // Test : is current var of the second order present in the first order.
158  // if not we add it to final order
159  if (*fite == *site) {
160  _rd_->add(**fite);
161  ++fite;
162  ++site;
163  continue;
164  }
165 
166  // Test : the current tested situation is when two retrograde variables
167  // are detected.
168  // Chosen solution here is to find compute domainSize in between
169  // and chose the one with the smallest
170  _nbVarRetro_++;
171  if (_distance_(_DG1_, *fite, *site) < _distance_(_DG2_, *site, *fite)) {
172  _rd_->add(**fite);
173  _sizeVarRetro_ *= (*fite)->domainSize();
174  ++fite;
175  continue;
176  } else {
177  _rd_->add(**site);
178  _sizeVarRetro_ *= (*site)->domainSize();
179  ++site;
180  continue;
181  }
182  }
183 
184  // Whenever an iterator has finished its sequence,
185  // the other may still be in the middle of its one.
186  // Hence, this part ensures that any variables remaining
187  // will be added to the final sequence if needed.
188  if (fite == _DG1_->variablesSequence().endSafe()) {
189  for (; site != _DG2_->variablesSequence().endSafe(); ++site)
190  if (!_rd_->variablesSequence().exists(*site)) _rd_->add(**site);
191  } else {
192  for (; fite != _DG1_->variablesSequence().endSafe(); ++fite)
193  if (!_rd_->variablesSequence().exists(*fite)) _rd_->add(**fite);
194  }
195 
196 
197  // Various initialization needed now that we have a bigger picture
198  _nbVar_ = _rd_->variablesSequence().size();
199 
200  if (_nbVar_ != 0) {
201  _default_ = static_cast< short int* >(SOA_ALLOCATE(sizeof(short int) * _nbVar_));
202  for (Idx i = 0; i < _nbVar_; i++)
203  _default_[i] = (short int)0;
204  }
205  }
const MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * _DG1_
One of the two function graphs used for the operation.
const MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * _DG2_
The other one.
Idx _distance_(const MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > *, const DiscreteVariable *, const DiscreteVariable *)
Heuristic methods to decide which of two retrograde variables should come first.
short int * _default_
Just a comptuationnal trick.
Idx _nbVar_
The total number of variable implied in the operation.
MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * _rd_
The resulting function graph.
#define SOA_ALLOCATE(x)
+ Here is the call graph for this function:

◆ _findRetrogradeVariables_()

template<typename GUM_SCALAR , template< typename > class FUNCTOR, template< typename > class TerminalNodePolicy>
INLINE void gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::_findRetrogradeVariables_ ( const MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > *  dg,
HashTable< NodeId, short int * > &  dgInstNeed 
)
private

Establish for each node in both function graph if it has retrograde variables beneath it.

Definition at line 238 of file multiDimFunctionGraphOperator_tpl.h.

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

239  {
240  HashTable< NodeId, short int* > nodesVarDescendant;
241  Size tableSize = Size(_nbVar_ * sizeof(short int));
242 
243  for (auto varIter = dg->variablesSequence().rbeginSafe();
244  varIter != dg->variablesSequence().rendSafe();
245  --varIter) {
246  Idx varPos = _rd_->variablesSequence().pos(*varIter);
247  const Link< NodeId >* nodeIter = dg->varNodeListe(*varIter)->list();
248  while (nodeIter != nullptr) {
249  short int* instantiationNeeded = static_cast< short int* >(SOA_ALLOCATE(tableSize));
250  dgInstNeed.insert(nodeIter->element(), instantiationNeeded);
251 
252  short int* varDescendant = static_cast< short int* >(SOA_ALLOCATE(tableSize));
253  nodesVarDescendant.insert(nodeIter->element(), varDescendant);
254  for (Idx j = 0; j < _nbVar_; j++) {
255  instantiationNeeded[j] = (short int)0;
256  varDescendant[j] = (short int)0;
257  }
258 
259  varDescendant[varPos] = (short int)1;
260  for (Idx modality = 0; modality < dg->node(nodeIter->element())->nbSons(); ++modality) {
261  if (!dg->isTerminalNode(dg->node(nodeIter->element())->son(modality))) {
262  short int* sonVarDescendant
263  = nodesVarDescendant[dg->node(nodeIter->element())->son(modality)];
264  for (Idx varIdx = 0; varIdx < _nbVar_; varIdx++) {
265  varDescendant[varIdx] += sonVarDescendant[varIdx];
266  if (varDescendant[varIdx] && varIdx < varPos)
267  instantiationNeeded[varIdx] = (short int)1;
268  }
269  }
270  }
271  nodeIter = nodeIter->nextLink();
272  }
273  }
274 
275  for (auto varIter = dg->variablesSequence().beginSafe();
276  varIter != dg->variablesSequence().endSafe();
277  ++varIter) {
278  const Link< NodeId >* nodeIter = dg->varNodeListe(*varIter)->list();
279  while (nodeIter != nullptr) {
280  for (Idx modality = 0; modality < dg->node(nodeIter->element())->nbSons(); ++modality) {
281  NodeId sonId = dg->node(nodeIter->element())->son(modality);
282  if (!dg->isTerminalNode(sonId)) {
283  for (Idx varIdx = 0; varIdx < _nbVar_; ++varIdx) {
284  if (dgInstNeed[nodeIter->element()][varIdx] && nodesVarDescendant[sonId][varIdx]) {
285  dgInstNeed[sonId][varIdx] = (short int)1;
286  }
287  }
288  }
289  }
290  nodeIter = nodeIter->nextLink();
291  }
292  }
293 
294  for (HashTableIterator< NodeId, short int* > it = nodesVarDescendant.begin();
295  it != nodesVarDescendant.end();
296  ++it) {
297  SOA_DEALLOCATE(it.val(), tableSize);
298  }
299  nodesVarDescendant.clear();
300  }
#define SOA_DEALLOCATE(x, y)
Idx _nbVar_
The total number of variable implied in the operation.
MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * _rd_
The resulting function graph.
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Definition: types.h:47
Size NodeId
Type for node ids.
Definition: graphElements.h:97
#define SOA_ALLOCATE(x)
+ Here is the call graph for this function:

◆ compute()

template<typename GUM_SCALAR , template< typename > class FUNCTOR, template< typename > class TerminalNodePolicy>
MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::compute ( )

Computes and builds the Function Graph that is the result of the operation.

Definition at line 89 of file multiDimFunctionGraphOperator_tpl.h.

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

89  {
93 
94  Idx* varInst = nullptr;
95  if (_nbVar_ != 0) {
96  varInst = static_cast< Idx* >(SOA_ALLOCATE(sizeof(Idx) * _nbVar_));
97  for (Idx i = 0; i < _nbVar_; i++)
98  varInst[i] = (Idx)0;
99  }
100 
101  O4DGContext conti(varInst, _nbVar_);
102  conti.setDG1Node(_DG1_->root());
103  conti.setDG2Node(_DG2_->root());
104 
105  NodeId root = _compute_(conti, (Idx)0 - 1);
106  _rd_->manager()->setRootNode(root);
107 
108  if (_nbVar_ != 0) SOA_DEALLOCATE(varInst, sizeof(Idx) * _nbVar_);
109 
110  return _rd_;
111  }
NodeId _compute_(O4DGContext &currentSituation, Idx lastInstVarPos)
The main recursion function.
const MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * _DG1_
One of the two function graphs used for the operation.
HashTable< NodeId, short int *> _DG2InstantiationNeeded_
Table uses to know if a given node of second function graph has retrograde vrariables.
void _findRetrogradeVariables_(const MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > *dg, HashTable< NodeId, short int * > &dgInstNeed)
Establish for each node in both function graph if it has retrograde variables beneath it...
const MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * _DG2_
The other one.
#define SOA_DEALLOCATE(x, y)
void _establishVarOrder_()
Computes an order for the final Decision graph that will minimize the number of re exploration...
Idx _nbVar_
The total number of variable implied in the operation.
MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * _rd_
The resulting function graph.
HashTable< NodeId, short int *> _DG1InstantiationNeeded_
Table uses to know if a given node of first function graph has retrograde vrariables.
Size NodeId
Type for node ids.
Definition: graphElements.h:97
#define SOA_ALLOCATE(x)
+ Here is the call graph for this function:

◆ nbCall()

template<typename GUM_SCALAR , template< typename > class FUNCTOR, template< typename > class TerminalNodePolicy>
INLINE Idx gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::nbCall ( )

Definition at line 533 of file multiDimFunctionGraphOperator_tpl.h.

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

+ Here is the call graph for this function:

◆ nbVarRetro()

template<typename GUM_SCALAR , template< typename > class FUNCTOR, template< typename > class TerminalNodePolicy>
INLINE Idx gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::nbVarRetro ( )

Definition at line 543 of file multiDimFunctionGraphOperator_tpl.h.

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

+ Here is the call graph for this function:

◆ sizeVarRetroDomain()

template<typename GUM_SCALAR , template< typename > class FUNCTOR, template< typename > class TerminalNodePolicy>
INLINE Idx gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::sizeVarRetroDomain ( )

Definition at line 553 of file multiDimFunctionGraphOperator_tpl.h.

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

+ Here is the call graph for this function:

Member Data Documentation

◆ _default_

template<typename GUM_SCALAR , template< typename > class FUNCTOR, template< typename > class TerminalNodePolicy = ExactTerminalNodePolicy>
short int* gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::_default_
private

Just a comptuationnal trick.

Definition at line 144 of file multiDimFunctionGraphOperator.h.

◆ _DG1_

template<typename GUM_SCALAR , template< typename > class FUNCTOR, template< typename > class TerminalNodePolicy = ExactTerminalNodePolicy>
const MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy >* gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::_DG1_
private

One of the two function graphs used for the operation.

Definition at line 117 of file multiDimFunctionGraphOperator.h.

◆ _DG1InstantiationNeeded_

template<typename GUM_SCALAR , template< typename > class FUNCTOR, template< typename > class TerminalNodePolicy = ExactTerminalNodePolicy>
HashTable< NodeId, short int* > gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::_DG1InstantiationNeeded_
private

Table uses to know if a given node of first function graph has retrograde vrariables.

Definition at line 137 of file multiDimFunctionGraphOperator.h.

◆ _DG2_

template<typename GUM_SCALAR , template< typename > class FUNCTOR, template< typename > class TerminalNodePolicy = ExactTerminalNodePolicy>
const MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy >* gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::_DG2_
private

The other one.

Definition at line 120 of file multiDimFunctionGraphOperator.h.

◆ _DG2InstantiationNeeded_

template<typename GUM_SCALAR , template< typename > class FUNCTOR, template< typename > class TerminalNodePolicy = ExactTerminalNodePolicy>
HashTable< NodeId, short int* > gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::_DG2InstantiationNeeded_
private

Table uses to know if a given node of second function graph has retrograde vrariables.

Definition at line 141 of file multiDimFunctionGraphOperator.h.

◆ _explorationTable_

template<typename GUM_SCALAR , template< typename > class FUNCTOR, template< typename > class TerminalNodePolicy = ExactTerminalNodePolicy>
HashTable< double, NodeId > gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::_explorationTable_
private

The hashtable used to know if two pair of nodes have already been visited.

Definition at line 133 of file multiDimFunctionGraphOperator.h.

◆ _function_

template<typename GUM_SCALAR , template< typename > class FUNCTOR, template< typename > class TerminalNodePolicy = ExactTerminalNodePolicy>
const FUNCTOR< GUM_SCALAR > gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::_function_
private

The function to be performed on the leaves.

Definition at line 129 of file multiDimFunctionGraphOperator.h.

◆ _nbCall_

template<typename GUM_SCALAR , template< typename > class FUNCTOR, template< typename > class TerminalNodePolicy = ExactTerminalNodePolicy>
Idx gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::_nbCall_
private

Definition at line 93 of file multiDimFunctionGraphOperator.h.

◆ _nbVar_

template<typename GUM_SCALAR , template< typename > class FUNCTOR, template< typename > class TerminalNodePolicy = ExactTerminalNodePolicy>
Idx gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::_nbVar_
private

The total number of variable implied in the operation.

Definition at line 126 of file multiDimFunctionGraphOperator.h.

◆ _nbVarRetro_

template<typename GUM_SCALAR , template< typename > class FUNCTOR, template< typename > class TerminalNodePolicy = ExactTerminalNodePolicy>
Idx gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::_nbVarRetro_
private

Definition at line 94 of file multiDimFunctionGraphOperator.h.

◆ _rd_

template<typename GUM_SCALAR , template< typename > class FUNCTOR, template< typename > class TerminalNodePolicy = ExactTerminalNodePolicy>
MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy >* gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::_rd_
private

The resulting function graph.

Definition at line 123 of file multiDimFunctionGraphOperator.h.

◆ _sizeVarRetro_

template<typename GUM_SCALAR , template< typename > class FUNCTOR, template< typename > class TerminalNodePolicy = ExactTerminalNodePolicy>
Idx gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::_sizeVarRetro_
private

Definition at line 95 of file multiDimFunctionGraphOperator.h.


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