34 #define ALLOCATE(x) SmallObjectAllocator::instance().allocate(x) 35 #define DEALLOCATE(x, y) SmallObjectAllocator::instance().deallocate(x, y) 39 template <
typename GUM_SCALAR,
41 class COMBINEOPERATOR,
43 class PROJECTOPERATOR,
45 class TerminalNodePolicy >
52 const GUM_SCALAR neutral) :
54 __DG2(DG2), __neutral(neutral), __combine(), __project(),
55 __DG1InstantiationNeeded(DG1->realSize(), true, false),
56 __DG2InstantiationNeeded(DG2->realSize(), true, false) {
60 TerminalNodePolicy >::getReducedAndOrderedInstance();
67 template <
typename GUM_SCALAR,
69 class COMBINEOPERATOR,
71 class PROJECTOPERATOR,
73 class TerminalNodePolicy >
95 template <
typename GUM_SCALAR,
97 class COMBINEOPERATOR,
99 class PROJECTOPERATOR,
100 template <
typename >
101 class TerminalNodePolicy >
109 Idx* varInst =
nullptr;
121 __rd->manager()->setRootNode(root);
133 template <
typename GUM_SCALAR,
134 template <
typename >
135 class COMBINEOPERATOR,
136 template <
typename >
137 class PROJECTOPERATOR,
138 template <
typename >
139 class TerminalNodePolicy >
144 __DG1->variablesSequence().beginSafe();
146 __DG2->variablesSequence().beginSafe();
148 while (fite !=
__DG1->variablesSequence().endSafe()
149 && site !=
__DG2->variablesSequence().endSafe()) {
152 if (
__rd->variablesSequence().exists(*fite)) {
159 if (
__rd->variablesSequence().exists(*site)) {
166 if (!
__DG2->variablesSequence().exists(*fite)
175 if (!
__DG1->variablesSequence().exists(*site)
184 if (*fite == *site) {
201 if (fite ==
__DG1->variablesSequence().endSafe()) {
202 for (; site !=
__DG2->variablesSequence().endSafe(); ++site)
203 if (!
__rd->variablesSequence().exists(*site))
__rd->add(**site);
205 for (; fite !=
__DG1->variablesSequence().endSafe(); ++fite)
206 if (!
__rd->variablesSequence().exists(*fite))
__rd->add(**fite);
221 template <
typename GUM_SCALAR,
222 template <
typename >
223 class COMBINEOPERATOR,
224 template <
typename >
225 class PROJECTOPERATOR,
226 template <
typename >
227 class TerminalNodePolicy >
236 for (
auto varIter = dg->variablesSequence().rbeginSafe();
237 varIter != dg->variablesSequence().rendSafe();
239 Idx varPos =
__rd->variablesSequence().pos(*varIter);
241 const Link< NodeId >* nodeIter = dg->varNodeListe(*varIter)->list();
242 while (nodeIter !=
nullptr) {
243 short int* instantiationNeeded =
244 static_cast< short int*
>(
ALLOCATE(tableSize));
246 short int* varDescendant =
static_cast< short int*
>(
ALLOCATE(tableSize));
247 nodesVarDescendant.
insert(nodeIter->
element(), varDescendant);
249 instantiationNeeded[j] = (
short int)0;
250 varDescendant[j] = (
short int)0;
254 varDescendant[varPos] = (
short int)1;
255 for (
Idx modality = 0; modality < dg->node(nodeIter->
element())->nbSons();
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;
271 for (
auto varIter = dg->variablesSequence().beginSafe();
272 varIter != dg->variablesSequence().endSafe();
274 const Link< NodeId >* nodeIter = dg->varNodeListe(*varIter)->list();
275 while (nodeIter !=
nullptr) {
276 for (
Idx modality = 0; modality < dg->node(nodeIter->
element())->nbSons();
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;
293 it != nodesVarDescendant.
end();
298 nodesVarDescendant.
clear();
319 template <
typename GUM_SCALAR,
320 template <
typename >
321 class COMBINEOPERATOR,
322 template <
typename >
323 class PROJECTOPERATOR,
324 template <
typename >
325 class TerminalNodePolicy >
343 return __rd->manager()->addTerminalNode(newVal);
351 short int* dg1NeededVar =
355 Idx dg1CurrentVarPos =
358 :
__rd->variablesSequence().pos(
360 short int* dg2NeededVar =
364 Idx dg2CurrentVarPos =
367 :
__rd->variablesSequence().pos(
370 short int* instNeeded =
374 instNeeded[i] = dg1NeededVar[i] + dg2NeededVar[i];
377 double curSitKey = currentSituation.
key(instNeeded);
380 DEALLOCATE(instNeeded,
sizeof(
short int) * __nbVar);
388 origDG2 = currentSituation.
DG2Node();
393 Idx leadVarPos =
__rd->variablesSequence().size();
395 SetNodeFunction leadFunction =
nullptr;
397 bool sameVar =
false;
399 if (!
__DG1->isTerminalNode(currentSituation.
DG1Node())) {
400 if (currentSituation.
varModality(dg1CurrentVarPos) != 0) {
405 ->son(currentSituation.
varModality(dg1CurrentVarPos) - 1));
407 newNode =
__compute(currentSituation, lastInstVarPos);
412 DEALLOCATE(instNeeded,
sizeof(
short int) * __nbVar);
418 leadNodeId = currentSituation.
DG1Node();
419 leadVarPos = dg1CurrentVarPos;
423 if (!
__DG2->isTerminalNode(currentSituation.
DG2Node())) {
424 if (currentSituation.
varModality(dg2CurrentVarPos) != 0) {
429 ->son(currentSituation.
varModality(dg2CurrentVarPos) - 1));
431 newNode =
__compute(currentSituation, lastInstVarPos);
436 DEALLOCATE(instNeeded,
sizeof(
short int) * __nbVar);
441 if (leadVarPos == dg2CurrentVarPos) { sameVar =
true; }
443 if (leadVarPos > dg2CurrentVarPos) {
445 leadNodeId = currentSituation.
DG2Node();
446 leadVarPos = dg2CurrentVarPos;
456 for (
Idx varPos = lastInstVarPos + 1; varPos < leadVarPos; ++varPos) {
457 if (instNeeded[varPos]) {
462 for (
Idx modality = 0; modality < curVar->
domainSize(); modality++) {
465 sonsIds[modality] =
__compute(currentSituation, varPos);
468 newNode =
__rd->manager()->addInternalNode(curVar, sonsIds);
475 DEALLOCATE(instNeeded,
sizeof(
short int) * __nbVar);
490 __DG2->nodeValue(
__DG2->node(origDG2)->son(targetModa))));
491 newNode =
__rd->manager()->addTerminalNode(newVal);
493 DEALLOCATE(instNeeded,
sizeof(
short int) * __nbVar);
496 if (
__DG1->isTerminalNode(origDG1)) {
504 __DG2->nodeValue(
__DG2->node(origDG2)->son(targetModa))));
505 newNode =
__rd->manager()->addTerminalNode(newVal);
507 DEALLOCATE(instNeeded,
sizeof(
short int) * __nbVar);
512 &&
__DG2->isTerminalNode(origDG2)) {
519 __DG2->nodeValue(origDG2)));
520 newNode =
__rd->manager()->addTerminalNode(newVal);
522 DEALLOCATE(instNeeded,
sizeof(
short int) * __nbVar);
539 Idx varPos =
__rd->variablesSequence().pos(curVar);
543 for (
Idx modality = 0; modality < curVar->
domainSize(); modality++) {
548 sonsIds[modality] =
__compute(currentSituation, varPos);
551 newNode =
__rd->manager()->addInternalNode(curVar, sonsIds);
558 DEALLOCATE(instNeeded,
sizeof(
short int) * __nbVar);
564 const InternalNode* leaddgNode = leaddg->node(leadNodeId);
570 for (
Idx modality = 0; modality < curVar->
domainSize(); modality++) {
572 (currentSituation.*leadFunction)(leaddgNode->
son(modality));
574 sonsIds[modality] =
__compute(currentSituation, leadVarPos);
577 newNode =
__rd->manager()->addInternalNode(curVar, sonsIds);
584 DEALLOCATE(instNeeded,
sizeof(
short int) * __nbVar);
iterator begin()
Returns an unsafe iterator pointing to the beginning of the hashtable.
const NodeId & DG2Node() const
Get DG2 diagram current explored Node.
const PROJECTOPERATOR< GUM_SCALAR > __project
Safe iterators for Sequence.
MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * __rd
The resulting function graph.
const iterator & end() noexcept
Returns the unsafe iterator pointing to the end of the hashtable.
HashTable< NodeId, short int *> __DG2InstantiationNeeded
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.
Unsafe Iterators for hashtablesHashTableIterator provides a fast but unsafe way to parse HashTables...
const GUM_SCALAR __neutral
The function to be performed on the leaves.
MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * compute()
Computes and builds the Function Graph that is the result of the operation.
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.
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.
Base class for discrete random variable.
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
const MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * __DG2
The other one.
Representation of a setA Set is a structure that contains arbitrary elements.
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.
const T & element() const
Returns the element stored in this link.
virtual Size domainSize() const =0
const NodeId & DG1Node() const
Get DG1 diagram current explored Node.
void setDG1Node(const NodeId &)
Set DG1 diagram current explored Node.
Structure used to represent a node internal structure.
Link of a chain list allocated using the SmallObjectAllocator.
void __establishVarOrder()
Computes an order for the final Decision graph that will minimize the number of re exploration...
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...
NodeId __compute(O4DGContext ¤tSituation, Idx lastInstVarPos)
The main recursion function.
Idx __nbVar
The total number of variable implied in the operation.
Class used to perform Function Graph Operations in the FMDP Framework.
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.
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.
Size Idx
Type for indexes.
short int * __default
Just a computationnal trick.
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Class used to manipulate context during Function Graph Operations.
value_type & insert(const Key &key, const Val &val)
Adds a new element (actually a copy of this element) into the hash table.
const Link< T > * nextLink() const
Returns next link.
const MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * __DG1
One of the two function graphs used for the operation.
Size NodeId
Type for node ids.
~Regress()
Default destructor.
Idx varModality(Idx)
Changes given variable modality.