aGrUM  0.20.2
a C++ library for (probabilistic) graphical models
decisionPotential.h
Go to the documentation of this file.
1 /**
2  *
3  * Copyright 2005-2020 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 
55  ~DecisionPotential() { GUM_DESTRUCTOR(DecisionPotential); }
56 
57  DecisionPotential(const Potential< GUM_SCALAR >& prob,
58  const Potential< GUM_SCALAR >& util) :
59  probPot(prob),
60  utilPot(util) {
61  GUM_CONSTRUCTOR(DecisionPotential);
62  }
63 
64  DecisionPotential(const DecisionPotential< GUM_SCALAR >& dp) :
66  GUM_CONS_CPY(DecisionPotential);
67  }
68 
69  void clear() {
70  gum::Potential< GUM_SCALAR > p;
71  p.fillWith(GUM_SCALAR(1));
72  probPot = p;
73  p.fillWith(GUM_SCALAR(0));
74  utilPot = p;
75  }
76 
77  DecisionPotential< GUM_SCALAR >&
78  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 >&
93  operator=(DecisionPotential< GUM_SCALAR >&& src) {
94  GUM_OP_MOV(DecisionPotential);
95  if (&src == this) return *this;
96  probPot = std::forward< Potential< GUM_SCALAR > >(src.probPot);
97  utilPot = std::forward< Potential< GUM_SCALAR > >(src.utilPot);
98  return *this;
99  }
100 
101  bool operator==(const DecisionPotential< GUM_SCALAR >& p) const {
102  // @see Evaluating Influence Diagrams using LIMIDS (2000) - section 3.3
103  return ((p.probPot == this->probPot)
104  && (p.probPot * p.utilPot == this->probPot * this->utilPot));
105  }
106 
107  bool operator!=(const DecisionPotential< GUM_SCALAR >& p) const {
108  return !operator==(p);
109  }
110 
111  const DiscreteVariable* variable(const std::string& name) const {
112  for (const auto& v: probPot.variablesSequence()) {
113  if (v->name() == name) return v;
114  }
115  for (const auto& v: utilPot.variablesSequence()) {
116  if (v->name() == name) return v;
117  }
118 
119  GUM_ERROR(NotFound,
120  "'" << name << "' can not be found in DecisionPotential.")
121  }
122 
123  void insertProba(const gum::Potential< GUM_SCALAR >& proba) {
124  probPot *= proba;
125  }
126 
127  void insertUtility(const gum::Potential< GUM_SCALAR >& util) {
128  utilPot += util;
129  }
130 
131  DecisionPotential< GUM_SCALAR >
132  operator*(const DecisionPotential< GUM_SCALAR >& dp1) const {
133  return DecisionPotential< GUM_SCALAR >::combination(*this, dp1);
134  }
135 
136  DecisionPotential< GUM_SCALAR >
137  operator*=(const DecisionPotential< GUM_SCALAR >& dp1) {
138  *this = DecisionPotential< GUM_SCALAR >::combination(*this, dp1);
139  return *this;
140  }
141 
142  DecisionPotential< GUM_SCALAR >
143  operator^(const Set< const DiscreteVariable* >& onto) const {
144  return DecisionPotential< GUM_SCALAR >::marginalization(*this, onto);
145  }
146 
147  DecisionPotential< GUM_SCALAR >
148  operator^(const std::vector< std::string >& ontonames) const {
149  return DecisionPotential< GUM_SCALAR >::marginalization(*this, ontonames);
150  }
151 
152 
153  static Potential< GUM_SCALAR >
155  const Potential< GUM_SCALAR >& p2) {
156  Potential< GUM_SCALAR > res(p1);
157  Instantiation I(res);
158  for (I.setFirst(); !I.end(); I.inc()) {
159  if (res[I] != 0) res.set(I, res[I] / p2[I]);
160  }
161  return res;
162  }
163 
164  static DecisionPotential< GUM_SCALAR >
165  combination(const DecisionPotential< GUM_SCALAR >& dp1,
166  const DecisionPotential< GUM_SCALAR >& dp2) {
167  return DecisionPotential< GUM_SCALAR >(dp1.probPot * dp2.probPot,
168  dp1.utilPot + dp2.utilPot);
169  }
170 
171  static DecisionPotential< GUM_SCALAR >
172  marginalization(const DecisionPotential< GUM_SCALAR >& dp,
173  const Set< const DiscreteVariable* >& onto) {
174  const auto pr = dp.probPot.margSumIn(onto);
175  return DecisionPotential(
176  pr,
177  divideEvenZero((dp.probPot * dp.utilPot).margSumIn(onto), pr));
178  }
179 
180  static DecisionPotential< GUM_SCALAR >
181  marginalization(const DecisionPotential< GUM_SCALAR >& dp,
182  const std::vector< std::string >& ontonames) {
183  Set< const DiscreteVariable* > onto;
184  for (const auto& varname: ontonames) {
185  onto.insert(dp.variable(varname));
186  }
187  return marginalization(dp, onto);
188  }
189 
191  auto tmp = probPot * utilPot;
192  GUM_SCALAR s = probPot.sum();
193  double m = tmp.sum() / s;
194  double m2 = (tmp * utilPot).sum() / s;
195  return std::pair< GUM_SCALAR, GUM_SCALAR >(m, m2 - m * m);
196  }
197 
198  virtual std::string toString() const {
199  return "prob : " + probPot.toString() + " util:" + utilPot.toString();
200  }
201  };
202 
203  template < typename GUM_SCALAR >
205  const DecisionPotential< GUM_SCALAR >& array) {
206  out << array.toString();
207  return out;
208  }
209 } // namespace gum
210 
211 #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:669
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)