aGrUM 3.1.1
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-2026 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-2026 *
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
41#pragma once
42
43
52
55
56#define ALLOCATE(x) SmallObjectAllocator::instance().allocate(x)
57#define DEALLOCATE(x, y) SmallObjectAllocator::instance().deallocate(x, y)
58
59namespace gum {
60
61 template < typename GUM_ELEMENT,
62 template < typename > class COMBINEOPERATOR,
63 template < typename > class TerminalNodePolicy >
72
73 template < typename GUM_ELEMENT,
74 template < typename > class COMBINEOPERATOR,
75 template < typename > class TerminalNodePolicy >
85
86 template < typename GUM_ELEMENT,
87 template < typename > class COMBINEOPERATOR,
88 template < typename > class TerminalNodePolicy >
92
93 // This function is the main function. To be call every time an operation
94 // between the two given Function Graphs is required
95 template < typename GUM_ELEMENT,
96 template < typename > class COMBINEOPERATOR,
97 template < typename > class TerminalNodePolicy >
100 _rd_->manager()->setRootNode(_xPloreDT1_(_dt1_->root()));
101
102 return _rd_;
103 }
104
105 // Main recursion function, called every time we move on a node to determine
106 // what we have to do
107 template < typename GUM_ELEMENT,
108 template < typename > class COMBINEOPERATOR,
109 template < typename > class TerminalNodePolicy >
111 NodeId currentNodeId) {
112 if (_dt1_->isTerminalNode(currentNodeId)) {
113 _curDT1Leaf_ = currentNodeId;
114 return _xPloreDT2_(_dt2_->root());
115 }
116
117 const InternalNode* currentNode = _dt1_->node(currentNodeId);
118
119 if (!_rd_->variablesSequence().exists(currentNode->nodeVar()))
120 _rd_->add(*(currentNode->nodeVar()));
121
122 NodeId* sonsMap
123 = static_cast< NodeId* >(ALLOCATE(sizeof(NodeId) * currentNode->nodeVar()->domainSize()));
124 for (Idx moda = 0; moda < currentNode->nodeVar()->domainSize(); ++moda) {
125 _context_.insert(currentNode->nodeVar(), moda);
126 sonsMap[moda] = _xPloreDT1_(currentNode->son(moda));
127 _context_.erase(currentNode->nodeVar());
128 }
129 return _checkRedundancy_(currentNode->nodeVar(), sonsMap);
130 }
131
132 template < typename GUM_ELEMENT,
133 template < typename > class COMBINEOPERATOR,
134 template < typename > class TerminalNodePolicy >
136 NodeId currentNodeId) {
137 if (_dt2_->isTerminalNode(currentNodeId))
138 return _rd_->manager()->addTerminalNode(
139 _combine_(_dt1_->nodeValue(_curDT1Leaf_), _dt2_->nodeValue(currentNodeId)));
140
141 const InternalNode* currentNode = _dt2_->node(currentNodeId);
142
143 if (!_rd_->variablesSequence().exists(currentNode->nodeVar()))
144 _rd_->add(*(currentNode->nodeVar()));
145
146 if (_context_.exists(currentNode->nodeVar()))
147 return _xPloreDT2_(currentNode->son(_context_[currentNode->nodeVar()]));
148
149 NodeId* sonsMap
150 = static_cast< NodeId* >(ALLOCATE(sizeof(NodeId) * currentNode->nodeVar()->domainSize()));
151 for (Idx moda = 0; moda < currentNode->nodeVar()->domainSize(); ++moda) {
152 _context_.insert(currentNode->nodeVar(), moda);
153 sonsMap[moda] = _xPloreDT2_(currentNode->son(moda));
154 _context_.erase(currentNode->nodeVar());
155 }
156 return _checkRedundancy_(currentNode->nodeVar(), sonsMap);
157 }
158
159 template < typename GUM_ELEMENT,
160 template < typename > class COMBINEOPERATOR,
161 template < typename > class TerminalNodePolicy >
163 const DiscreteVariable* var,
164 NodeId* sonsMap) {
165 bool diff = false;
166 for (Idx moda = 1; moda < var->domainSize() && !diff; ++moda)
167 if (sonsMap[0] != sonsMap[moda]) diff = true;
168
169 if (!diff) {
170 NodeId zero = sonsMap[0];
171 DEALLOCATE(sonsMap, sizeof(NodeId) * var->domainSize());
172 return zero;
173 }
174
175 return _rd_->manager()->addInternalNode(var, sonsMap);
176 }
177
178} // namespace gum
Base class for discrete random variable.
virtual Size domainSize() const =0
The class for generic Hash Tables.
Definition hashTable.h:640
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_ELEMENT, TerminalNodePolicy > * getTreeInstance()
Returns an arborescent instance.
HashTable< const DiscreteVariable *, Idx > _context_
TreeOperator(const MultiDimFunctionGraph< GUM_ELEMENT, TerminalNodePolicy > *dt1, const MultiDimFunctionGraph< GUM_ELEMENT, TerminalNodePolicy > *dt2)
Default constructor.
const MultiDimFunctionGraph< GUM_ELEMENT, TerminalNodePolicy > * _dt1_
The two function graphs used for the operation.
MultiDimFunctionGraph< GUM_ELEMENT, TerminalNodePolicy > * _rd_
The resulting function graph.
NodeId _checkRedundancy_(const DiscreteVariable *, NodeId *)
NodeId _xPloreDT1_(NodeId currentNodeId)
The main recursion function.
~TreeOperator()
Default destructor.
NodeId _xPloreDT2_(NodeId currentNodeId)
The main recursion function.
const COMBINEOPERATOR< GUM_ELEMENT > _combine_
The function to be performed on the leaves.
const MultiDimFunctionGraph< GUM_ELEMENT, TerminalNodePolicy > * _dt2_
MultiDimFunctionGraph< GUM_ELEMENT, TerminalNodePolicy > * compute()
Computes and builds the Function Graph that is the result of the operation.
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.