aGrUM  0.20.2
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 56 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__(),
46  DG1InstantiationNeeded__(DG1->realSize(), true, false),
47  DG2InstantiationNeeded__(DG2->realSize(), true, false) {
48  GUM_CONSTRUCTOR(MultiDimFunctionGraphOperator);
51  nbVar__ = 0;
52  default__ = nullptr;
53 
54  nbCall__ = 0;
55  nbVar__ = 0;
56  sizeVarRetro__ = 1;
57  }
const FUNCTOR< GUM_SCALAR > function__
The function to be performed on the leaves.
HashTable< NodeId, short int *> DG1InstantiationNeeded__
Table uses to know if a given node of first function graph has retrograde vrariables.
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.
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.
HashTable< NodeId, short int *> DG2InstantiationNeeded__
Table uses to know if a given node of second 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 65 of file multiDimFunctionGraphOperator_tpl.h.

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

65  {
66  GUM_DESTRUCTOR(MultiDimFunctionGraphOperator);
67 
68 
69  for (auto instIter = DG1InstantiationNeeded__.beginSafe();
70  instIter != DG1InstantiationNeeded__.endSafe();
71  ++instIter)
72  SOA_DEALLOCATE(instIter.val(), sizeof(short int) * nbVar__);
73 
74  for (auto instIter = DG2InstantiationNeeded__.beginSafe();
75  instIter != DG2InstantiationNeeded__.endSafe();
76  ++instIter)
77  SOA_DEALLOCATE(instIter.val(), sizeof(short int) * nbVar__);
78 
79  if (nbVar__ != 0) SOA_DEALLOCATE(default__, sizeof(short int) * nbVar__);
80  }
const iterator_safe & endSafe() noexcept
Returns the safe iterator pointing to the end of the hashtable.
HashTable< NodeId, short int *> DG1InstantiationNeeded__
Table uses to know if a given node of first 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.
HashTable< NodeId, short int *> DG2InstantiationNeeded__
Table uses to know if a given node of second function graph has retrograde vrariables.
iterator_safe beginSafe()
Returns the safe iterator pointing to the beginning of the hashtable.
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>
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 92 of file multiDimFunctionGraphOperator_tpl.h.

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

92  {
96 
97  Idx* varInst = nullptr;
98  if (nbVar__ != 0) {
99  varInst = static_cast< Idx* >(SOA_ALLOCATE(sizeof(Idx) * nbVar__));
100  for (Idx i = 0; i < nbVar__; i++)
101  varInst[i] = (Idx)0;
102  }
103 
104  O4DGContext conti(varInst, nbVar__);
105  conti.setDG1Node(DG1__->root());
106  conti.setDG2Node(DG2__->root());
107 
108  NodeId root = compute__(conti, (Idx)0 - 1);
109  rd__->manager()->setRootNode(root);
110 
111  if (nbVar__ != 0) SOA_DEALLOCATE(varInst, sizeof(Idx) * nbVar__);
112 
113  return rd__;
114  }
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...
HashTable< NodeId, short int *> DG1InstantiationNeeded__
Table uses to know if a given node of first function graph has retrograde vrariables.
#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.
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.
HashTable< NodeId, short int *> DG2InstantiationNeeded__
Table uses to know if a given node of second function graph has retrograde vrariables.
NodeId compute__(O4DGContext &currentSituation, Idx lastInstVarPos)
The main recursion function.
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>
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 345 of file multiDimFunctionGraphOperator_tpl.h.

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

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

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

225  {
226  Idx posi = d->variablesSequence().pos(from);
227  Idx dist = 1;
228 
229  while (d->variablesSequence().atPos(posi) != to) {
230  dist *= (*(d->variablesSequence().atPos(posi))).domainSize();
231  posi++;
232  }
233 
234  return dist;
235  }
+ 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 124 of file multiDimFunctionGraphOperator_tpl.h.

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

124  {
125  SequenceIteratorSafe< const DiscreteVariable* > fite
126  = DG1__->variablesSequence().beginSafe();
127  SequenceIteratorSafe< const DiscreteVariable* > site
128  = DG2__->variablesSequence().beginSafe();
129 
130  while (fite != DG1__->variablesSequence().endSafe()
131  && site != DG2__->variablesSequence().endSafe()) {
132  // Test : if var from first order is already in final order
133  // we move onto the next one
134  if (rd__->variablesSequence().exists(*fite)) {
135  ++fite;
136  continue;
137  }
138 
139  // Test : if var from second order is already in final order
140  // we move onto the next one
141  if (rd__->variablesSequence().exists(*site)) {
142  ++site;
143  continue;
144  }
145 
146  // Test : is current var of the first order present in the second order.
147  // if not we add it to final order
148  if (!DG2__->variablesSequence().exists(*fite)) {
149  rd__->add(**fite);
150  ++fite;
151  continue;
152  }
153 
154  // Test : is current var of the second order present in the first order.
155  // if not we add it to final order
156  if (!DG1__->variablesSequence().exists(*site)) {
157  rd__->add(**site);
158  ++site;
159  continue;
160  }
161 
162  // Test : is current var of the second order present in the first order.
163  // if not we add it to final order
164  if (*fite == *site) {
165  rd__->add(**fite);
166  ++fite;
167  ++site;
168  continue;
169  }
170 
171  // Test : the current tested situation is when two retrograde variables
172  // are detected.
173  // Chosen solution here is to find compute domainSize in between
174  // and chose the one with the smallest
175  nbVarRetro__++;
176  if (distance__(DG1__, *fite, *site) < distance__(DG2__, *site, *fite)) {
177  rd__->add(**fite);
178  sizeVarRetro__ *= (*fite)->domainSize();
179  ++fite;
180  continue;
181  } else {
182  rd__->add(**site);
183  sizeVarRetro__ *= (*site)->domainSize();
184  ++site;
185  continue;
186  }
187  }
188 
189  // Whenever an iterator has finished its sequence,
190  // the other may still be in the middle of its one.
191  // Hence, this part ensures that any variables remaining
192  // will be added to the final sequence if needed.
193  if (fite == DG1__->variablesSequence().endSafe()) {
194  for (; site != DG2__->variablesSequence().endSafe(); ++site)
195  if (!rd__->variablesSequence().exists(*site)) rd__->add(**site);
196  } else {
197  for (; fite != DG1__->variablesSequence().endSafe(); ++fite)
198  if (!rd__->variablesSequence().exists(*fite)) rd__->add(**fite);
199  }
200 
201 
202  // Various initialization needed now that we have a bigger picture
203  nbVar__ = rd__->variablesSequence().size();
204 
205  if (nbVar__ != 0) {
206  default__
207  = static_cast< short int* >(SOA_ALLOCATE(sizeof(short int) * nbVar__));
208  for (Idx i = 0; i < nbVar__; i++)
209  default__[i] = (short int)0;
210  }
211  }
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.
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.
#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 247 of file multiDimFunctionGraphOperator_tpl.h.

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

249  {
250  HashTable< NodeId, short int* > nodesVarDescendant;
251  Size tableSize = Size(nbVar__ * sizeof(short int));
252 
253  for (auto varIter = dg->variablesSequence().rbeginSafe();
254  varIter != dg->variablesSequence().rendSafe();
255  --varIter) {
256  Idx varPos = rd__->variablesSequence().pos(*varIter);
257  const Link< NodeId >* nodeIter = dg->varNodeListe(*varIter)->list();
258  while (nodeIter != nullptr) {
259  short int* instantiationNeeded
260  = static_cast< short int* >(SOA_ALLOCATE(tableSize));
261  dgInstNeed.insert(nodeIter->element(), instantiationNeeded);
262 
263  short int* varDescendant
264  = static_cast< short int* >(SOA_ALLOCATE(tableSize));
265  nodesVarDescendant.insert(nodeIter->element(), varDescendant);
266  for (Idx j = 0; j < nbVar__; j++) {
267  instantiationNeeded[j] = (short int)0;
268  varDescendant[j] = (short int)0;
269  }
270 
271  varDescendant[varPos] = (short int)1;
272  for (Idx modality = 0; modality < dg->node(nodeIter->element())->nbSons();
273  ++modality) {
274  if (!dg->isTerminalNode(dg->node(nodeIter->element())->son(modality))) {
275  short int* sonVarDescendant
276  = nodesVarDescendant[dg->node(nodeIter->element())->son(modality)];
277  for (Idx varIdx = 0; varIdx < nbVar__; varIdx++) {
278  varDescendant[varIdx] += sonVarDescendant[varIdx];
279  if (varDescendant[varIdx] && varIdx < varPos)
280  instantiationNeeded[varIdx] = (short int)1;
281  }
282  }
283  }
284  nodeIter = nodeIter->nextLink();
285  }
286  }
287 
288  for (auto varIter = dg->variablesSequence().beginSafe();
289  varIter != dg->variablesSequence().endSafe();
290  ++varIter) {
291  const Link< NodeId >* nodeIter = dg->varNodeListe(*varIter)->list();
292  while (nodeIter != nullptr) {
293  for (Idx modality = 0; modality < dg->node(nodeIter->element())->nbSons();
294  ++modality) {
295  NodeId sonId = dg->node(nodeIter->element())->son(modality);
296  if (!dg->isTerminalNode(sonId)) {
297  for (Idx varIdx = 0; varIdx < nbVar__; ++varIdx) {
298  if (dgInstNeed[nodeIter->element()][varIdx]
299  && nodesVarDescendant[sonId][varIdx]) {
300  dgInstNeed[sonId][varIdx] = (short int)1;
301  }
302  }
303  }
304  }
305  nodeIter = nodeIter->nextLink();
306  }
307  }
308 
309  for (HashTableIterator< NodeId, short int* > it = nodesVarDescendant.begin();
310  it != nodesVarDescendant.end();
311  ++it) {
312  SOA_DEALLOCATE(it.val(), tableSize);
313  }
314  nodesVarDescendant.clear();
315  }
#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:

◆ 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 558 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 569 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 580 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 145 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 118 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 138 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 121 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 142 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 134 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 130 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 94 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 127 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 95 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 124 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 96 of file multiDimFunctionGraphOperator.h.


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