aGrUM  0.14.1
marginalTargetedInference_tpl.h
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2005 by Pierre-Henri WUILLEMIN et Christophe GONZALES *
3  * {prenom.nom}_at_lip6.fr *
4  * *
5  * This program is free software; you can redistribute it and/or modify *
6  * it under the terms of the GNU General Public License as published by *
7  * the Free Software Foundation; either version 2 of the License, or *
8  * (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public License *
16  * along with this program; if not, write to the *
17  * Free Software Foundation, Inc., *
18  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19  ***************************************************************************/
25 #include <iterator>
26 
27 namespace gum {
28 
29 
30  // Default Constructor
31  template < typename GUM_SCALAR >
33  const IBayesNet< GUM_SCALAR >* bn) :
34  BayesNetInference< GUM_SCALAR >(bn) {
35  // assign a BN if this has not been done before (due to virtual inheritance)
36  if (this->__bn == nullptr) {
38  }
39 
40  // sets all the nodes as targets
41  if (bn != nullptr) {
42  __targeted_mode = false;
43  __targets = bn->dag().asNodeSet();
44  }
45 
46  GUM_CONSTRUCTOR(MarginalTargetedInference);
47  }
48 
49 
50  // Destructor
51  template < typename GUM_SCALAR >
53  GUM_DESTRUCTOR(MarginalTargetedInference);
54  }
55 
56 
57  // fired when a new BN is assigned to the inference engine
58  template < typename GUM_SCALAR >
60  const IBayesNet< GUM_SCALAR >* bn) {
61  __targeted_mode = true;
63  }
64 
65 
66  // ##############################################################################
67  // Targets
68  // ##############################################################################
69 
70  // return true if variable is a target
71  template < typename GUM_SCALAR >
72  INLINE bool
74  // check that the variable belongs to the bn
75  if (this->__bn == nullptr)
77  "No Bayes net has been assigned to the "
78  "inference algorithm");
79  if (!this->__bn->dag().exists(node)) {
80  GUM_ERROR(UndefinedElement, node << " is not a NodeId in the bn");
81  }
82 
83  return __targets.contains(node);
84  }
85 
86  // Add a single target to the list of targets
87  template < typename GUM_SCALAR >
89  const std::string& nodeName) const {
90  return isTarget(this->__bn->idFromName(nodeName));
91  }
92 
93 
94  // Clear all previously defined targets (single targets and sets of targets)
95  template < typename GUM_SCALAR >
98 
99  __targets.clear();
100  _setTargetedMode(); // does nothing if already in targeted mode
101 
102  this->__setState(
104  }
105 
106 
107  // Add a single target to the list of targets
108  template < typename GUM_SCALAR >
110  // check if the node belongs to the Bayesian network
111  if (this->__bn == nullptr)
113  "No Bayes net has been assigned to the "
114  "inference algorithm");
115 
116  if (!this->__bn->dag().exists(target)) {
117  GUM_ERROR(UndefinedElement, target << " is not a NodeId in the bn");
118  }
119 
120  _setTargetedMode(); // does nothing if already in targeted mode
121  // add the new target
122  if (!__targets.contains(target)) {
123  __targets.insert(target);
124  _onMarginalTargetAdded(target);
125  this->__setState(
127  }
128  }
129 
130 
131  // Add all nodes as targets
132  template < typename GUM_SCALAR >
134  // check if the node belongs to the Bayesian network
135  if (this->__bn == nullptr)
137  "No Bayes net has been assigned to the "
138  "inference algorithm");
139 
140 
141  _setTargetedMode(); // does nothing if already in targeted mode
142  for (const auto target : this->__bn->dag()) {
143  if (!__targets.contains(target)) {
144  __targets.insert(target);
145  _onMarginalTargetAdded(target);
146  this->__setState(
148  }
149  }
150  }
151 
152 
153  // Add a single target to the list of targets
154  template < typename GUM_SCALAR >
156  const std::string& nodeName) {
157  // check if the node belongs to the Bayesian network
158  if (this->__bn == nullptr)
160  "No Bayes net has been assigned to the "
161  "inference algorithm");
162 
163  addTarget(this->__bn->idFromName(nodeName));
164  }
165 
166 
167  // removes an existing target
168  template < typename GUM_SCALAR >
170  // check if the node belongs to the Bayesian network
171  if (this->__bn == nullptr)
173  "No Bayes net has been assigned to the "
174  "inference algorithm");
175 
176  if (!this->__bn->dag().exists(target)) {
177  GUM_ERROR(UndefinedElement, target << " is not a NodeId in the bn");
178  }
179 
180 
181  if (__targets.contains(target)) {
182  __targeted_mode = true; // we do not use _setTargetedMode because we do not
183  // want to clear the targets
184  _onMarginalTargetErased(target);
185  __targets.erase(target);
186  this->__setState(
188  }
189  }
190 
191 
192  // Add a single target to the list of targets
193  template < typename GUM_SCALAR >
195  const std::string& nodeName) {
196  // check if the node belongs to the Bayesian network
197  if (this->__bn == nullptr)
199  "No Bayes net has been assigned to the "
200  "inference algorithm");
201 
202  eraseTarget(this->__bn->idFromName(nodeName));
203  }
204 
205 
206  // returns the list of single targets
207  template < typename GUM_SCALAR >
209  noexcept {
210  return __targets;
211  }
212 
213  // returns the list of single targets
214  template < typename GUM_SCALAR >
216  noexcept {
217  return __targets.size();
218  }
219 
220 
222  template < typename GUM_SCALAR >
224  __targets.clear();
225  if (this->__bn != nullptr) {
226  __targets = this->__bn->dag().asNodeSet();
228  }
229  }
230 
231 
232  // ##############################################################################
233  // Inference
234  // ##############################################################################
235 
236  // Compute the posterior of a node.
237  template < typename GUM_SCALAR >
240  if (this->hardEvidenceNodes().contains(node)) {
241  return *(this->evidence()[node]);
242  }
243 
244  if (!isTarget(node)) {
245  // throws UndefinedElement if var is not a target
246  GUM_ERROR(UndefinedElement, node << " is not a target node");
247  }
248 
249  if (!this->isDone()) { this->makeInference(); }
250 
251  return _posterior(node);
252  }
253 
254  // Compute the posterior of a node.
255  template < typename GUM_SCALAR >
258  const std::string& nodeName) {
259  return posterior(this->BN().idFromName(nodeName));
260  }
261 
262  /* Entropy
263  * Compute Shanon's entropy of a node given the observation
264  */
265  template < typename GUM_SCALAR >
267  return posterior(X).entropy();
268  }
269 
270  /* Entropy
271  * Compute Shanon's entropy of a node given the observation
272  */
273  template < typename GUM_SCALAR >
274  INLINE GUM_SCALAR
275  MarginalTargetedInference< GUM_SCALAR >::H(const std::string& nodeName) {
276  return H(this->BN().idFromName(nodeName));
277  }
278 
279 
280  template < typename GUM_SCALAR >
283  const NodeSet& evs) {
284  const auto& vtarget = this->BN().variable(target);
285 
286  if (evs.contains(target)) {
288  "Target <" << vtarget.name() << "> (" << target
289  << ") can not be in evs (" << evs << ").");
290  }
291  auto condset = this->BN().minimalCondSet(target, evs);
292 
294  this->eraseAllTargets();
295  this->eraseAllEvidence();
296  res.add(this->BN().variable(target));
297  this->addTarget(target);
298  for (const auto& n : condset) {
299  res.add(this->BN().variable(n));
300  this->addEvidence(n, 0);
301  }
302 
303  Instantiation inst(res);
304  for (inst.setFirst(); !inst.end(); inst.incNotVar(vtarget)) {
305  // inferring
306  for (const auto& n : condset)
307  this->chgEvidence(n, inst.val(this->BN().variable(n)));
308  this->makeInference();
309  // populate res
310  for (inst.setFirstVar(vtarget); !inst.end(); inst.incVar(vtarget)) {
311  res.set(inst, this->posterior(target)[inst]);
312  }
313  inst.setFirstVar(vtarget); // remove inst.end() flag
314  }
315 
316  return res;
317  }
318 
319 
320  template < typename GUM_SCALAR >
322  const std::string& target, const std::vector< std::string >& evs) {
323  const auto& bn = this->BN();
324 
325  gum::NodeSet evsId;
326  for (const auto& evname : evs) {
327  evsId.insert(bn.idFromName(evname));
328  }
329 
330  return evidenceImpact(bn.idFromName(target), evsId);
331  }
332 
333 
334  template < typename GUM_SCALAR >
336  return __targeted_mode;
337  }
338  template < typename GUM_SCALAR >
340  if (!__targeted_mode) {
341  __targets.clear();
342  __targeted_mode = true;
343  }
344  }
345 } /* namespace gum */
void __setBayesNetDuringConstruction(const IBayesNet< GUM_SCALAR > *bn)
assigns a BN during the inference engine construction
bool contains(const Key &k) const
Indicates whether a given elements belong to the set.
Definition: set_tpl.h:578
aGrUM&#39;s Potential is a multi-dimensional array with tensor operators.
Definition: potential.h:57
virtual void __setState(const StateOfInference state) final
set the state of the inference engine and call the notification _onStateChanged when necessary (i...
virtual void _onBayesNetChanged(const IBayesNet< GUM_SCALAR > *bn)
fired after a new Bayes net has been assigned to the engine
virtual GUM_SCALAR H(NodeId X) final
Entropy Compute Shanon&#39;s entropy of a node given the observation.
NodeSet __targets
the set of marginal targets
const NodeProperty< const Potential< GUM_SCALAR > *> & evidence() const
returns the set of evidence
virtual void eraseTarget(NodeId target) final
removes an existing (marginal) target
virtual void _onMarginalTargetAdded(const NodeId id)=0
fired after a new marginal target is inserted
virtual const Size nbrTargets() const noexcept final
returns the number of marginal targets
const IBayesNet< GUM_SCALAR > * __bn
the Bayes net on which we perform inferences
virtual bool isTarget(NodeId node) const final
return true if variable is a (marginal) target
void erase(const Key &k)
Erases an element from the set.
Definition: set_tpl.h:653
<agrum/BN/inference/marginalTargetedInference.h>
void incNotVar(const DiscreteVariable &v)
Operator increment for vars which are not v.
Class representing the minimal interface for Bayesian Network.
Definition: IBayesNet.h:59
gum is the global namespace for all aGrUM entities
Definition: agrum.h:25
void incVar(const DiscreteVariable &v)
Operator increment for variable v only.
virtual void _onAllMarginalTargetsErased()=0
fired before a all marginal targets are removed
Idx val(Idx i) const
Returns the current value of the variable at position i.
virtual void makeInference() final
perform the heavy computations needed to compute the targets&#39; posteriors
virtual void addTarget(NodeId target) final
Add a marginal target to the list of targets.
void __setAllMarginalTargets()
sets all the nodes of the Bayes net as targets
<agrum/BN/inference/BayesNetInference.h>
virtual void addAllTargets() final
adds all nodes as targets
void setFirstVar(const DiscreteVariable &v)
Assign the first value in the Instantiation for var v.
virtual void chgEvidence(NodeId id, const Idx val) final
change the value of an already existing hard evidence
virtual bool isDone() const noexcept final
returns whether the inference object is in a done state
virtual void addEvidence(NodeId id, const Idx val) final
adds a new hard evidence on node id
virtual void eraseAllEvidence() final
removes all the evidence entered into the network
virtual const Potential< GUM_SCALAR > & posterior(NodeId node)
Computes and returns the posterior of a node.
const NodeSet & hardEvidenceNodes() const
returns the set of nodes with hard evidence
Class for assigning/browsing values to tuples of discrete variables.
Definition: instantiation.h:80
virtual void _onMarginalTargetErased(const NodeId id)=0
fired before a marginal target is removed
virtual void add(const DiscreteVariable &v) final
Adds a new var to the variables of the multidimensional matrix.
Potential< GUM_SCALAR > evidenceImpact(NodeId target, const NodeSet &evs)
Create a gum::Potential for P(target|evs) (for all instanciation of target and evs) ...
virtual void _onAllMarginalTargetsAdded()=0
fired after all the nodes of the BN are added as marginal targets
virtual void set(const Instantiation &i, const GUM_SCALAR &value) const final
Default implementation of MultiDimContainer::set().
void setFirst()
Assign the first values to the tuple of the Instantiation.
virtual const Potential< GUM_SCALAR > & _posterior(NodeId id)=0
asks derived classes for the posterior of a given variable
virtual const NodeSet & targets() const noexcept final
returns the list of marginal targets
virtual void eraseAllTargets()
Clear all previously defined targets.
void clear()
Removes all the elements, if any, from the set.
Definition: set_tpl.h:372
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Definition: types.h:45
Size size() const noexcept
Returns the number of elements in the set.
Definition: set_tpl.h:698
bool __targeted_mode
whether the actual targets are default
virtual const IBayesNet< GUM_SCALAR > & BN() const final
Returns a constant reference over the IBayesNet referenced by this class.
const DAG & dag() const
Returns a constant reference to the dag of this Bayes Net.
Definition: DAGmodel_inl.h:60
Size NodeId
Type for node ids.
Definition: graphElements.h:97
void insert(const Key &k)
Inserts a new element into the set.
Definition: set_tpl.h:610
#define GUM_ERROR(type, msg)
Definition: exceptions.h:52
MarginalTargetedInference(const IBayesNet< GUM_SCALAR > *bn)
default constructor
bool end() const
Returns true if the Instantiation reached the end.