aGrUM  0.16.0
gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy > Class Template Reference

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

#include <agrum/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.

References gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::__default, gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::__nbCall, gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::__nbVar, gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::__rd, gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::__sizeVarRetro, and gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::~MultiDimFunctionGraphOperator().

43  :
44  __DG1(DG1),
45  __DG2(DG2), __function(),
46  __DG1InstantiationNeeded(DG1->realSize(), true, false),
47  __DG2InstantiationNeeded(DG2->realSize(), true, false) {
48  GUM_CONSTRUCTOR(MultiDimFunctionGraphOperator);
49  __rd =
50  MultiDimFunctionGraph< GUM_SCALAR,
51  TerminalNodePolicy >::getReducedAndOrderedInstance();
52  __nbVar = 0;
53  __default = nullptr;
54 
55  __nbCall = 0;
56  __nbVar = 0;
57  __sizeVarRetro = 1;
58  }
MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * __rd
The resulting function graph.
short int * __default
Just a comptuationnal trick.
HashTable< NodeId, short int *> __DG1InstantiationNeeded
Table uses to know if a given node of first function graph has retrograde vrariables.
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.
const FUNCTOR< GUM_SCALAR > __function
The function to be performed on the leaves.
const MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * __DG1
One of the two function graphs used for the operation.
MultiDimFunctionGraphOperator(const MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > *DG1, const MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > *DG2)
Default constructor.
const MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * __DG2
The other one.
+ Here is the call graph for this function:

◆ ~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 66 of file multiDimFunctionGraphOperator_tpl.h.

References gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::__default, gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::__DG1InstantiationNeeded, gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::__DG2InstantiationNeeded, gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::__nbVar, gum::HashTable< Key, Val, Alloc >::beginSafe(), gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::compute(), gum::HashTable< Key, Val, Alloc >::endSafe(), and SOA_DEALLOCATE.

Referenced by gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::MultiDimFunctionGraphOperator().

66  {
67  GUM_DESTRUCTOR(MultiDimFunctionGraphOperator);
68 
69 
70  for (auto instIter = __DG1InstantiationNeeded.beginSafe();
71  instIter != __DG1InstantiationNeeded.endSafe();
72  ++instIter)
73  SOA_DEALLOCATE(instIter.val(), sizeof(short int) * __nbVar);
74 
75  for (auto instIter = __DG2InstantiationNeeded.beginSafe();
76  instIter != __DG2InstantiationNeeded.endSafe();
77  ++instIter)
78  SOA_DEALLOCATE(instIter.val(), sizeof(short int) * __nbVar);
79 
80  if (__nbVar != 0) SOA_DEALLOCATE(__default, sizeof(short int) * __nbVar);
81  }
const iterator_safe & endSafe() noexcept
Returns the safe iterator pointing to the end of the hashtable.
#define SOA_DEALLOCATE(x, y)
short int * __default
Just a comptuationnal trick.
HashTable< NodeId, short int *> __DG1InstantiationNeeded
Table uses to know if a given node of first function graph has retrograde vrariables.
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:
+ Here is the caller 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 346 of file multiDimFunctionGraphOperator_tpl.h.

References gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::__default, gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::__DG1, gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::__DG1InstantiationNeeded, gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::__DG2, gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::__DG2InstantiationNeeded, gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::__explorationTable, gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::__function, gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::__nbCall, gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::__nbVar, gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::__rd, gum::O4DGContext::chgVarModality(), gum::O4DGContext::DG1Node(), gum::O4DGContext::DG2Node(), gum::DiscreteVariable::domainSize(), gum::HashTable< Key, Val, Alloc >::exists(), gum::HashTable< Key, Val, Alloc >::insert(), gum::O4DGContext::key(), gum::InternalNode::nodeVar(), gum::O4DGContext::setDG1Node(), gum::O4DGContext::setDG2Node(), SOA_ALLOCATE, SOA_DEALLOCATE, gum::InternalNode::son(), and gum::O4DGContext::varModality().

Referenced by gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::__findRetrogradeVariables(), and gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::compute().

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

References gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::__findRetrogradeVariables().

Referenced by gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::__establishVarOrder().

226  {
227  Idx posi = d->variablesSequence().pos(from);
228  Idx dist = 1;
229 
230  while (d->variablesSequence().atPos(posi) != to) {
231  dist *= (*(d->variablesSequence().atPos(posi))).domainSize();
232  posi++;
233  }
234 
235  return dist;
236  }
+ Here is the call graph for this function:
+ Here is the caller 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 125 of file multiDimFunctionGraphOperator_tpl.h.

References gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::__default, gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::__DG1, gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::__DG2, gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::__distance(), gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::__nbVar, gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::__nbVarRetro, gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::__rd, gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::__sizeVarRetro, and SOA_ALLOCATE.

Referenced by gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::compute().

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

References gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::__compute(), gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::__nbVar, gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::__rd, gum::HashTable< Key, Val, Alloc >::begin(), gum::HashTable< Key, Val, Alloc >::clear(), gum::Link< T >::element(), gum::HashTable< Key, Val, Alloc >::end(), gum::HashTable< Key, Val, Alloc >::insert(), gum::Link< T >::nextLink(), SOA_ALLOCATE, and SOA_DEALLOCATE.

Referenced by gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::__distance(), and gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::compute().

250  {
251  HashTable< NodeId, short int* > nodesVarDescendant;
252  Size tableSize = Size(__nbVar * sizeof(short int));
253 
254  for (auto varIter = dg->variablesSequence().rbeginSafe();
255  varIter != dg->variablesSequence().rendSafe();
256  --varIter) {
257  Idx varPos = __rd->variablesSequence().pos(*varIter);
258  const Link< NodeId >* nodeIter = dg->varNodeListe(*varIter)->list();
259  while (nodeIter != nullptr) {
260  short int* instantiationNeeded =
261  static_cast< short int* >(SOA_ALLOCATE(tableSize));
262  dgInstNeed.insert(nodeIter->element(), instantiationNeeded);
263 
264  short int* varDescendant =
265  static_cast< short int* >(SOA_ALLOCATE(tableSize));
266  nodesVarDescendant.insert(nodeIter->element(), varDescendant);
267  for (Idx j = 0; j < __nbVar; j++) {
268  instantiationNeeded[j] = (short int)0;
269  varDescendant[j] = (short int)0;
270  }
271 
272  varDescendant[varPos] = (short int)1;
273  for (Idx modality = 0; modality < dg->node(nodeIter->element())->nbSons();
274  ++modality) {
275  if (!dg->isTerminalNode(dg->node(nodeIter->element())->son(modality))) {
276  short int* sonVarDescendant =
277  nodesVarDescendant[dg->node(nodeIter->element())->son(modality)];
278  for (Idx varIdx = 0; varIdx < __nbVar; varIdx++) {
279  varDescendant[varIdx] += sonVarDescendant[varIdx];
280  if (varDescendant[varIdx] && varIdx < varPos)
281  instantiationNeeded[varIdx] = (short int)1;
282  }
283  }
284  }
285  nodeIter = nodeIter->nextLink();
286  }
287  }
288 
289  for (auto varIter = dg->variablesSequence().beginSafe();
290  varIter != dg->variablesSequence().endSafe();
291  ++varIter) {
292  const Link< NodeId >* nodeIter = dg->varNodeListe(*varIter)->list();
293  while (nodeIter != nullptr) {
294  for (Idx modality = 0; modality < dg->node(nodeIter->element())->nbSons();
295  ++modality) {
296  NodeId sonId = dg->node(nodeIter->element())->son(modality);
297  if (!dg->isTerminalNode(sonId)) {
298  for (Idx varIdx = 0; varIdx < __nbVar; ++varIdx) {
299  if (dgInstNeed[nodeIter->element()][varIdx]
300  && nodesVarDescendant[sonId][varIdx]) {
301  dgInstNeed[sonId][varIdx] = (short int)1;
302  }
303  }
304  }
305  }
306  nodeIter = nodeIter->nextLink();
307  }
308  }
309 
310  for (HashTableIterator< NodeId, short int* > it = nodesVarDescendant.begin();
311  it != nodesVarDescendant.end();
312  ++it) {
313  SOA_DEALLOCATE(it.val(), tableSize);
314  }
315  nodesVarDescendant.clear();
316  }
MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * __rd
The resulting function graph.
#define SOA_DEALLOCATE(x, y)
Idx __nbVar
The total number of variable implied in the operation.
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Definition: types.h:48
Size NodeId
Type for node ids.
Definition: graphElements.h:98
#define SOA_ALLOCATE(x)
+ Here is the call graph for this function:
+ Here is the caller 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 93 of file multiDimFunctionGraphOperator_tpl.h.

References gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::__compute(), gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::__DG1, gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::__DG1InstantiationNeeded, gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::__DG2, gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::__DG2InstantiationNeeded, gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::__establishVarOrder(), gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::__findRetrogradeVariables(), gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::__nbVar, gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::__rd, gum::O4DGContext::setDG1Node(), gum::O4DGContext::setDG2Node(), SOA_ALLOCATE, and SOA_DEALLOCATE.

Referenced by gum::MDDOperatorStrategy< GUM_SCALAR >::argmaximize(), and gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::~MultiDimFunctionGraphOperator().

93  {
97 
98  Idx* varInst = nullptr;
99  if (__nbVar != 0) {
100  varInst = static_cast< Idx* >(SOA_ALLOCATE(sizeof(Idx) * __nbVar));
101  for (Idx i = 0; i < __nbVar; i++)
102  varInst[i] = (Idx)0;
103  }
104 
105  O4DGContext conti(varInst, __nbVar);
106  conti.setDG1Node(__DG1->root());
107  conti.setDG2Node(__DG2->root());
108 
109  NodeId root = __compute(conti, (Idx)0 - 1);
110  __rd->manager()->setRootNode(root);
111 
112  if (__nbVar != 0) SOA_DEALLOCATE(varInst, sizeof(Idx) * __nbVar);
113 
114  return __rd;
115  }
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...
MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * __rd
The resulting function graph.
#define SOA_DEALLOCATE(x, y)
HashTable< NodeId, short int *> __DG1InstantiationNeeded
Table uses to know if a given node of first function graph has retrograde vrariables.
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.
const MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * __DG1
One of the two function graphs used for the operation.
void __establishVarOrder()
Computes an order for the final Decision graph that will minimize the number of re exploration...
Size NodeId
Type for node ids.
Definition: graphElements.h:98
NodeId __compute(O4DGContext &currentSituation, Idx lastInstVarPos)
The main recursion function.
const MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * __DG2
The other one.
#define SOA_ALLOCATE(x)
+ Here is the call graph for this function:
+ Here is the caller 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 ( )

◆ 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 572 of file multiDimFunctionGraphOperator_tpl.h.

References gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::__nbVarRetro, and gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::sizeVarRetroDomain().

+ 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 583 of file multiDimFunctionGraphOperator_tpl.h.

References gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::__sizeVarRetro.

Referenced by gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::nbVarRetro().

+ Here is the caller graph for this function:

Member Data Documentation

◆ __default

◆ __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

◆ __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

◆ __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

◆ __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

◆ __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.

Referenced by gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::__compute().

◆ __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.

Referenced by gum::MultiDimFunctionGraphOperator< GUM_SCALAR, FUNCTOR, TerminalNodePolicy >::__compute().

◆ __nbCall

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

◆ __nbVar

◆ __nbVarRetro

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

◆ __rd

◆ __sizeVarRetro

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

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