aGrUM 2.3.2
a C++ library for (probabilistic) graphical models
treeOperator_tpl.h
Go to the documentation of this file.
1/****************************************************************************
2 * This file is part of the aGrUM/pyAgrum library. *
3 * *
4 * Copyright (c) 2005-2025 by *
5 * - Pierre-Henri WUILLEMIN(_at_LIP6) *
6 * - Christophe GONZALES(_at_AMU) *
7 * *
8 * The aGrUM/pyAgrum library is free software; you can redistribute it *
9 * and/or modify it under the terms of either : *
10 * *
11 * - the GNU Lesser General Public License as published by *
12 * the Free Software Foundation, either version 3 of the License, *
13 * or (at your option) any later version, *
14 * - the MIT license (MIT), *
15 * - or both in dual license, as here. *
16 * *
17 * (see https://agrum.gitlab.io/articles/dual-licenses-lgplv3mit.html) *
18 * *
19 * This aGrUM/pyAgrum library is distributed in the hope that it will be *
20 * useful, but WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
21 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES MERCHANTABILITY or FITNESS *
22 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
25 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR *
26 * OTHER DEALINGS IN THE SOFTWARE. *
27 * *
28 * See LICENCES for more details. *
29 * *
30 * SPDX-FileCopyrightText: Copyright 2005-2025 *
31 * - Pierre-Henri WUILLEMIN(_at_LIP6) *
32 * - Christophe GONZALES(_at_AMU) *
33 * SPDX-License-Identifier: LGPL-3.0-or-later OR MIT *
34 * *
35 * Contact : info_at_agrum_dot_org *
36 * homepage : http://agrum.gitlab.io *
37 * gitlab : https://gitlab.com/agrumery/agrum *
38 * *
39 ****************************************************************************/
40#pragma once
41
42
51
54
55#define ALLOCATE(x) SmallObjectAllocator::instance().allocate(x)
56#define DEALLOCATE(x, y) SmallObjectAllocator::instance().deallocate(x, y)
57
58namespace gum {
59
60 template < typename GUM_SCALAR,
61 template < typename > class COMBINEOPERATOR,
62 template < typename > class TerminalNodePolicy >
71
72 template < typename GUM_SCALAR,
73 template < typename > class COMBINEOPERATOR,
74 template < typename > class TerminalNodePolicy >
84
85 template < typename GUM_SCALAR,
86 template < typename > class COMBINEOPERATOR,
87 template < typename > class TerminalNodePolicy >
91
92 // This function is the main function. To be call every time an operation
93 // between the two given Function Graphs is required
94 template < typename GUM_SCALAR,
95 template < typename > class COMBINEOPERATOR,
96 template < typename > class TerminalNodePolicy >
99 _rd_->manager()->setRootNode(_xPloreDT1_(_dt1_->root()));
100
101 return _rd_;
102 }
103
104 // Main recursion function, called every time we move on a node to determine
105 // what we have to do
106 template < typename GUM_SCALAR,
107 template < typename > class COMBINEOPERATOR,
108 template < typename > class TerminalNodePolicy >
110 NodeId currentNodeId) {
111 if (_dt1_->isTerminalNode(currentNodeId)) {
112 _curDT1Leaf_ = currentNodeId;
113 return _xPloreDT2_(_dt2_->root());
114 }
115
116 const InternalNode* currentNode = _dt1_->node(currentNodeId);
117
118 if (!_rd_->variablesSequence().exists(currentNode->nodeVar()))
119 _rd_->add(*(currentNode->nodeVar()));
120
121 NodeId* sonsMap
122 = static_cast< NodeId* >(ALLOCATE(sizeof(NodeId) * currentNode->nodeVar()->domainSize()));
123 for (Idx moda = 0; moda < currentNode->nodeVar()->domainSize(); ++moda) {
124 _context_.insert(currentNode->nodeVar(), moda);
125 sonsMap[moda] = _xPloreDT1_(currentNode->son(moda));
126 _context_.erase(currentNode->nodeVar());
127 }
128 return _checkRedundancy_(currentNode->nodeVar(), sonsMap);
129 }
130
131 template < typename GUM_SCALAR,
132 template < typename > class COMBINEOPERATOR,
133 template < typename > class TerminalNodePolicy >
135 NodeId currentNodeId) {
136 if (_dt2_->isTerminalNode(currentNodeId))
137 return _rd_->manager()->addTerminalNode(
138 _combine_(_dt1_->nodeValue(_curDT1Leaf_), _dt2_->nodeValue(currentNodeId)));
139
140 const InternalNode* currentNode = _dt2_->node(currentNodeId);
141
142 if (!_rd_->variablesSequence().exists(currentNode->nodeVar()))
143 _rd_->add(*(currentNode->nodeVar()));
144
145 if (_context_.exists(currentNode->nodeVar()))
146 return _xPloreDT2_(currentNode->son(_context_[currentNode->nodeVar()]));
147
148 NodeId* sonsMap
149 = static_cast< NodeId* >(ALLOCATE(sizeof(NodeId) * currentNode->nodeVar()->domainSize()));
150 for (Idx moda = 0; moda < currentNode->nodeVar()->domainSize(); ++moda) {
151 _context_.insert(currentNode->nodeVar(), moda);
152 sonsMap[moda] = _xPloreDT2_(currentNode->son(moda));
153 _context_.erase(currentNode->nodeVar());
154 }
155 return _checkRedundancy_(currentNode->nodeVar(), sonsMap);
156 }
157
158 template < typename GUM_SCALAR,
159 template < typename > class COMBINEOPERATOR,
160 template < typename > class TerminalNodePolicy >
162 const DiscreteVariable* var,
163 NodeId* sonsMap) {
164 bool diff = false;
165 for (Idx moda = 1; moda < var->domainSize() && !diff; ++moda)
166 if (sonsMap[0] != sonsMap[moda]) diff = true;
167
168 if (!diff) {
169 NodeId zero = sonsMap[0];
170 DEALLOCATE(sonsMap, sizeof(NodeId) * var->domainSize());
171 return zero;
172 }
173
174 return _rd_->manager()->addInternalNode(var, sonsMap);
175 }
176
177} // namespace gum
Base class for discrete random variable.
virtual Size domainSize() const =0
The class for generic Hash Tables.
Definition hashTable.h:637
Structure used to represent a node internal structure.
const DiscreteVariable * nodeVar() const
Returns the node variable.
NodeId son(Idx modality) const
Returns the son at a given index.
static MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * getTreeInstance()
Returns an arborescent instance.
const MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * _dt1_
The two function graphs used for the operation.
NodeId _xPloreDT2_(NodeId currentNodeId)
The main recursion function.
MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * _rd_
The resulting function graph.
const MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * _dt2_
NodeId _checkRedundancy_(const DiscreteVariable *, NodeId *)
~TreeOperator()
Default destructor.
HashTable< const DiscreteVariable *, Idx > _context_
MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * compute()
Computes and builds the Function Graph that is the result of the operation.
NodeId _xPloreDT1_(NodeId currentNodeId)
The main recursion function.
TreeOperator(const MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > *dt1, const MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > *dt2)
Default constructor.
const COMBINEOPERATOR< GUM_SCALAR > _combine_
The function to be performed on the leaves.
Size Idx
Type for indexes.
Definition types.h:79
Size NodeId
Type for node ids.
#define DEALLOCATE(x, y)
#define ALLOCATE(x)
Headers of the InternalNode class.
gum is the global namespace for all aGrUM entities
Definition agrum.h:46
Class used to compute the operation between two decision diagrams.