35 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
39 __name(
"MultiDimFunctionGraph"), __tableName(
"NO NAME"), __model(500, true),
40 __manager(nullptr), __root(0), __internalNodeMap(500, true, false),
41 __var2NodeIdMap(500, true, false), __isReduced(isReduced) {
49 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
54 __name(
"MultiDimFunctionGraph"), __tableName(
"No NAME"), __model(500, true),
55 __manager(nullptr), __root(0), __internalNodeMap(500, true, false),
56 __var2NodeIdMap(500, true, false), __isReduced(from.isReducedAndOrdered()) {
62 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
71 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
73 TerminalNodePolicy >::~MultiDimFunctionGraph() {
76 if (__manager !=
nullptr)
delete __manager;
80 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
88 TerminalNodePolicy >::getTreeInstance();
91 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
92 INLINE
const std::string&
97 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
101 "Function Graph can't be edited so " 102 "easily.\nMultiDimFunctionGraphManager " 103 "provides the framework to edit a " 107 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
109 const GUM_SCALAR& d)
const {
111 "Function Graph can't be edited so " 112 "easily.\nMultiDimFunctionGraphManager " 113 "provides the framework to edit a " 117 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
119 const std::vector< GUM_SCALAR >& v)
const {
121 "Function Graph can't be edited so " 122 "easily.\nMultiDimFunctionGraphManager " 123 "provides the framework to editaa " 126 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
128 std::initializer_list< GUM_SCALAR > l)
const {
130 "Function Graph can't be edited so " 131 "easily.\nMultiDimFunctionGraphManager " 132 "provides the framework to edit a " 136 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
139 if (!this->variablesSequence().exists(&v))
142 if (!this->__var2NodeIdMap.exists(&v))
146 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
149 if (this->__var2NodeIdMap.exists(&v)) {
150 while (__var2NodeIdMap[&v]->list() !=
nullptr) {
151 manager()->eraseNode(__var2NodeIdMap[&v]->list()->element());
153 delete __var2NodeIdMap[&v];
154 __var2NodeIdMap.
erase(&v);
157 if (this->variablesSequence().exists(&v))
161 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
164 return __internalNodeMap.size();
168 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
176 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
181 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
186 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
191 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
196 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
200 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
201 INLINE
const std::string
204 std::stringstream sBuff;
205 sBuff << (*i) <<
" = " << this->
get(*i);
209 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
213 "You cannot copy another type of multiDim " 214 "into a MultiDimFunctionGraph.");
217 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
221 "You cannot copy another type of multiDim " 222 "into a MultiDimFunctionGraph.");
225 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
228 if (this->__isReduced != src.isReducedAndOrdered())
230 "Cannot copy a Reduced and Ordered " 231 "function graph into Tree function graph " 238 src.variablesSequence().beginSafe();
239 varIter != src.variablesSequence().endSafe();
241 this->add(**varIter);
243 std::vector< NodeId > lifo;
246 if (src.isTerminalNode(src.root()))
247 this->manager()->setRootNode(
248 this->manager()->addTerminalNode(src.nodeValue(src.root())));
250 this->manager()->setRootNode(
251 this->manager()->addInternalNode(src.node(src.root())->nodeVar()));
252 src2dest.
insert(src.root(), this->root());
253 lifo.push_back(src.root());
257 while (!lifo.empty()) {
258 NodeId currentSrcNodeId = lifo.back();
261 const InternalNode* currentSrcNode = src.node(currentSrcNodeId);
263 for (
Idx index = 0; index < currentSrcNode->
nbSons(); ++index) {
265 NodeId srcSonNodeId = currentSrcNode->
son(index), destSonNodeId = 0;
266 if (src.isTerminalNode(srcSonNodeId)) {
268 this->manager()->addTerminalNode(src.nodeValue(srcSonNodeId));
271 this->manager()->addInternalNode(src.node(srcSonNodeId)->nodeVar());
272 lifo.push_back(srcSonNodeId);
274 src2dest.
insert(srcSonNodeId, destSonNodeId);
276 this->manager()->setSon(src2dest.
second(currentSrcNodeId),
278 src2dest.
second(currentSrcNode->
son(index)));
286 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
292 if (this->__isReduced != src.isReducedAndOrdered())
294 "Cannot copy a Reduced and Ordered " 295 "function graph into Tree function graph " 302 src.variablesSequence().beginSafe();
303 varIter != src.variablesSequence().endSafe();
305 if ((*varIter)->domainSize() != reassign.
second(*varIter)->domainSize())
307 "Var " << (*varIter)->name() <<
" and var " 308 << reassign.
second(*varIter)->name()
309 <<
" have different domain sizes (" 310 << (*varIter)->domainSize()
311 <<
"!=" << reassign.
second(*varIter)->domainSize() <<
")")
312 this->add(*(reassign.
second(*varIter)));
315 std::vector< NodeId > lifo;
318 if (src.isTerminalNode(src.root())) {
319 this->manager()->setRootNode(
320 this->manager()->addTerminalNode(src.nodeValue(src.root())));
322 this->manager()->setRootNode(this->manager()->addInternalNode(
323 reassign.
second(src.node(src.root())->nodeVar())));
324 src2dest.
insert(src.root(), this->root());
325 lifo.push_back(src.root());
329 while (!lifo.empty()) {
330 NodeId currentSrcNodeId = lifo.back();
333 const InternalNode* currentSrcNode = src.node(currentSrcNodeId);
335 for (
Idx index = 0; index < currentSrcNode->
nbSons(); ++index) {
337 NodeId srcSonNodeId = currentSrcNode->
son(index), destSonNodeId = 0;
338 if (src.isTerminalNode(srcSonNodeId)) {
340 this->manager()->addTerminalNode(src.nodeValue(srcSonNodeId));
342 destSonNodeId = this->manager()->addInternalNode(
343 reassign.
second(src.node(srcSonNodeId)->nodeVar()));
344 lifo.push_back(srcSonNodeId);
346 src2dest.
insert(srcSonNodeId, destSonNodeId);
348 this->manager()->setSon(src2dest.
second(currentSrcNodeId),
350 src2dest.
second(currentSrcNode->
son(index)));
358 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
363 if (this->__isReduced != src.isReducedAndOrdered())
365 "Cannot copy a Reduced and Ordered " 366 "function graph into Tree function graph " 373 src.variablesSequence().beginSafe();
374 varIter != src.variablesSequence().endSafe();
376 this->add(**varIter);
378 std::vector< NodeId > lifo;
381 if (src.isTerminalNode(src.root()))
382 this->manager()->setRootNode(
383 this->manager()->addTerminalNode(gamma * src.nodeValue(src.root())));
385 this->manager()->setRootNode(
386 this->manager()->addInternalNode(src.node(src.root())->nodeVar()));
387 src2dest.
insert(src.root(), this->root());
388 lifo.push_back(src.root());
392 while (!lifo.empty()) {
393 NodeId currentSrcNodeId = lifo.back();
396 const InternalNode* currentSrcNode = src.node(currentSrcNodeId);
398 for (
Idx index = 0; index < currentSrcNode->
nbSons(); ++index) {
399 if (!src2dest.
exists(currentSrcNode->
son(index))) {
400 NodeId srcSonNodeId = currentSrcNode->
son(index), destSonNodeId = 0;
401 if (src.isTerminalNode(srcSonNodeId)) {
402 destSonNodeId = this->manager()->addTerminalNode(
403 gamma * src.nodeValue(srcSonNodeId));
406 this->manager()->addInternalNode(src.node(srcSonNodeId)->nodeVar());
407 lifo.push_back(srcSonNodeId);
409 src2dest.
insert(srcSonNodeId, destSonNodeId);
411 this->manager()->setSon(src2dest[currentSrcNodeId],
413 src2dest[currentSrcNode->
son(index)]);
421 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
427 this->clearAllTerminalNodes();
431 __internalNodeMap.begin();
432 nodeIter != __internalNodeMap.end();
434 delete nodeIter.val();
436 __internalNodeMap.clear();
440 varIter = __var2NodeIdMap.begin();
441 varIter != __var2NodeIdMap.end();
443 delete varIter.val();
445 __var2NodeIdMap.clear();
448 this->variablesSequence().rbeginSafe();
449 varIter != this->variablesSequence().rendSafe();
451 this->erase(**varIter);
456 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
459 bool withBackArcs)
const {
460 std::stringstream output;
461 std::stringstream terminalStream;
462 std::stringstream nonTerminalStream;
463 std::stringstream arcstream;
465 output << std::endl <<
"digraph \" " << __tableName <<
"\" {" << std::endl;
467 terminalStream <<
"node [shape = box];" << std::endl;
468 nonTerminalStream <<
"node [shape = ellipse];" << std::endl;
469 std::string tab =
" ";
472 nodeIter != __model.end();
474 if (*nodeIter != 0) {
475 if (this->isTerminalNode((
NodeId)*nodeIter))
476 terminalStream << tab << *nodeIter <<
";" << tab << *nodeIter
477 <<
" [label=\"" << *nodeIter <<
" - " 478 << std::setprecision(30)
479 << this->terminalNodeValue(*nodeIter) <<
"\"]" 482 InternalNode* currentNode = __internalNodeMap[*nodeIter];
483 nonTerminalStream << tab << *nodeIter <<
";" << tab << *nodeIter
484 <<
" [label=\"" << *nodeIter <<
" - " 490 for (
Idx sonIter = 0; sonIter < currentNode->
nbSons(); ++sonIter) {
491 if (!sonMap.
exists(currentNode->
son(sonIter)))
493 sonMap[currentNode->
son(sonIter)]->addLink(sonIter);
498 arcstream << tab << *nodeIter <<
" -> " << sonIter.
key()
506 arcstream <<
"\",color=\"#0000ff\"]" 508 delete sonIter.val();
513 while (parentIter !=
nullptr) {
514 arcstream << tab << *nodeIter <<
" -> " 515 << parentIter->
element().parentId <<
" [label=\"" 516 << parentIter->
element().modality
517 <<
"\",color=\"#ff0000\"]" 519 parentIter = parentIter->
nextLink();
525 output << terminalStream.str() << std::endl
526 << nonTerminalStream.str() << std::endl
527 << arcstream.str() << std::endl
534 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
541 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
544 if (__manager ==
nullptr) {
558 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
565 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
568 const NodeId& node)
const {
569 return this->existsTerminalNodeWithId(node);
573 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
576 const NodeId& node)
const {
577 return this->__internalNodeMap.exists(node);
581 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
582 INLINE
const GUM_SCALAR&
585 if (!isTerminalNode(n))
587 "Id " << n <<
" is not bound to any terminal node")
588 return this->terminalNodeValue(n);
592 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
596 if (!isInternalNode(n))
598 "Id " << n <<
" is not bound to any terminal node")
599 return this->__internalNodeMap[n];
603 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
607 if (!this->variablesSequence().exists(var))
609 "Var " << var->
name()
610 <<
" has not been inserted in the function graph")
611 return __var2NodeIdMap[var];
615 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
616 INLINE
const std::string&
622 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
625 const std::string& name) {
630 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
638 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
641 TerminalNodePolicy >::getReducedAndOrderedInstance() {
646 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
653 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
659 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
663 "You can't edit a function by other mean than the manager");
667 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
670 NodeId currentNodeId = __root;
672 while (!isTerminalNode(currentNodeId)) {
673 currentNode = __internalNodeMap[currentNodeId];
674 currentNodeId = currentNode->
son(inst.
val(*(currentNode->
nodeVar())));
676 return this->terminalNodeValue(currentNodeId);
void insert(const T1 &first, const T2 &second)
Inserts a new association in the gum::Bijection.
const T2 & second(const T1 &first) const
Returns the second value of a pair given its first value.
Safe iterators for Sequence.
const iterator_safe & endSafe() noexcept
Returns the safe iterator pointing to the end of the hashtable.
const DiscreteVariable * nodeVar() const
Returns the node variable.
Idx nbSons() const
Returns the number of sons.
MultiDimFunctionGraph(bool isReduced=true)
Default constructor.
Unsafe Iterators for hashtablesHashTableIterator provides a fast but unsafe way to parse HashTables...
NodeId son(Idx modality) const
Returns the son at a given index.
bool exists(const Key &key) const
Checks whether there exists an element with a given key in the hashtable.
const Key & key(const Key &key) const
Returns a reference on a given key.
virtual void erase(const DiscreteVariable &v)
Removes a var from the variables of the multidimensional matrix.
Link< Parent > * parents()
Returns the list of parents.
Base class for discrete random variable.
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
Abstract base class for all multi dimensionnal containers.
Idx val(Idx i) const
Returns the current value of the variable at position i.
const T & element() const
Returns the element stored in this link.
bool existsFirst(const T1 &first) const
Returns true if first is the first element in a pair in the gum::Bijection.
Unsafe iterator on the node set of a graph.
Class implementingting a function graph manager.
virtual std::string label(Idx i) const =0
get the indice-th label. This method is pure virtual.
Structure used to represent a node internal structure.
Link of a chain list allocated using the SmallObjectAllocator.
Set of pairs of elements with fast search for both elements.
Class implementingting a function graph.
Class for node sets in graph.
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
Class for assigning/browsing values to tuples of discrete variables.
Chain list allocated using the SmallObjectAllocator.
iterator_safe beginSafe()
Returns the safe iterator pointing to the beginning of the hashtable.
<agrum/multidim/multiDimImplementation.h>
Size Idx
Type for indexes.
std::size_t Size
In aGrUM, hashed values are unsigned long int.
value_type & insert(const Key &key, const Val &val)
Adds a new element (actually a copy of this element) into the hash table.
const std::string & name() const
returns the name of the variable
const Link< T > * nextLink() const
Returns next link.
Size NodeId
Type for node ids.
#define GUM_ERROR(type, msg)
void clear()
Clears the function graph.