aGrUM  0.16.0
multiDimFunctionGraphProjector_tpl.h
Go to the documentation of this file.
1 
34 
35 namespace gum {
36 
37  // CONSTRUCTOR
38  template < typename GUM_SCALAR,
39  template < typename >
40  class FUNCTOR,
41  template < typename >
42  class TerminalNodePolicy >
46  const Set< const DiscreteVariable* >& delVars,
47  const GUM_SCALAR neutral) :
48  __src(src),
49  __delVars(delVars), __function(), __neutral(neutral) {
50  GUM_CONSTRUCTOR(MultiDimFunctionGraphProjector);
52  }
53 
54 
55  // DESTRUCTOR
56  template < typename GUM_SCALAR,
57  template < typename >
58  class FUNCTOR,
59  template < typename >
60  class TerminalNodePolicy >
63  GUM_DESTRUCTOR(MultiDimFunctionGraphProjector);
64  }
65 
66 
67  // This function is the main function. To be call every time an Projection
68  // between the two given Function Graphs is required
69  template < typename GUM_SCALAR,
70  template < typename >
71  class FUNCTOR,
72  template < typename >
73  class TerminalNodePolicy >
77  __rd->copy(*__src);
78 
80  __delVars.beginSafe();
81  varIter != __delVars.endSafe();
82  ++varIter) {
83  const DiscreteVariable* curVar = *varIter;
84 
85  // Tout d'abord, on déplace la variable à projeter en fin de séquence afin
86  // de simplifier la projection
87  if (__rd->variablesSequence().exists(curVar))
88  __rd->manager()->moveTo(curVar, __rd->variablesSequence().size() - 1);
89 
90  // 1er cas spécial : le diagramme est un un simple noeud terminal
91  if (__rd->isTerminalNode(__rd->root())) {
92  GUM_SCALAR newVal = __neutral, oldVal = __rd->nodeValue(__rd->root());
93  for (Idx curVarModality = 0; curVarModality < curVar->domainSize();
94  ++curVarModality)
95  newVal = __function(newVal, oldVal);
96 
97  NodeId newSonId = __rd->manager()->addTerminalNode(newVal);
98  __rd->manager()->setRootNode(newSonId);
99 
100  if (__rd->variablesSequence().exists(curVar)) __rd->erase(*curVar);
101  continue;
102  }
103 
104  // 2ème cas spécial : la racine du diagramme est associée à la variable
105  // projetée
106  if (__rd->node(__rd->root())->nodeVar() == curVar) {
107  const InternalNode* curVarNode = __rd->node(__rd->root());
108  GUM_SCALAR newVal = __neutral;
109  for (Idx curVarModality = 0; curVarModality < curVar->domainSize();
110  ++curVarModality)
111  newVal =
112  __function(newVal, __rd->nodeValue(curVarNode->son(curVarModality)));
113 
114  NodeId newSonId = __rd->manager()->addTerminalNode(newVal);
115 
116  __rd->manager()->eraseNode(__rd->root(), newSonId, false);
117 
118  if (__rd->variablesSequence().exists(curVar)) __rd->erase(*curVar);
119  continue;
120  }
121 
122  // Cas général
123  HashTable< NodeId, NodeId > visitedNode(2 * __rd->realSize(), true, false);
124  std::vector< NodeId > filo;
125  filo.push_back(__rd->root());
126 
127  while (!filo.empty()) {
128  NodeId curNodeId = filo.back();
129  filo.pop_back();
130 
131  const InternalNode* curNode = __rd->node(curNodeId);
132 
133  for (Idx modality = 0; modality < curNode->nodeVar()->domainSize();
134  ++modality) {
135  NodeId oldSonId = curNode->son(modality);
136 
137  if (!visitedNode.exists(oldSonId)) {
138  NodeId newSonId = oldSonId;
139 
140  if (!__rd->isTerminalNode(oldSonId)) {
141  if (__rd->node(oldSonId)->nodeVar() != curVar) {
142  filo.push_back(oldSonId);
143  } else {
144  const InternalNode* curVarNode = __rd->node(oldSonId);
145  GUM_SCALAR newVal = __neutral;
146  for (Idx curVarModality = 0; curVarModality < curVar->domainSize();
147  ++curVarModality)
148  newVal = __function(
149  newVal, __rd->nodeValue(curVarNode->son(curVarModality)));
150 
151  newSonId = __rd->manager()->addTerminalNode(newVal);
152 
153  __rd->manager()->eraseNode(oldSonId, newSonId, false);
154  __rd->manager()->setSon(curNodeId, modality, newSonId);
155  }
156 
157  } else {
158  GUM_SCALAR newVal = __neutral, oldVal = __rd->nodeValue(oldSonId);
159  for (Idx curVarModality = 0; curVarModality < curVar->domainSize();
160  ++curVarModality)
161  newVal = __function(newVal, oldVal);
162 
163  newSonId = __rd->manager()->addTerminalNode(newVal);
164  __rd->manager()->setSon(curNodeId, modality, newSonId);
165  }
166 
167  visitedNode.insert(oldSonId, newSonId);
168 
169  } else {
170  if (__rd->node(curNodeId)->son(modality) != visitedNode[oldSonId])
171  __rd->manager()->setSon(curNodeId, modality, visitedNode[oldSonId]);
172  }
173  }
174  }
175 
176  if (__rd->variablesSequence().exists(curVar)) __rd->erase(*curVar);
177  }
178 
179  return __rd;
180  }
181 
182 } // namespace gum
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * __rd
The resulting function graph.
Safe iterators for the Set classDevelopers may consider using Set<x>::iterator_safe instead of SetIte...
Definition: set.h:811
const DiscreteVariable * nodeVar() const
Returns the node variable.
const MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * __src
One of the two function graphs used for the Projection.
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.
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
const FUNCTOR< GUM_SCALAR > __function
The function to be performed on the leaves.
Representation of a setA Set is a structure that contains arbitrary elements.
Definition: set.h:165
virtual Size domainSize() const =0
MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * project()
Computes and builds the Function Graph that is the result of the Projection.
const GUM_SCALAR __neutral
The function to be performed on the leaves.
Structure used to represent a node internal structure.
Definition: internalNode.h:102
Class implementingting a function graph.
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
const Set< const DiscreteVariable *> & __delVars
The list of variables on which the projection is performed.
Size Idx
Type for indexes.
Definition: types.h:53
MultiDimFunctionGraphProjector(const MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > *src, const Set< const DiscreteVariable * > &delVars, const GUM_SCALAR neutral)
Default constructor.
bool empty() const noexcept
Indicates whether the hash table is empty.
Size NodeId
Type for node ids.
Definition: graphElements.h:98
static MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * getReducedAndOrderedInstance()
Returns a reduced and ordered instance.
Class used to perform Function Graph projections.