aGrUM  0.13.2
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 >
282  NodeId target, const std::vector< NodeId >& evs) {
283  const auto& vtarget = this->BN().variable(target);
284 
285  NodeSet soids(Size(evs.size()));
286  for (const auto& e : evs)
287  soids << e;
288  if (soids.contains(target)) {
290  "Target <" << vtarget.name() << "> (" << target
291  << ") can not be in evs (" << evs << ").");
292  }
293  auto condset = this->BN().minimalCondSet(target, soids);
294 
296  this->eraseAllTargets();
297  this->eraseAllEvidence();
298  res.add(this->BN().variable(target));
299  this->addTarget(target);
300  for (const auto& n : condset) {
301  res.add(this->BN().variable(n));
302  this->addEvidence(n, 0);
303  }
304 
305  Instantiation inst(res);
306  for (inst.setFirst(); !inst.end(); inst.incNotVar(vtarget)) {
307  // inferring
308  for (const auto& n : condset)
309  this->chgEvidence(n, inst.val(this->BN().variable(n)));
310  this->makeInference();
311  // populate res
312  for (inst.setFirstVar(vtarget); !inst.end(); inst.incVar(vtarget)) {
313  res.set(inst, this->posterior(target)[inst]);
314  }
315  inst.setFirstVar(vtarget); // remove inst.end() flag
316  }
317 
318  return res;
319  }
320 
321 
322  template < typename GUM_SCALAR >
324  const std::string& target, const std::vector< std::string >& evs) {
325  const auto& bn = this->BN();
326 
327  std::vector< NodeId > evsId;
328  evsId.reserve(evs.size());
329  std::transform(std::begin(evs),
330  std::end(evs),
331  std::back_inserter(evsId),
332  [&bn](const std::string& s) { return bn.idFromName(s); });
333 
334  return evidenceImpact(bn.idFromName(target), evsId);
335  }
336 
337 
338  template < typename GUM_SCALAR >
340  return __targeted_mode;
341  }
342  template < typename GUM_SCALAR >
344  if (!__targeted_mode) {
345  __targets.clear();
346  __targeted_mode = true;
347  }
348  }
349 } /* namespace gum */
void __setBayesNetDuringConstruction(const IBayesNet< GUM_SCALAR > *bn)
assigns a BN during the inference engine construction
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...
unsigned long Size
In aGrUM, hashed values are unsigned long int.
Definition: types.h:50
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 DAG & dag() const
Returns a constant reference to the dag of this Bayes Net.
Definition: DAGmodel_inl.h:61
virtual void eraseTarget(NodeId target) final
removes an existing (marginal) target
unsigned int NodeId
Type for node ids.
Definition: graphElements.h:97
const NodeProperty< const Potential< GUM_SCALAR > * > & evidence() const
returns the set of evidence
virtual void _onMarginalTargetAdded(NodeId id)=0
fired after a new marginal target is inserted
Potential< GUM_SCALAR > evidenceImpact(NodeId target, const std::vector< NodeId > &evs)
Create a gum::Potential for P(target|evs) (for all instanciation of target and evs) ...
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:656
<agrum/BN/inference/marginalTargetedInference.h>
bool contains(const Key &k) const
Indicates whether a given elements belong to the set.
Definition: set_tpl.h:581
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
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 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.
bool end() const
Returns true if the Instantiation reached the end.
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 add(const DiscreteVariable &v) final
Adds a new var to the variables of the multidimensional matrix.
virtual const NodeSet & targets() const noexceptfinal
returns the list of marginal targets
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 void eraseAllTargets()
Clear all previously defined targets.
void clear()
Removes all the elements, if any, from the set.
Definition: set_tpl.h:375
Size size() const noexcept
Returns the number of elements in the set.
Definition: set_tpl.h:701
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.
virtual bool isDone() const noexceptfinal
returns whether the inference object is in a done state
void insert(const Key &k)
Inserts a new element into the set.
Definition: set_tpl.h:613
Idx val(Idx i) const
Returns the current value of the variable at position i.
virtual const Size nbrTargets() const noexceptfinal
returns the number of marginal targets
#define GUM_ERROR(type, msg)
Definition: exceptions.h:66
MarginalTargetedInference(const IBayesNet< GUM_SCALAR > *bn)
default constructor
virtual void _onMarginalTargetErased(NodeId id)=0
fired before a marginal target is removed