aGrUM  0.14.2
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 53 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 38 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().

40  :
41  __DG1(DG1),
42  __DG2(DG2), __function(),
43  __DG1InstantiationNeeded(DG1->realSize(), true, false),
44  __DG2InstantiationNeeded(DG2->realSize(), true, false) {
45  GUM_CONSTRUCTOR(MultiDimFunctionGraphOperator);
46  __rd =
47  MultiDimFunctionGraph< GUM_SCALAR,
48  TerminalNodePolicy >::getReducedAndOrderedInstance();
49  __nbVar = 0;
50  __default = nullptr;
51 
52  __nbCall = 0;
53  __nbVar = 0;
54  __sizeVarRetro = 1;
55  }
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 63 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().

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.
#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 343 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().

343  {
344  __nbCall += 1;
345 
346  NodeId newNode = 0;
347 
348 
349  // If both current nodes are terminal,
350  // we only have to compute the resulting value
351  if (__DG1->isTerminalNode(currentSituation.DG1Node())
352  && __DG2->isTerminalNode(currentSituation.DG2Node())) {
353  // We have to compute new valueand we insert a new node in diagram with
354  // this value, ...
355  return __rd->manager()->addTerminalNode(
356  __function(__DG1->terminalNodeValue(currentSituation.DG1Node()),
357  __DG2->terminalNodeValue(currentSituation.DG2Node())));
358  }
359 
360  // If not,
361  // we'll have to do some exploration
362 
363  // First we ensure that we hadn't already visit this pair of node under hte
364  // same circumstances
365 
366  short int* dg1NeededVar =
367  __DG1InstantiationNeeded.exists(currentSituation.DG1Node())
368  ? __DG1InstantiationNeeded[currentSituation.DG1Node()]
369  : __default;
370  Idx dg1CurrentVarPos =
371  __DG1->isTerminalNode(currentSituation.DG1Node())
372  ? __nbVar
373  : __rd->variablesSequence().pos(
374  __DG1->node(currentSituation.DG1Node())->nodeVar());
375  short int* dg2NeededVar =
376  __DG2InstantiationNeeded.exists(currentSituation.DG2Node())
377  ? __DG2InstantiationNeeded[currentSituation.DG2Node()]
378  : __default;
379  Idx dg2CurrentVarPos =
380  __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  }
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:97
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 220 of file multiDimFunctionGraphOperator_tpl.h.

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

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

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

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

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

90  {
94 
95  Idx* varInst = nullptr;
96  if (__nbVar != 0) {
97  varInst = static_cast< Idx* >(SOA_ALLOCATE(sizeof(Idx) * __nbVar));
98  for (Idx i = 0; i < __nbVar; i++)
99  varInst[i] = (Idx)0;
100  }
101 
102  O4DGContext conti(varInst, __nbVar);
103  conti.setDG1Node(__DG1->root());
104  conti.setDG2Node(__DG2->root());
105 
106  NodeId root = __compute(conti, (Idx)0 - 1);
107  __rd->manager()->setRootNode(root);
108 
109  if (__nbVar != 0) SOA_DEALLOCATE(varInst, sizeof(Idx) * __nbVar);
110 
111  return __rd;
112  }
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:97
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 569 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 580 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 131 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 127 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: