31 #define ALLOCATE(x) SmallObjectAllocator::instance().allocate(x) 32 #define DEALLOCATE(x, y) SmallObjectAllocator::instance().deallocate(x, y) 36 template <
typename GUM_SCALAR,
38 class COMBINEOPERATOR,
40 class PROJECTOPERATOR,
42 class TerminalNodePolicy >
49 const GUM_SCALAR neutral) :
51 __DG2(DG2), __neutral(neutral), __combine(), __project(),
52 __DG1InstantiationNeeded(DG1->realSize(), true, false),
53 __DG2InstantiationNeeded(DG2->realSize(), true, false) {
57 TerminalNodePolicy >::getReducedAndOrderedInstance();
64 template <
typename GUM_SCALAR,
66 class COMBINEOPERATOR,
68 class PROJECTOPERATOR,
70 class TerminalNodePolicy >
92 template <
typename GUM_SCALAR,
94 class COMBINEOPERATOR,
96 class PROJECTOPERATOR,
98 class TerminalNodePolicy >
106 Idx* varInst =
nullptr;
118 __rd->manager()->setRootNode(root);
130 template <
typename GUM_SCALAR,
131 template <
typename >
132 class COMBINEOPERATOR,
133 template <
typename >
134 class PROJECTOPERATOR,
135 template <
typename >
136 class TerminalNodePolicy >
141 __DG1->variablesSequence().beginSafe();
143 __DG2->variablesSequence().beginSafe();
145 while (fite !=
__DG1->variablesSequence().endSafe()
146 && site !=
__DG2->variablesSequence().endSafe()) {
149 if (
__rd->variablesSequence().exists(*fite)) {
156 if (
__rd->variablesSequence().exists(*site)) {
163 if (!
__DG2->variablesSequence().exists(*fite)
172 if (!
__DG1->variablesSequence().exists(*site)
181 if (*fite == *site) {
198 if (fite ==
__DG1->variablesSequence().endSafe()) {
199 for (; site !=
__DG2->variablesSequence().endSafe(); ++site)
200 if (!
__rd->variablesSequence().exists(*site))
__rd->add(**site);
202 for (; fite !=
__DG1->variablesSequence().endSafe(); ++fite)
203 if (!
__rd->variablesSequence().exists(*fite))
__rd->add(**fite);
218 template <
typename GUM_SCALAR,
219 template <
typename >
220 class COMBINEOPERATOR,
221 template <
typename >
222 class PROJECTOPERATOR,
223 template <
typename >
224 class TerminalNodePolicy >
233 for (
auto varIter = dg->variablesSequence().rbeginSafe();
234 varIter != dg->variablesSequence().rendSafe();
236 Idx varPos =
__rd->variablesSequence().pos(*varIter);
238 const Link< NodeId >* nodeIter = dg->varNodeListe(*varIter)->list();
239 while (nodeIter !=
nullptr) {
240 short int* instantiationNeeded =
241 static_cast< short int*
>(
ALLOCATE(tableSize));
243 short int* varDescendant =
static_cast< short int*
>(
ALLOCATE(tableSize));
244 nodesVarDescendant.
insert(nodeIter->
element(), varDescendant);
246 instantiationNeeded[j] = (
short int)0;
247 varDescendant[j] = (
short int)0;
251 varDescendant[varPos] = (
short int)1;
252 for (
Idx modality = 0; modality < dg->node(nodeIter->
element())->nbSons();
254 if (!dg->isTerminalNode(dg->node(nodeIter->
element())->son(modality))) {
255 short int* sonVarDescendant =
256 nodesVarDescendant[dg->node(nodeIter->
element())->son(modality)];
257 for (
Idx varIdx = 0; varIdx <
__nbVar; varIdx++) {
258 varDescendant[varIdx] += sonVarDescendant[varIdx];
259 if (varDescendant[varIdx] && varIdx < varPos)
260 instantiationNeeded[varIdx] = (
short int)1;
268 for (
auto varIter = dg->variablesSequence().beginSafe();
269 varIter != dg->variablesSequence().endSafe();
271 const Link< NodeId >* nodeIter = dg->varNodeListe(*varIter)->list();
272 while (nodeIter !=
nullptr) {
273 for (
Idx modality = 0; modality < dg->node(nodeIter->
element())->nbSons();
276 if (!dg->isTerminalNode(sonId)) {
277 for (
Idx varIdx = 0; varIdx <
__nbVar; ++varIdx) {
278 if (dgInstNeed[nodeIter->
element()][varIdx]
279 && nodesVarDescendant[sonId][varIdx]) {
280 dgInstNeed[sonId][varIdx] = (
short int)1;
290 it != nodesVarDescendant.
end();
295 nodesVarDescendant.
clear();
316 template <
typename GUM_SCALAR,
317 template <
typename >
318 class COMBINEOPERATOR,
319 template <
typename >
320 class PROJECTOPERATOR,
321 template <
typename >
322 class TerminalNodePolicy >
340 return __rd->manager()->addTerminalNode(newVal);
348 short int* dg1NeededVar =
352 Idx dg1CurrentVarPos =
355 :
__rd->variablesSequence().pos(
357 short int* dg2NeededVar =
361 Idx dg2CurrentVarPos =
364 :
__rd->variablesSequence().pos(
367 short int* instNeeded =
371 instNeeded[i] = dg1NeededVar[i] + dg2NeededVar[i];
374 double curSitKey = currentSituation.
key(instNeeded);
377 DEALLOCATE(instNeeded,
sizeof(
short int) * __nbVar);
385 origDG2 = currentSituation.
DG2Node();
390 Idx leadVarPos =
__rd->variablesSequence().size();
392 SetNodeFunction leadFunction =
nullptr;
394 bool sameVar =
false;
396 if (!
__DG1->isTerminalNode(currentSituation.
DG1Node())) {
397 if (currentSituation.
varModality(dg1CurrentVarPos) != 0) {
402 ->son(currentSituation.
varModality(dg1CurrentVarPos) - 1));
404 newNode =
__compute(currentSituation, lastInstVarPos);
409 DEALLOCATE(instNeeded,
sizeof(
short int) * __nbVar);
415 leadNodeId = currentSituation.
DG1Node();
416 leadVarPos = dg1CurrentVarPos;
420 if (!
__DG2->isTerminalNode(currentSituation.
DG2Node())) {
421 if (currentSituation.
varModality(dg2CurrentVarPos) != 0) {
426 ->son(currentSituation.
varModality(dg2CurrentVarPos) - 1));
428 newNode =
__compute(currentSituation, lastInstVarPos);
433 DEALLOCATE(instNeeded,
sizeof(
short int) * __nbVar);
438 if (leadVarPos == dg2CurrentVarPos) { sameVar =
true; }
440 if (leadVarPos > dg2CurrentVarPos) {
442 leadNodeId = currentSituation.
DG2Node();
443 leadVarPos = dg2CurrentVarPos;
453 for (
Idx varPos = lastInstVarPos + 1; varPos < leadVarPos; ++varPos) {
454 if (instNeeded[varPos]) {
459 for (
Idx modality = 0; modality < curVar->
domainSize(); modality++) {
462 sonsIds[modality] =
__compute(currentSituation, varPos);
465 newNode =
__rd->manager()->addInternalNode(curVar, sonsIds);
472 DEALLOCATE(instNeeded,
sizeof(
short int) * __nbVar);
487 __DG2->nodeValue(
__DG2->node(origDG2)->son(targetModa))));
488 newNode =
__rd->manager()->addTerminalNode(newVal);
490 DEALLOCATE(instNeeded,
sizeof(
short int) * __nbVar);
493 if (
__DG1->isTerminalNode(origDG1)) {
501 __DG2->nodeValue(
__DG2->node(origDG2)->son(targetModa))));
502 newNode =
__rd->manager()->addTerminalNode(newVal);
504 DEALLOCATE(instNeeded,
sizeof(
short int) * __nbVar);
509 &&
__DG2->isTerminalNode(origDG2)) {
516 __DG2->nodeValue(origDG2)));
517 newNode =
__rd->manager()->addTerminalNode(newVal);
519 DEALLOCATE(instNeeded,
sizeof(
short int) * __nbVar);
536 Idx varPos =
__rd->variablesSequence().pos(curVar);
540 for (
Idx modality = 0; modality < curVar->
domainSize(); modality++) {
545 sonsIds[modality] =
__compute(currentSituation, varPos);
548 newNode =
__rd->manager()->addInternalNode(curVar, sonsIds);
555 DEALLOCATE(instNeeded,
sizeof(
short int) * __nbVar);
561 const InternalNode* leaddgNode = leaddg->node(leadNodeId);
567 for (
Idx modality = 0; modality < curVar->
domainSize(); modality++) {
569 (currentSituation.*leadFunction)(leaddgNode->
son(modality));
571 sonsIds[modality] =
__compute(currentSituation, leadVarPos);
574 newNode =
__rd->manager()->addInternalNode(curVar, sonsIds);
581 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.
Headers of the InternalNode class.
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.
gum is the global namespace for all aGrUM entities
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.
Class used to compute the operation between two decision diagrams.
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.