aGrUM  0.16.0
regress_tpl.h
Go to the documentation of this file.
1 
33 
34 #define ALLOCATE(x) SmallObjectAllocator::instance().allocate(x)
35 #define DEALLOCATE(x, y) SmallObjectAllocator::instance().deallocate(x, y)
36 
37 namespace gum {
38 
39  template < typename GUM_SCALAR,
40  template < typename >
41  class COMBINEOPERATOR,
42  template < typename >
43  class PROJECTOPERATOR,
44  template < typename >
45  class TerminalNodePolicy >
46  INLINE
50  const Set< const DiscreteVariable* >* primedVars,
51  const DiscreteVariable* targetVar,
52  const GUM_SCALAR neutral) :
53  __DG1(DG1),
54  __DG2(DG2), __neutral(neutral), __combine(), __project(),
55  __DG1InstantiationNeeded(DG1->realSize(), true, false),
56  __DG2InstantiationNeeded(DG2->realSize(), true, false) {
57  GUM_CONSTRUCTOR(Regress);
58  __rd =
59  MultiDimFunctionGraph< GUM_SCALAR,
60  TerminalNodePolicy >::getReducedAndOrderedInstance();
61  __nbVar = 0;
62  __default = nullptr;
63  __primedVars = primedVars;
64  __targetVar = targetVar;
65  }
66 
67  template < typename GUM_SCALAR,
68  template < typename >
69  class COMBINEOPERATOR,
70  template < typename >
71  class PROJECTOPERATOR,
72  template < typename >
73  class TerminalNodePolicy >
74  INLINE
77  GUM_DESTRUCTOR(Regress);
78 
79  for (auto instIter = __DG1InstantiationNeeded.beginSafe();
80  instIter != __DG1InstantiationNeeded.endSafe();
81  ++instIter)
82  DEALLOCATE(instIter.val(), sizeof(short int) * __nbVar);
83 
84  for (auto instIter = __DG2InstantiationNeeded.beginSafe();
85  instIter != __DG2InstantiationNeeded.endSafe();
86  ++instIter)
87  DEALLOCATE(instIter.val(), sizeof(short int) * __nbVar);
88 
89  if (__nbVar != 0) DEALLOCATE(__default, sizeof(short int) * __nbVar);
90  }
91 
92 
93  // This function is the main function. To be call every time an operation
94  // between the two given Function Graphs is required
95  template < typename GUM_SCALAR,
96  template < typename >
97  class COMBINEOPERATOR,
98  template < typename >
99  class PROJECTOPERATOR,
100  template < typename >
101  class TerminalNodePolicy >
108 
109  Idx* varInst = nullptr;
110  if (__nbVar != 0) {
111  varInst = static_cast< Idx* >(ALLOCATE(sizeof(Idx) * __nbVar));
112  for (Idx i = 0; i < __nbVar; i++)
113  varInst[i] = (Idx)0;
114  }
115 
116  O4DGContext conti(varInst, __nbVar);
117  conti.setDG1Node(__DG1->root());
118  conti.setDG2Node(__DG2->root());
119 
120  NodeId root = __compute(conti, (Idx)0 - 1);
121  __rd->manager()->setRootNode(root);
122 
123  if (__nbVar != 0) DEALLOCATE(varInst, sizeof(Idx) * __nbVar);
124 
125  __rd->erase(*__targetVar);
126 
127  return __rd;
128  }
129 
130  // This function computes an efficient order for the final decision diagrams.
131  // Its main criterion to do so is the number of
132  // re-exploration to be done
133  template < typename GUM_SCALAR,
134  template < typename >
135  class COMBINEOPERATOR,
136  template < typename >
137  class PROJECTOPERATOR,
138  template < typename >
139  class TerminalNodePolicy >
140  INLINE void
144  __DG1->variablesSequence().beginSafe();
146  __DG2->variablesSequence().beginSafe();
147 
148  while (fite != __DG1->variablesSequence().endSafe()
149  && site != __DG2->variablesSequence().endSafe()) {
150  // Test : if var from first order is already in final order
151  // we move onto the next one
152  if (__rd->variablesSequence().exists(*fite)) {
153  ++fite;
154  continue;
155  }
156 
157  // Test : if var from second order is already in final order
158  // we move onto the next one
159  if (__rd->variablesSequence().exists(*site)) {
160  ++site;
161  continue;
162  }
163 
164  // Test : is current var of the first order present in the second order.
165  // if not we add it to final order
166  if (!__DG2->variablesSequence().exists(*fite)
167  && !__primedVars->exists(*fite)) {
168  __rd->add(**fite);
169  ++fite;
170  continue;
171  }
172 
173  // Test : is current var of the second order present in the first order.
174  // if not we add it to final order
175  if (!__DG1->variablesSequence().exists(*site)
176  && !__primedVars->exists(*site)) {
177  __rd->add(**site);
178  ++site;
179  continue;
180  }
181 
182  // Test : is current var of the second order present in the first order.
183  // if not we add it to final order
184  if (*fite == *site) {
185  __rd->add(**fite);
186  ++fite;
187  ++site;
188  continue;
189  }
190 
191  // Test : if chosing first order var cost less in terms or re exploration,
192  // we chose it
193  __rd->add(**fite);
194  ++fite;
195  }
196 
197  // Whenever an iterator has finished its sequence,
198  // the other may still be in the middle of its one.
199  // Hence, this part ensures that any variables remaining
200  // will be added to the final sequence if needed.
201  if (fite == __DG1->variablesSequence().endSafe()) {
202  for (; site != __DG2->variablesSequence().endSafe(); ++site)
203  if (!__rd->variablesSequence().exists(*site)) __rd->add(**site);
204  } else {
205  for (; fite != __DG1->variablesSequence().endSafe(); ++fite)
206  if (!__rd->variablesSequence().exists(*fite)) __rd->add(**fite);
207  }
208 
209  // Various initialization needed now that we have a bigger picture
210  __nbVar = __rd->variablesSequence().size();
211 
212  if (__nbVar != 0) {
213  __default = static_cast< short int* >(ALLOCATE(sizeof(short int) * __nbVar));
214  for (Idx i = 0; i < __nbVar; i++)
215  __default[i] = (short int)0;
216  }
217  }
218 
219  // This function computes for every nodes if any retrograde variable is
220  // present below
221  template < typename GUM_SCALAR,
222  template < typename >
223  class COMBINEOPERATOR,
224  template < typename >
225  class PROJECTOPERATOR,
226  template < typename >
227  class TerminalNodePolicy >
228  INLINE void
232  HashTable< NodeId, short int* >& dgInstNeed) {
233  HashTable< NodeId, short int* > nodesVarDescendant;
234  Size tableSize = Size(__nbVar * sizeof(short int));
235 
236  for (auto varIter = dg->variablesSequence().rbeginSafe();
237  varIter != dg->variablesSequence().rendSafe();
238  --varIter) {
239  Idx varPos = __rd->variablesSequence().pos(*varIter);
240 
241  const Link< NodeId >* nodeIter = dg->varNodeListe(*varIter)->list();
242  while (nodeIter != nullptr) {
243  short int* instantiationNeeded =
244  static_cast< short int* >(ALLOCATE(tableSize));
245  dgInstNeed.insert(nodeIter->element(), instantiationNeeded);
246  short int* varDescendant = static_cast< short int* >(ALLOCATE(tableSize));
247  nodesVarDescendant.insert(nodeIter->element(), varDescendant);
248  for (Idx j = 0; j < __nbVar; j++) {
249  instantiationNeeded[j] = (short int)0;
250  varDescendant[j] = (short int)0;
251  }
252 
253 
254  varDescendant[varPos] = (short int)1;
255  for (Idx modality = 0; modality < dg->node(nodeIter->element())->nbSons();
256  ++modality) {
257  if (!dg->isTerminalNode(dg->node(nodeIter->element())->son(modality))) {
258  short int* sonVarDescendant =
259  nodesVarDescendant[dg->node(nodeIter->element())->son(modality)];
260  for (Idx varIdx = 0; varIdx < __nbVar; varIdx++) {
261  varDescendant[varIdx] += sonVarDescendant[varIdx];
262  if (varDescendant[varIdx] && varIdx < varPos)
263  instantiationNeeded[varIdx] = (short int)1;
264  }
265  }
266  }
267  nodeIter = nodeIter->nextLink();
268  }
269  }
270 
271  for (auto varIter = dg->variablesSequence().beginSafe();
272  varIter != dg->variablesSequence().endSafe();
273  ++varIter) {
274  const Link< NodeId >* nodeIter = dg->varNodeListe(*varIter)->list();
275  while (nodeIter != nullptr) {
276  for (Idx modality = 0; modality < dg->node(nodeIter->element())->nbSons();
277  ++modality) {
278  NodeId sonId = dg->node(nodeIter->element())->son(modality);
279  if (!dg->isTerminalNode(sonId)) {
280  for (Idx varIdx = 0; varIdx < __nbVar; ++varIdx) {
281  if (dgInstNeed[nodeIter->element()][varIdx]
282  && nodesVarDescendant[sonId][varIdx]) {
283  dgInstNeed[sonId][varIdx] = (short int)1;
284  }
285  }
286  }
287  }
288  nodeIter = nodeIter->nextLink();
289  }
290  }
291 
292  for (HashTableIterator< NodeId, short int* > it = nodesVarDescendant.begin();
293  it != nodesVarDescendant.end();
294  ++it) {
295  DEALLOCATE(it.val(), tableSize);
296  }
297 
298  nodesVarDescendant.clear();
299  }
300 
301  // A key is used for prunning uneccesary operations since once a node has been
302  // visited in a given context, there's no use to revisit him,
303  // the result will be the same node, so we just have to do an association
304  // context - node.
305  // The context consists in :
306  // _ Leader node we are visiting.
307  // _ Follower node we are visiting.
308  // _ For all retrograde variables, if it has been instanciated
309  // before, current modality instanciated, meaning :
310  // _ 0 means the variable hasn't be instanciated yet,
311  // _ From 1 to domainSize + 1 means that current modality
312  // index of variable is value - 1,
313  // _ domainSize + 2 means variable is on default mode.
314  // A key - node association is made each time we create a node in resulting
315  // diagram.
316  // Since GUM_MULTI_DIM_DECISION_DIAGRAM_RECUR_FUNCTION is a corner step in
317  // algorithm ( meaning each time we explore a node we go trought
318  // this function ), check only have to be at the beginning of that function.
319  template < typename GUM_SCALAR,
320  template < typename >
321  class COMBINEOPERATOR,
322  template < typename >
323  class PROJECTOPERATOR,
324  template < typename >
325  class TerminalNodePolicy >
326  INLINE NodeId
328  __compute(O4DGContext& currentSituation, Idx lastInstVarPos) {
329  NodeId newNode = 0;
330 
331  // If both current nodes are terminal,
332  // we only have to compute the resulting value
333  if (__DG1->isTerminalNode(currentSituation.DG1Node())
334  && __DG2->isTerminalNode(currentSituation.DG2Node())) {
335  // We have to compute new valueand we insert a new node in diagram with
336  // this value, ...
337  GUM_SCALAR newVal = __neutral;
338  GUM_SCALAR tempVal = __combine(__DG1->nodeValue(currentSituation.DG1Node()),
339  __DG2->nodeValue(currentSituation.DG2Node()));
340  for (Idx targetModa = 0; targetModa < __targetVar->domainSize();
341  ++targetModa)
342  newVal = __project(newVal, tempVal);
343  return __rd->manager()->addTerminalNode(newVal);
344  }
345 
346  // If not,
347  // we'll have to do some exploration
348 
349  // First we ensure that we hadn't already visit this pair of node under hte
350  // same circumstances
351  short int* dg1NeededVar =
352  __DG1InstantiationNeeded.exists(currentSituation.DG1Node())
353  ? __DG1InstantiationNeeded[currentSituation.DG1Node()]
354  : __default;
355  Idx dg1CurrentVarPos =
356  __DG1->isTerminalNode(currentSituation.DG1Node())
357  ? __nbVar
358  : __rd->variablesSequence().pos(
359  __DG1->node(currentSituation.DG1Node())->nodeVar());
360  short int* dg2NeededVar =
361  __DG2InstantiationNeeded.exists(currentSituation.DG2Node())
362  ? __DG2InstantiationNeeded[currentSituation.DG2Node()]
363  : __default;
364  Idx dg2CurrentVarPos =
365  __DG2->isTerminalNode(currentSituation.DG2Node())
366  ? __nbVar
367  : __rd->variablesSequence().pos(
368  __DG2->node(currentSituation.DG2Node())->nodeVar());
369 
370  short int* instNeeded =
371  static_cast< short int* >(ALLOCATE(sizeof(short int) * __nbVar));
372 
373  for (Idx i = 0; i < __nbVar; i++) {
374  instNeeded[i] = dg1NeededVar[i] + dg2NeededVar[i];
375  }
376 
377  double curSitKey = currentSituation.key(instNeeded);
378 
379  if (__explorationTable.exists(curSitKey)) {
380  DEALLOCATE(instNeeded, sizeof(short int) * __nbVar);
381 
382  return __explorationTable[curSitKey];
383  }
384 
385  // ====================================================
386 
387  NodeId origDG1 = currentSituation.DG1Node(),
388  origDG2 = currentSituation.DG2Node();
389 
391  nullptr;
392  NodeId leadNodeId = 0;
393  Idx leadVarPos = __rd->variablesSequence().size();
394  typedef void (O4DGContext::*SetNodeFunction)(const NodeId&);
395  SetNodeFunction leadFunction = nullptr;
396 
397  bool sameVar = false;
398 
399  if (!__DG1->isTerminalNode(currentSituation.DG1Node())) {
400  if (currentSituation.varModality(dg1CurrentVarPos) != 0) {
401  // If var associated to current node has already been instanciated, we
402  // have to jump it
403  currentSituation.setDG1Node(
404  __DG1->node(currentSituation.DG1Node())
405  ->son(currentSituation.varModality(dg1CurrentVarPos) - 1));
406 
407  newNode = __compute(currentSituation, lastInstVarPos);
408  __explorationTable.insert(curSitKey, newNode);
409  currentSituation.setDG1Node(origDG1);
410  currentSituation.setDG2Node(origDG2);
411 
412  DEALLOCATE(instNeeded, sizeof(short int) * __nbVar);
413 
414  return newNode;
415  }
416 
417  leaddg = __DG1;
418  leadNodeId = currentSituation.DG1Node();
419  leadVarPos = dg1CurrentVarPos;
420  leadFunction = &O4DGContext::setDG1Node;
421  }
422 
423  if (!__DG2->isTerminalNode(currentSituation.DG2Node())) {
424  if (currentSituation.varModality(dg2CurrentVarPos) != 0) {
425  // If var associated to current node has already been instanciated, we
426  // have to jump it
427  currentSituation.setDG2Node(
428  __DG2->node(currentSituation.DG2Node())
429  ->son(currentSituation.varModality(dg2CurrentVarPos) - 1));
430 
431  newNode = __compute(currentSituation, lastInstVarPos);
432  __explorationTable.insert(curSitKey, newNode);
433  currentSituation.setDG1Node(origDG1);
434  currentSituation.setDG2Node(origDG2);
435 
436  DEALLOCATE(instNeeded, sizeof(short int) * __nbVar);
437 
438  return newNode;
439  }
440 
441  if (leadVarPos == dg2CurrentVarPos) { sameVar = true; }
442 
443  if (leadVarPos > dg2CurrentVarPos) {
444  leaddg = __DG2;
445  leadNodeId = currentSituation.DG2Node();
446  leadVarPos = dg2CurrentVarPos;
447  leadFunction = &O4DGContext::setDG2Node;
448  }
449  }
450 
451  // ====================================================
452  // Anticipated Exploration
453 
454  // Before exploring nodes, we have to ensure that every anticipated
455  // exploration is done
456  for (Idx varPos = lastInstVarPos + 1; varPos < leadVarPos; ++varPos) {
457  if (instNeeded[varPos]) {
458  const DiscreteVariable* curVar = __rd->variablesSequence().atPos(varPos);
459  NodeId* sonsIds =
460  static_cast< NodeId* >(ALLOCATE(sizeof(NodeId) * curVar->domainSize()));
461 
462  for (Idx modality = 0; modality < curVar->domainSize(); modality++) {
463  currentSituation.chgVarModality(varPos, modality + 1);
464 
465  sonsIds[modality] = __compute(currentSituation, varPos);
466  }
467 
468  newNode = __rd->manager()->addInternalNode(curVar, sonsIds);
469 
470  __explorationTable.insert(curSitKey, newNode);
471  currentSituation.chgVarModality(varPos, 0);
472  currentSituation.setDG1Node(origDG1);
473  currentSituation.setDG2Node(origDG2);
474 
475  DEALLOCATE(instNeeded, sizeof(short int) * __nbVar);
476 
477  return newNode;
478  }
479  }
480 
481  // ====================================================
482  // Terminal Exploration
483  if (sameVar && __DG1->node(origDG1)->nodeVar() == __targetVar) {
484  GUM_SCALAR newVal = __neutral;
485  for (Idx targetModa = 0; targetModa < __targetVar->domainSize();
486  ++targetModa)
487  newVal = __project(
488  newVal,
489  __combine(__DG1->nodeValue(__DG1->node(origDG1)->son(targetModa)),
490  __DG2->nodeValue(__DG2->node(origDG2)->son(targetModa))));
491  newNode = __rd->manager()->addTerminalNode(newVal);
492  __explorationTable.insert(curSitKey, newNode);
493  DEALLOCATE(instNeeded, sizeof(short int) * __nbVar);
494  return newNode;
495  }
496  if (__DG1->isTerminalNode(origDG1)) {
497  if (__DG2->node(origDG2)->nodeVar() == __targetVar) {
498  GUM_SCALAR newVal = __neutral;
499  for (Idx targetModa = 0; targetModa < __targetVar->domainSize();
500  ++targetModa)
501  newVal = __project(
502  newVal,
503  __combine(__DG1->nodeValue(origDG1),
504  __DG2->nodeValue(__DG2->node(origDG2)->son(targetModa))));
505  newNode = __rd->manager()->addTerminalNode(newVal);
506  __explorationTable.insert(curSitKey, newNode);
507  DEALLOCATE(instNeeded, sizeof(short int) * __nbVar);
508  return newNode;
509  }
510  } else {
511  if (__DG1->node(origDG1)->nodeVar() == __targetVar
512  && __DG2->isTerminalNode(origDG2)) {
513  GUM_SCALAR newVal = __neutral;
514  for (Idx targetModa = 0; targetModa < __targetVar->domainSize();
515  ++targetModa)
516  newVal = __project(
517  newVal,
518  __combine(__DG1->nodeValue(__DG1->node(origDG1)->son(targetModa)),
519  __DG2->nodeValue(origDG2)));
520  newNode = __rd->manager()->addTerminalNode(newVal);
521  __explorationTable.insert(curSitKey, newNode);
522  DEALLOCATE(instNeeded, sizeof(short int) * __nbVar);
523  return newNode;
524  }
525  }
526 
527  // ====================================================
528  // Normal Exploration
529 
530  // If only one of the current node is terminal,
531  // we have to pursue deeper on the other diagram
532  if (sameVar) {
533  // If so - meaning it's the same variable - we have to go
534  // down on both
535  const InternalNode* dg1Node = __DG1->node(origDG1);
536  const InternalNode* dg2Node = __DG2->node(origDG2);
537 
538  const DiscreteVariable* curVar = dg1Node->nodeVar();
539  Idx varPos = __rd->variablesSequence().pos(curVar);
540  NodeId* sonsIds =
541  static_cast< NodeId* >(ALLOCATE(sizeof(NodeId) * curVar->domainSize()));
542 
543  for (Idx modality = 0; modality < curVar->domainSize(); modality++) {
544  currentSituation.chgVarModality(varPos, modality + 1);
545  currentSituation.setDG1Node(dg1Node->son(modality));
546  currentSituation.setDG2Node(dg2Node->son(modality));
547 
548  sonsIds[modality] = __compute(currentSituation, varPos);
549  }
550 
551  newNode = __rd->manager()->addInternalNode(curVar, sonsIds);
552 
553  __explorationTable.insert(curSitKey, newNode);
554  currentSituation.chgVarModality(varPos, 0);
555  currentSituation.setDG1Node(origDG1);
556  currentSituation.setDG2Node(origDG2);
557 
558  DEALLOCATE(instNeeded, sizeof(short int) * __nbVar);
559 
560  return newNode;
561  }
562  // ====================================================
563  else {
564  const InternalNode* leaddgNode = leaddg->node(leadNodeId);
565 
566  const DiscreteVariable* curVar = leaddgNode->nodeVar();
567  NodeId* sonsIds =
568  static_cast< NodeId* >(ALLOCATE(sizeof(NodeId) * curVar->domainSize()));
569 
570  for (Idx modality = 0; modality < curVar->domainSize(); modality++) {
571  currentSituation.chgVarModality(leadVarPos, modality + 1);
572  (currentSituation.*leadFunction)(leaddgNode->son(modality));
573 
574  sonsIds[modality] = __compute(currentSituation, leadVarPos);
575  }
576 
577  newNode = __rd->manager()->addInternalNode(curVar, sonsIds);
578 
579  __explorationTable.insert(curSitKey, newNode);
580  currentSituation.chgVarModality(leadVarPos, 0);
581  currentSituation.setDG1Node(origDG1);
582  currentSituation.setDG2Node(origDG2);
583 
584  DEALLOCATE(instNeeded, sizeof(short int) * __nbVar);
585 
586  return newNode;
587  }
588  }
589 
590 } // namespace gum
iterator begin()
Returns an unsafe iterator pointing to the beginning of the hashtable.
const NodeId & DG2Node() const
Get DG2 diagram current explored Node.
Definition: o4DGContext.h:92
const PROJECTOPERATOR< GUM_SCALAR > __project
Definition: regress.h:124
Safe iterators for Sequence.
Definition: sequence.h:1206
MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * __rd
The resulting function graph.
Definition: regress.h:108
const iterator & end() noexcept
Returns the unsafe iterator pointing to the end of the hashtable.
HashTable< NodeId, short int *> __DG2InstantiationNeeded
Definition: regress.h:133
const iterator_safe & endSafe() noexcept
Returns the safe iterator pointing to the end of the hashtable.
const DiscreteVariable * nodeVar() const
Returns the node variable.
const DiscreteVariable * __targetVar
The variable we work on to eleminate.
Definition: regress.h:114
Unsafe Iterators for hashtablesHashTableIterator provides a fast but unsafe way to parse HashTables...
Definition: hashTable.h:2750
const GUM_SCALAR __neutral
The function to be performed on the leaves.
Definition: regress.h:117
MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * compute()
Computes and builds the Function Graph that is the result of the operation.
Definition: regress_tpl.h:104
NodeId son(Idx modality) const
Returns the son at a given index.
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
bool exists(const Key &key) const
Checks whether there exists an element with a given key in the hashtable.
const COMBINEOPERATOR< GUM_SCALAR > __combine
The functions to be performed on the leaves.
Definition: regress.h:123
const double & key(short int *instNeeded)
Returns o4DGContext key.
void chgVarModality(Idx, Idx)
Changes given variable modality.
HashTable< NodeId, short int *> __DG1InstantiationNeeded
Table uses to know if a given node of given function graph has retrograde variables.
Definition: regress.h:132
Base class for discrete random variable.
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
Definition: agrum.h:25
#define ALLOCATE(x)
Definition: regress_tpl.h:34
const MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * __DG2
The other one.
Definition: regress.h:105
Representation of a setA Set is a structure that contains arbitrary elements.
Definition: set.h:165
Regress(const MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > *vfunction, const MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > *probDist, const Set< const DiscreteVariable * > *primedVars, const DiscreteVariable *targetVar, const GUM_SCALAR neutral)
Default constructor.
Definition: regress_tpl.h:48
virtual Size domainSize() const =0
const NodeId & DG1Node() const
Get DG1 diagram current explored Node.
Definition: o4DGContext.h:86
#define DEALLOCATE(x, y)
Definition: regress_tpl.h:35
void setDG1Node(const NodeId &)
Set DG1 diagram current explored Node.
Structure used to represent a node internal structure.
Definition: internalNode.h:102
void __establishVarOrder()
Computes an order for the final Decision graph that will minimize the number of re exploration...
Definition: regress_tpl.h:142
Class implementingting a function graph.
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...
Definition: regress_tpl.h:230
NodeId __compute(O4DGContext &currentSituation, Idx lastInstVarPos)
The main recursion function.
Definition: regress_tpl.h:328
Idx __nbVar
The total number of variable implied in the operation.
Definition: regress.h:120
Class used to perform Function Graph Operations in the FMDP Framework.
Definition: regress.h:54
void setDG2Node(const NodeId &)
Set DG2 diagram current explored Node.
const Set< const DiscreteVariable *> * __primedVars
The set of variables we want to keep at the end.
Definition: regress.h:111
void clear()
Removes all the elements in the hash table.
iterator_safe beginSafe()
Returns the safe iterator pointing to the beginning of the hashtable.
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
HashTable< double, NodeId > __explorationTable
The hashtable used to know if two pair of nodes have already been visited.
Definition: regress.h:128
Size Idx
Type for indexes.
Definition: types.h:53
short int * __default
Just a computationnal trick.
Definition: regress.h:136
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Definition: types.h:48
Class used to manipulate context during Function Graph Operations.
Definition: o4DGContext.h:49
value_type & insert(const Key &key, const Val &val)
Adds a new element (actually a copy of this element) into the hash table.
const MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * __DG1
One of the two function graphs used for the operation.
Definition: regress.h:102
Size NodeId
Type for node ids.
Definition: graphElements.h:98
~Regress()
Default destructor.
Definition: regress_tpl.h:76
Idx varModality(Idx)
Changes given variable modality.