aGrUM  0.20.3
a C++ library for (probabilistic) graphical models
decisionPotential.h
Go to the documentation of this file.
1 /**
2  *
3  * Copyright (c) 2005-2021 by Pierre-Henri WUILLEMIN(@LIP6) & Christophe GONZALES(@AMU)
4  * info_at_agrum_dot_org
5  *
6  * This library is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this library. If not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 
22 /**
23  * @file
24  * @brief This file contains abstract class definitions influence diagrams
25  * inference classes.
26  *
27  * @author Pierre-Henri WUILLEMIN(@LIP6) and Christophe Gonzalez(@
28  */
29 #ifndef AGRUM_DECISIONPOTENTIAL_H
30 #define AGRUM_DECISIONPOTENTIAL_H
31 
32 #include <agrum/tools/core/set.h>
33 #include <agrum/tools/variables/discreteVariable.h>
34 #include <agrum/tools/multidim/instantiation.h>
35 #include <agrum/tools/multidim/potential.h>
36 
37 namespace gum {
38  /**
39  * @class DecisionPotential decisionPotential.h
40  *<agrum/ID/inference/decisionPotential.h>
41  * @brief Potential for optimization in LIMIDS (such as Single Policy Update)
42  */
43  template < typename GUM_SCALAR >
45  public:
48 
49  explicit DecisionPotential() {
50  GUM_CONSTRUCTOR(DecisionPotential);
51  probPot.fillWith(GUM_SCALAR(1));
52  utilPot.fillWith(GUM_SCALAR(0));
53  }
54 
56  GUM_DESTRUCTOR(DecisionPotential);
57  ;
58  }
59 
60  DecisionPotential(const Potential< GUM_SCALAR >& prob, const Potential< GUM_SCALAR >& util) :
62  GUM_CONSTRUCTOR(DecisionPotential);
63  }
64 
65  DecisionPotential(const DecisionPotential< GUM_SCALAR >& dp) :
67  GUM_CONS_CPY(DecisionPotential);
68  }
69 
70  void clear() {
71  gum::Potential< GUM_SCALAR > p;
72  p.fillWith(GUM_SCALAR(1));
73  probPot = p;
74  p.fillWith(GUM_SCALAR(0));
75  utilPot = p;
76  }
77 
78  DecisionPotential< GUM_SCALAR >& operator=(const DecisionPotential< GUM_SCALAR >& src) {
79  GUM_OP_CPY(DecisionPotential);
80  if (&src == this) return *this;
81  probPot = src.probPot;
82  utilPot = src.utilPot;
83  return *this;
84  }
85 
86  DecisionPotential(DecisionPotential< GUM_SCALAR >&& dp) :
89  GUM_CONS_MOV(DecisionPotential);
90  }
91 
92  DecisionPotential< GUM_SCALAR >& operator=(DecisionPotential< GUM_SCALAR >&& src) {
93  GUM_OP_MOV(DecisionPotential);
94  if (&src == this) return *this;
95  probPot = std::forward< Potential< GUM_SCALAR > >(src.probPot);
96  utilPot = std::forward< Potential< GUM_SCALAR > >(src.utilPot);
97  return *this;
98  }
99 
100  bool operator==(const DecisionPotential< GUM_SCALAR >& p) const {
101  // @see Evaluating Influence Diagrams using LIMIDS (2000) - section 3.3
102  return ((p.probPot == this->probPot)
103  && (p.probPot * p.utilPot == this->probPot * this->utilPot));
104  }
105 
106  bool operator!=(const DecisionPotential< GUM_SCALAR >& p) const { return !operator==(p); }
107 
108  const DiscreteVariable* variable(const std::string& name) const {
109  for (const auto& v: probPot.variablesSequence()) {
110  if (v->name() == name) return v;
111  }
112  for (const auto& v: utilPot.variablesSequence()) {
113  if (v->name() == name) return v;
114  }
115 
116  GUM_ERROR(NotFound, "'" << name << "' can not be found in DecisionPotential.")
117  }
118 
119  void insertProba(const gum::Potential< GUM_SCALAR >& proba) { probPot *= proba; }
120 
121  void insertUtility(const gum::Potential< GUM_SCALAR >& util) { utilPot += util; }
122 
123  DecisionPotential< GUM_SCALAR > operator*(const DecisionPotential< GUM_SCALAR >& dp1) const {
124  return DecisionPotential< GUM_SCALAR >::combination(*this, dp1);
125  }
126 
127  DecisionPotential< GUM_SCALAR > operator*=(const DecisionPotential< GUM_SCALAR >& dp1) {
128  *this = DecisionPotential< GUM_SCALAR >::combination(*this, dp1);
129  return *this;
130  }
131 
132  DecisionPotential< GUM_SCALAR > operator^(const Set< const DiscreteVariable* >& onto) const {
133  return DecisionPotential< GUM_SCALAR >::marginalization(*this, onto);
134  }
135 
136  DecisionPotential< GUM_SCALAR > operator^(const std::vector< std::string >& ontonames) const {
137  return DecisionPotential< GUM_SCALAR >::marginalization(*this, ontonames);
138  }
139 
140 
142  const Potential< GUM_SCALAR >& p2) {
143  Potential< GUM_SCALAR > res(p1);
144  Instantiation I(res);
145  for (I.setFirst(); !I.end(); I.inc()) {
146  if (res[I] != 0) res.set(I, res[I] / p2[I]);
147  }
148  return res;
149  }
150 
151  static DecisionPotential< GUM_SCALAR > combination(const DecisionPotential< GUM_SCALAR >& dp1,
152  const DecisionPotential< GUM_SCALAR >& dp2) {
153  return DecisionPotential< GUM_SCALAR >(dp1.probPot * dp2.probPot, dp1.utilPot + dp2.utilPot);
154  }
155 
156  static DecisionPotential< GUM_SCALAR >
157  marginalization(const DecisionPotential< GUM_SCALAR >& dp,
158  const Set< const DiscreteVariable* >& onto) {
159  const auto pr = dp.probPot.margSumIn(onto);
160  return DecisionPotential(pr, divideEvenZero((dp.probPot * dp.utilPot).margSumIn(onto), pr));
161  }
162 
163  static DecisionPotential< GUM_SCALAR >
164  marginalization(const DecisionPotential< GUM_SCALAR >& dp,
165  const std::vector< std::string >& ontonames) {
166  Set< const DiscreteVariable* > onto;
167  for (const auto& varname: ontonames) {
168  onto.insert(dp.variable(varname));
169  }
170  return marginalization(dp, onto);
171  }
172 
174  auto tmp = probPot * utilPot;
175  GUM_SCALAR s = probPot.sum();
176  double m = tmp.sum() / s;
177  double m2 = (tmp * utilPot).sum() / s;
178  return std::pair< GUM_SCALAR, GUM_SCALAR >(m, m2 - m * m);
179  }
180 
181  virtual std::string toString() const {
182  return "prob : " + probPot.toString() + " util:" + utilPot.toString();
183  }
184  };
185 
186  template < typename GUM_SCALAR >
188  out << array.toString();
189  return out;
190  }
191 } // namespace gum
192 
193 #endif // AGRUM_DECISIONPOTENTIAL_H
DecisionPotential< GUM_SCALAR > operator*(const DecisionPotential< GUM_SCALAR > &dp1) const
bool operator!=(const DecisionPotential< GUM_SCALAR > &p) const
static DecisionPotential< GUM_SCALAR > combination(const DecisionPotential< GUM_SCALAR > &dp1, const DecisionPotential< GUM_SCALAR > &dp2)
Potential< GUM_SCALAR > probPot
const DiscreteVariable * variable(const std::string &name) const
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:643
DecisionPotential< GUM_SCALAR > operator*=(const DecisionPotential< GUM_SCALAR > &dp1)
DecisionPotential(const Potential< GUM_SCALAR > &prob, const Potential< GUM_SCALAR > &util)
Potential< GUM_SCALAR > utilPot
DecisionPotential(DecisionPotential< GUM_SCALAR > &&dp)
DecisionPotential< GUM_SCALAR > & operator=(DecisionPotential< GUM_SCALAR > &&src)
<agrum/ID/inference/decisionPotential.h>
void insertUtility(const gum::Potential< GUM_SCALAR > &util)
virtual std::string toString() const
bool operator==(const DecisionPotential< GUM_SCALAR > &p) const
void insertProba(const gum::Potential< GUM_SCALAR > &proba)
DecisionPotential< GUM_SCALAR > & operator=(const DecisionPotential< GUM_SCALAR > &src)
std::pair< GUM_SCALAR, GUM_SCALAR > meanVar()
std::ostream & operator<<(std::ostream &out, const DecisionPotential< GUM_SCALAR > &array)
static DecisionPotential< GUM_SCALAR > marginalization(const DecisionPotential< GUM_SCALAR > &dp, const std::vector< std::string > &ontonames)
DecisionPotential< GUM_SCALAR > operator^(const std::vector< std::string > &ontonames) const
static Potential< GUM_SCALAR > divideEvenZero(const Potential< GUM_SCALAR > &p1, const Potential< GUM_SCALAR > &p2)
DecisionPotential(const DecisionPotential< GUM_SCALAR > &dp)