aGrUM 2.3.2
a C++ library for (probabilistic) graphical models
decisionTensor.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
41
49#ifndef AGRUM_DECISIONTENSOR_H
50#define AGRUM_DECISIONTENSOR_H
51
53
54namespace gum {
60 template < typename GUM_SCALAR >
62 public:
63 Tensor< GUM_SCALAR > probPot;
64 Tensor< GUM_SCALAR > utilPot;
65
66 explicit DecisionTensor() {
67 GUM_CONSTRUCTOR(DecisionTensor);
68 probPot.fillWith(GUM_SCALAR(1));
69 utilPot.fillWith(GUM_SCALAR(0));
70 }
71
73 GUM_DESTRUCTOR(DecisionTensor);
74 ;
75 }
76
77 DecisionTensor(const Tensor< GUM_SCALAR >& prob, const Tensor< GUM_SCALAR >& util) :
78 probPot(prob), utilPot(util) {
79 GUM_CONSTRUCTOR(DecisionTensor);
80 }
81
84 GUM_CONS_CPY(DecisionTensor);
85 }
86
87 void clear() {
89 p.fillWith(GUM_SCALAR(1));
90 probPot = p;
91 p.fillWith(GUM_SCALAR(0));
92 utilPot = p;
93 }
94
96 GUM_OP_CPY(DecisionTensor);
97 if (&src == this) return *this;
98 probPot = src.probPot;
99 utilPot = src.utilPot;
100 return *this;
101 }
102
104 probPot(std::forward< Tensor< GUM_SCALAR > >(dp.probPot)),
105 utilPot(std::forward< Tensor< GUM_SCALAR > >(dp.utilPot)) {
106 GUM_CONS_MOV(DecisionTensor);
107 }
108
110 GUM_OP_MOV(DecisionTensor);
111 if (&src == this) return *this;
112 probPot = std::forward< Tensor< GUM_SCALAR > >(src.probPot);
113 utilPot = std::forward< Tensor< GUM_SCALAR > >(src.utilPot);
114 return *this;
115 }
116
118 // @see Evaluating Influence Diagrams using LIMIDS (2000) - section 3.3
119 return ((p.probPot == this->probPot)
120 && (p.probPot * p.utilPot == this->probPot * this->utilPot));
121 }
122
123 bool operator!=(const DecisionTensor< GUM_SCALAR >& p) const { return !operator==(p); }
124
125 const DiscreteVariable* variable(const std::string& name) const {
126 for (const auto& v: probPot.variablesSequence()) {
127 if (v->name() == name) return v;
128 }
129 for (const auto& v: utilPot.variablesSequence()) {
130 if (v->name() == name) return v;
131 }
132
133 GUM_ERROR(NotFound, "'" << name << "' can not be found in DecisionTensor.")
134 }
135
136 void insertProba(const gum::Tensor< GUM_SCALAR >& proba) { probPot *= proba; }
137
138 void insertUtility(const gum::Tensor< GUM_SCALAR >& util) { utilPot += util; }
139
143
148
152
153 DecisionTensor< GUM_SCALAR > operator^(const std::vector< std::string >& ontonames) const {
154 return DecisionTensor< GUM_SCALAR >::marginalization(*this, ontonames);
155 }
156
157 static Tensor< GUM_SCALAR > divideEvenZero(const Tensor< GUM_SCALAR >& p1,
158 const Tensor< GUM_SCALAR >& p2) {
159 Tensor< GUM_SCALAR > res(p1);
160 Instantiation I(res);
161 for (I.setFirst(); !I.end(); I.inc()) {
162 if (p2[I] != 0) res.set(I, res[I] / p2[I]);
163 }
164 return res;
165 }
166
171
173 const gum::VariableSet& onto) {
174 const auto pr = dp.probPot.sumIn(onto);
175 return DecisionTensor(pr, divideEvenZero((dp.probPot * dp.utilPot).sumIn(onto), pr));
176 }
177
180 const std::vector< std::string >& ontonames) {
181 gum::VariableSet onto;
182 for (const auto& varname: ontonames) {
183 onto.insert(dp.variable(varname));
184 }
185 return marginalization(dp, onto);
186 }
187
188 std::pair< GUM_SCALAR, GUM_SCALAR > meanVar() {
189 const auto tmp = probPot * utilPot;
190 const GUM_SCALAR s = probPot.sum();
191 const double m = tmp.sum() / s;
192 const double m2 = (tmp * utilPot).sum() / s;
193 double var = m2 - m * m;
194 if (var < 0.0) var = 0.0; // var is a small number<0 due to computation errors
195 return std::pair< GUM_SCALAR, GUM_SCALAR >(m, var);
196 }
197
198 virtual std::string toString() const {
199 return "prob : " + probPot.toString() + " util:" + utilPot.toString();
200 }
201 };
202
203 template < typename GUM_SCALAR >
204 std::ostream& operator<<(std::ostream& out, const DecisionTensor< GUM_SCALAR >& array) {
205 out << array.toString();
206 return out;
207 }
208} // namespace gum
209
210#endif // AGRUM_DECISIONTENSOR_H
<agrum/ID/inference/decisionTensor.h>
bool operator==(const DecisionTensor< GUM_SCALAR > &p) const
void insertProba(const gum::Tensor< GUM_SCALAR > &proba)
std::pair< GUM_SCALAR, GUM_SCALAR > meanVar()
static Tensor< GUM_SCALAR > divideEvenZero(const Tensor< GUM_SCALAR > &p1, const Tensor< GUM_SCALAR > &p2)
DecisionTensor(const Tensor< GUM_SCALAR > &prob, const Tensor< GUM_SCALAR > &util)
DecisionTensor< GUM_SCALAR > & operator=(DecisionTensor< GUM_SCALAR > &&src)
static DecisionTensor< GUM_SCALAR > combination(const DecisionTensor< GUM_SCALAR > &dp1, const DecisionTensor< GUM_SCALAR > &dp2)
DecisionTensor(const DecisionTensor< GUM_SCALAR > &dp)
DecisionTensor< GUM_SCALAR > & operator=(const DecisionTensor< GUM_SCALAR > &src)
DecisionTensor(DecisionTensor< GUM_SCALAR > &&dp)
DecisionTensor< GUM_SCALAR > operator^(const std::vector< std::string > &ontonames) const
void insertUtility(const gum::Tensor< GUM_SCALAR > &util)
DecisionTensor< GUM_SCALAR > operator^(const gum::VariableSet &onto) const
DecisionTensor< GUM_SCALAR > operator*(const DecisionTensor< GUM_SCALAR > &dp1) const
Tensor< GUM_SCALAR > utilPot
static DecisionTensor< GUM_SCALAR > marginalization(const DecisionTensor< GUM_SCALAR > &dp, const gum::VariableSet &onto)
const DiscreteVariable * variable(const std::string &name) const
DecisionTensor< GUM_SCALAR > operator*=(const DecisionTensor< GUM_SCALAR > &dp1)
static DecisionTensor< GUM_SCALAR > marginalization(const DecisionTensor< GUM_SCALAR > &dp, const std::vector< std::string > &ontonames)
Tensor< GUM_SCALAR > probPot
virtual std::string toString() const
bool operator!=(const DecisionTensor< GUM_SCALAR > &p) const
Base class for discrete random variable.
Class for assigning/browsing values to tuples of discrete variables.
bool end() const
Returns true if the Instantiation reached the end.
void inc()
Operator increment.
void setFirst()
Assign the first values to the tuple of the Instantiation.
Exception : the element we looked for cannot be found.
void insert(const Key &k)
Inserts a new element into the set.
Definition set_tpl.h:539
aGrUM's Tensor is a multi-dimensional array with tensor operators.
Definition tensor.h:85
const Tensor< GUM_SCALAR > & fillWith(const Tensor< GUM_SCALAR > &src) const
copy a Tensor data using name of variables and labels (not necessarily the same variables in the same...
Definition tensor_tpl.h:271
#define GUM_ERROR(type, msg)
Definition exceptions.h:72
gum is the global namespace for all aGrUM entities
Definition agrum.h:46
Set< const DiscreteVariable * > VariableSet
std::ostream & operator<<(std::ostream &stream, const AVLTree< Val, Cmp > &tree)
display the content of a tree
Definition AVLTree.h:913
STL namespace.
Header of the Tensor class.