32 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
36 __name(
"MultiDimFunctionGraph"), __tableName(
"NO NAME"), __model(500, true),
37 __manager(nullptr), __root(0), __internalNodeMap(500, true, false),
38 __var2NodeIdMap(500, true, false), __isReduced(isReduced) {
46 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
51 __name(
"MultiDimFunctionGraph"), __tableName(
"No NAME"), __model(500, true),
52 __manager(nullptr), __root(0), __internalNodeMap(500, true, false),
53 __var2NodeIdMap(500, true, false), __isReduced(from.isReducedAndOrdered()) {
59 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
68 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
70 TerminalNodePolicy >::~MultiDimFunctionGraph() {
73 if (__manager !=
nullptr)
delete __manager;
77 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
85 TerminalNodePolicy >::getTreeInstance();
88 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
89 INLINE
const std::string&
94 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
98 "Function Graph can't be edited so " 99 "easily.\nMultiDimFunctionGraphManager " 100 "provides the framework to edit a " 104 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
106 const GUM_SCALAR& d)
const {
108 "Function Graph can't be edited so " 109 "easily.\nMultiDimFunctionGraphManager " 110 "provides the framework to edit a " 114 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
116 const std::vector< GUM_SCALAR >& v)
const {
118 "Function Graph can't be edited so " 119 "easily.\nMultiDimFunctionGraphManager " 120 "provides the framework to editaa " 123 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
125 std::initializer_list< GUM_SCALAR > l)
const {
127 "Function Graph can't be edited so " 128 "easily.\nMultiDimFunctionGraphManager " 129 "provides the framework to edit a " 133 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
136 if (!this->variablesSequence().exists(&v))
139 if (!this->__var2NodeIdMap.exists(&v))
143 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
146 if (this->__var2NodeIdMap.exists(&v)) {
147 while (__var2NodeIdMap[&v]->list() !=
nullptr) {
148 manager()->eraseNode(__var2NodeIdMap[&v]->list()->element());
150 delete __var2NodeIdMap[&v];
151 __var2NodeIdMap.
erase(&v);
154 if (this->variablesSequence().exists(&v))
158 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
161 return __internalNodeMap.size();
165 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
173 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
178 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
183 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
188 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
193 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
197 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
198 INLINE
const std::string
201 std::stringstream sBuff;
202 sBuff << (*i) <<
" = " << this->
get(*i);
206 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
210 "You cannot copy another type of multiDim " 211 "into a MultiDimFunctionGraph.");
214 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
218 "You cannot copy another type of multiDim " 219 "into a MultiDimFunctionGraph.");
222 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
225 if (this->__isReduced != src.isReducedAndOrdered())
227 "Cannot copy a Reduced and Ordered " 228 "function graph into Tree function graph " 235 src.variablesSequence().beginSafe();
236 varIter != src.variablesSequence().endSafe();
238 this->add(**varIter);
240 std::vector< NodeId > lifo;
243 if (src.isTerminalNode(src.root()))
244 this->manager()->setRootNode(
245 this->manager()->addTerminalNode(src.nodeValue(src.root())));
247 this->manager()->setRootNode(
248 this->manager()->addInternalNode(src.node(src.root())->nodeVar()));
249 src2dest.
insert(src.root(), this->root());
250 lifo.push_back(src.root());
254 while (!lifo.empty()) {
255 NodeId currentSrcNodeId = lifo.back();
258 const InternalNode* currentSrcNode = src.node(currentSrcNodeId);
260 for (
Idx index = 0; index < currentSrcNode->
nbSons(); ++index) {
262 NodeId srcSonNodeId = currentSrcNode->
son(index), destSonNodeId = 0;
263 if (src.isTerminalNode(srcSonNodeId)) {
265 this->manager()->addTerminalNode(src.nodeValue(srcSonNodeId));
268 this->manager()->addInternalNode(src.node(srcSonNodeId)->nodeVar());
269 lifo.push_back(srcSonNodeId);
271 src2dest.
insert(srcSonNodeId, destSonNodeId);
273 this->manager()->setSon(src2dest.
second(currentSrcNodeId),
275 src2dest.
second(currentSrcNode->
son(index)));
283 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
289 if (this->__isReduced != src.isReducedAndOrdered())
291 "Cannot copy a Reduced and Ordered " 292 "function graph into Tree function graph " 299 src.variablesSequence().beginSafe();
300 varIter != src.variablesSequence().endSafe();
302 if ((*varIter)->domainSize() != reassign.
second(*varIter)->domainSize())
304 "Var " << (*varIter)->name() <<
" and var " 305 << reassign.
second(*varIter)->name()
306 <<
" have different domain sizes (" 307 << (*varIter)->domainSize()
308 <<
"!=" << reassign.
second(*varIter)->domainSize() <<
")")
309 this->add(*(reassign.
second(*varIter)));
312 std::vector< NodeId > lifo;
315 if (src.isTerminalNode(src.root())) {
316 this->manager()->setRootNode(
317 this->manager()->addTerminalNode(src.nodeValue(src.root())));
319 this->manager()->setRootNode(this->manager()->addInternalNode(
320 reassign.
second(src.node(src.root())->nodeVar())));
321 src2dest.
insert(src.root(), this->root());
322 lifo.push_back(src.root());
326 while (!lifo.empty()) {
327 NodeId currentSrcNodeId = lifo.back();
330 const InternalNode* currentSrcNode = src.node(currentSrcNodeId);
332 for (
Idx index = 0; index < currentSrcNode->
nbSons(); ++index) {
334 NodeId srcSonNodeId = currentSrcNode->
son(index), destSonNodeId = 0;
335 if (src.isTerminalNode(srcSonNodeId)) {
337 this->manager()->addTerminalNode(src.nodeValue(srcSonNodeId));
339 destSonNodeId = this->manager()->addInternalNode(
340 reassign.
second(src.node(srcSonNodeId)->nodeVar()));
341 lifo.push_back(srcSonNodeId);
343 src2dest.
insert(srcSonNodeId, destSonNodeId);
345 this->manager()->setSon(src2dest.
second(currentSrcNodeId),
347 src2dest.
second(currentSrcNode->
son(index)));
355 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
360 if (this->__isReduced != src.isReducedAndOrdered())
362 "Cannot copy a Reduced and Ordered " 363 "function graph into Tree function graph " 370 src.variablesSequence().beginSafe();
371 varIter != src.variablesSequence().endSafe();
373 this->add(**varIter);
375 std::vector< NodeId > lifo;
378 if (src.isTerminalNode(src.root()))
379 this->manager()->setRootNode(
380 this->manager()->addTerminalNode(gamma * src.nodeValue(src.root())));
382 this->manager()->setRootNode(
383 this->manager()->addInternalNode(src.node(src.root())->nodeVar()));
384 src2dest.
insert(src.root(), this->root());
385 lifo.push_back(src.root());
389 while (!lifo.empty()) {
390 NodeId currentSrcNodeId = lifo.back();
393 const InternalNode* currentSrcNode = src.node(currentSrcNodeId);
395 for (
Idx index = 0; index < currentSrcNode->
nbSons(); ++index) {
396 if (!src2dest.
exists(currentSrcNode->
son(index))) {
397 NodeId srcSonNodeId = currentSrcNode->
son(index), destSonNodeId = 0;
398 if (src.isTerminalNode(srcSonNodeId)) {
399 destSonNodeId = this->manager()->addTerminalNode(
400 gamma * src.nodeValue(srcSonNodeId));
403 this->manager()->addInternalNode(src.node(srcSonNodeId)->nodeVar());
404 lifo.push_back(srcSonNodeId);
406 src2dest.
insert(srcSonNodeId, destSonNodeId);
408 this->manager()->setSon(src2dest[currentSrcNodeId],
410 src2dest[currentSrcNode->
son(index)]);
418 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
424 this->clearAllTerminalNodes();
428 __internalNodeMap.begin();
429 nodeIter != __internalNodeMap.end();
431 delete nodeIter.val();
433 __internalNodeMap.clear();
437 varIter = __var2NodeIdMap.begin();
438 varIter != __var2NodeIdMap.end();
440 delete varIter.val();
442 __var2NodeIdMap.clear();
445 this->variablesSequence().rbeginSafe();
446 varIter != this->variablesSequence().rendSafe();
448 this->erase(**varIter);
453 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
456 bool withBackArcs)
const {
457 std::stringstream output;
458 std::stringstream terminalStream;
459 std::stringstream nonTerminalStream;
460 std::stringstream arcstream;
462 output << std::endl <<
"digraph \" " << __tableName <<
"\" {" << std::endl;
464 terminalStream <<
"node [shape = box];" << std::endl;
465 nonTerminalStream <<
"node [shape = ellipse];" << std::endl;
466 std::string tab =
" ";
469 nodeIter != __model.end();
471 if (*nodeIter != 0) {
472 if (this->isTerminalNode((
NodeId)*nodeIter))
473 terminalStream << tab << *nodeIter <<
";" << tab << *nodeIter
474 <<
" [label=\"" << *nodeIter <<
" - " 475 << std::setprecision(30)
476 << this->terminalNodeValue(*nodeIter) <<
"\"]" 479 InternalNode* currentNode = __internalNodeMap[*nodeIter];
480 nonTerminalStream << tab << *nodeIter <<
";" << tab << *nodeIter
481 <<
" [label=\"" << *nodeIter <<
" - " 487 for (
Idx sonIter = 0; sonIter < currentNode->
nbSons(); ++sonIter) {
488 if (!sonMap.
exists(currentNode->
son(sonIter)))
490 sonMap[currentNode->
son(sonIter)]->addLink(sonIter);
495 arcstream << tab << *nodeIter <<
" -> " << sonIter.
key()
503 arcstream <<
"\",color=\"#0000ff\"]" 505 delete sonIter.val();
510 while (parentIter !=
nullptr) {
511 arcstream << tab << *nodeIter <<
" -> " 512 << parentIter->
element().parentId <<
" [label=\"" 513 << parentIter->
element().modality
514 <<
"\",color=\"#ff0000\"]" 516 parentIter = parentIter->
nextLink();
522 output << terminalStream.str() << std::endl
523 << nonTerminalStream.str() << std::endl
524 << arcstream.str() << std::endl
531 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
538 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
541 if (__manager ==
nullptr) {
555 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
562 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
565 const NodeId& node)
const {
566 return this->existsTerminalNodeWithId(node);
570 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
573 const NodeId& node)
const {
574 return this->__internalNodeMap.exists(node);
578 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
579 INLINE
const GUM_SCALAR&
582 if (!isTerminalNode(n))
584 "Id " << n <<
" is not bound to any terminal node")
585 return this->terminalNodeValue(n);
589 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
593 if (!isInternalNode(n))
595 "Id " << n <<
" is not bound to any terminal node")
596 return this->__internalNodeMap[n];
600 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
604 if (!this->variablesSequence().exists(var))
606 "Var " << var->
name()
607 <<
" has not been inserted in the function graph")
608 return __var2NodeIdMap[var];
612 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
613 INLINE
const std::string&
619 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
622 const std::string& name) {
627 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
635 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
638 TerminalNodePolicy >::getReducedAndOrderedInstance() {
643 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
650 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
656 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
660 "You can't edit a function by other mean than the manager");
664 template <
typename GUM_SCALAR,
template <
class >
class TerminalNodePolicy >
667 NodeId currentNodeId = __root;
669 while (!isTerminalNode(currentNodeId)) {
670 currentNode = __internalNodeMap[currentNodeId];
671 currentNodeId = currentNode->
son(inst.
val(*(currentNode->
nodeVar())));
673 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.
gum is the global namespace for all aGrUM entities
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.
Headers of MultiDimFunctionGraph.
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.