aGrUM  0.20.3
a C++ library for (probabilistic) graphical models
BayesNetFragment.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 Class representing Fragment of Bayesian networks
25  *
26  * @author Pierre-Henri WUILLEMIN(@LIP6) & Christophe GONZALES(@AMU)
27  *
28  */
29 #ifndef GUM_BAYES_NET_FRAGMENT_H
30 #define GUM_BAYES_NET_FRAGMENT_H
31 
32 #include <agrum/agrum.h>
33 
34 #include <agrum/BN/IBayesNet.h>
35 #include <agrum/tools/graphs/parts/listeners/diGraphListener.h>
36 
37 #include <agrum/BN/BayesNet.h>
38 
39 namespace gum {
40  /**
41  * @class BayesNetFragment
42  * @headerfile BayesNetFragment.h <agrum/BN/BayesNetFragment.h>
43  * @brief Portion of a BN identified by the list of nodes and a BayesNet.
44  * @ingroup bn_group
45  *
46  * @author Pierre-Henri WUILLEMIN(@LIP6)
47  *
48  * This class is a decorator of a BayesNet implementing the IBayesNet
49  * interface. CPTs can be shared with the BN or can be specific to the
50  * Fragment if different.
51  *
52  * BayesNetFragment is a DiGraphListener in order to be synchronized
53  * (especially when removing nodes or arcs).
54  *
55  * In a BayesNetFragment, one can install or remove nodes. An arc can be in
56  * the fragment if and only if its head and tail are installed in the
57  * fragment. *When installing a node, all the arcs that can be added in the
58  * fragment are *effectively installed (resp. *when uninstalling a node,
59  * etc.).
60  *
61  * A BayesNetFragment can redefine potential for node. The main reason is to
62  * be able to install a node without installing all its parents (and its
63  * ascendants). So local CPT to the node can be installed. However, it is not
64  * done automatically.
65  *
66  * If a cpt is not locally defined, the fragment uses the cpt defined in the
67  * referred BN. The checkConsistency() method verifies that, for all
68  * installed nodes, either all the parents are installed or a local CPT is
69  * defined.
70  */
71  template < typename GUM_SCALAR >
73  private:
74  /// The referred BayesNet
76 
77  /// Mapping between the variable's id and their CPT specific to this
78  /// Fragment.
80 
81  public:
82  /// @name Constructors / Destructors
83  /// @{
84  BayesNetFragment() = delete;
85  BayesNetFragment(const BayesNetFragment< GUM_SCALAR >& fragment) = delete;
86  BayesNetFragment(BayesNetFragment< GUM_SCALAR >&& fragment) = delete;
87 
88  explicit BayesNetFragment(const IBayesNet< GUM_SCALAR >& bn);
89 
90  virtual ~BayesNetFragment();
91  /// @}
92 
93  /// @name signals
94  /// @{
95 
96  /// the action to take when a new node is inserted into the graph
97  /** @param src the object that sent the signal
98  * @param id the id of the new node inserted into the graph */
99  virtual void whenNodeAdded(const void* src, NodeId id) final;
100 
101  /// the action to take when a node has just been removed from the graph
102  /** @param src the object that sent the signal
103  * @param id the id of the node has just been removed from the graph */
104  virtual void whenNodeDeleted(const void* src, NodeId id) final;
105 
106  /// the action to take when a new arc is inserted into the graph
107  /** @param src the object that sent the signal
108  * @param from the id of tail of the new arc inserted into the graph
109  * @param to the id of head of the new arc inserted into the graph */
110  virtual void whenArcAdded(const void* src, NodeId from, NodeId to) final;
111 
112  /// the action to take when an arc has just been removed from the graph
113  /** @param src the object that sent the signal
114  * @param from the id of tail of the arc removed from the graph
115  * @param to the id of head of the arc removed from the graph */
116  virtual void whenArcDeleted(const void* src, NodeId from, NodeId to) final;
117  /// @}
118 
119  /// @name IBayesNet interface
120  /// @{
121 
122  /**
123  * Returns the CPT of a variable.
124  *
125  * @throw NotFound If no variable's id matches varId.
126  */
127  const Potential< GUM_SCALAR >& cpt(NodeId varId) const final;
128  const Potential< GUM_SCALAR >& cpt(const std::string& name) const {
129  return cpt(idFromName(name));
130  };
131 
132  /**
133  * Returns a constant reference to the VariableNodeMap of this BN
134  */
135  const VariableNodeMap& variableNodeMap() const final;
136 
137  /**
138  * Returns a constant reference over a variabe given it's node id.
139  *
140  * @throw NotFound If no variable's id matches varId.
141  */
142  virtual const DiscreteVariable& variable(NodeId id) const final;
143  virtual const DiscreteVariable& variable(const std::string& name) const final {
144  return variable(idFromName(name));
145  };
146 
147  /**
148  * Return id node from discrete var pointer.
149  *
150  * @throw NotFound If no variable matches var.
151  */
152  virtual NodeId nodeId(const DiscreteVariable& var) const final;
153 
154  /**
155  * Getter by name
156  *
157  * @throw NotFound if no such name exists in the graph.
158  */
159  virtual NodeId idFromName(const std::string& name) const final;
160 
161  /**
162  * Getter by name
163  *
164  * @throw NotFound if no such name exists in the graph.
165  */
166  virtual const DiscreteVariable& variableFromName(const std::string& name) const final;
167 
168  /**
169  * creates a dot representing the whole referred BN hilighting the fragment.
170  * @return Returns a dot representation of this fragment
171  */
172  virtual std::string toDot() const final;
173 
174  /// @}
175 
176  /// @name API for Fragment
177  /// @{
178 
179  /**
180  * check if a certain NodeId exists in the fragment
181  */
182  bool isInstalledNode(NodeId id) const;
183  bool isInstalledNode(const std::string& name) const {
184  return isInstalledNode(idFromName(name));
185  };
186 
187  /**
188  * install a node referenced by its nodeId
189  *
190  * @throw NotFound if the node does not exist in the referred BN
191  * @warning nothing happens if the node is already installed
192  */
193  void installNode(NodeId id);
194  void installNode(const std::string& name) { installNode(_bn_.idFromName(name)); }
195 
196  /**
197  * install a node and all its ascendants
198  *
199  * @throw NotFound if the node does not exist in the referred BN
200  * @warning nothing happens if the node is already installed
201  */
202  void installAscendants(NodeId id);
203  void installAscendants(const std::string& name) { installAscendants(_bn_.idFromName(name)); }
204 
205  /**
206  * uninstall a node referenced by its nodeId
207  *
208  * @warning nothing happens if the node is not installed
209  */
210  void uninstallNode(NodeId id);
211  void uninstallNode(const std::string& name) { uninstallNode(idFromName(name)); }
212 
213  /**
214  * install a local marginal BY COPY for a node into the fragment.
215  * This function will remove all the arcs from the parents to the node.
216  * @param id the nodeId
217  * @param pot the potential
218  * @throw NotFound if the id is not in the fragment
219  * @throw OperationNotAllowed if the potential is not compliant with the
220  *variable
221  *(or is not a marginal)
222  **/
223  void installMarginal(NodeId id, const Potential< GUM_SCALAR >& pot);
224  void installMarginal(const std::string& name, const Potential< GUM_SCALAR >& pot) {
225  installMarginal(_bn_.idFromName(name), pot);
226  }
227 
228  /**
229  * install a local cpt BY COPYfor a node into the fragment.
230  * This function will change the arcs from the parents to the node in order
231  *to be
232  * consistent with the new local potential.
233  * @param id the nodeId
234  * @param pot the potential to be copied
235  *
236  * @throw NotFound if the id is not in the fragment
237  * @throw OperationNotAllowed if the potential is not compliant with the
238  *variable or if a variable in the CPT is not a parent in the referred bn.
239  **/
240  void installCPT(NodeId id, const Potential< GUM_SCALAR >& pot);
241  void installCPT(const std::string& name, const Potential< GUM_SCALAR >& pot) {
242  installCPT(_bn_.idFromName(name), pot);
243  };
244 
245  /**
246  * uninstall a local CPT.
247  *
248  * @warning Nothing happens if no local CPT for this nodeId or if the node
249  *is
250  *not installed.
251  */
252  void uninstallCPT(NodeId id);
253  void uninstallCPT(const std::string& name) { uninstallCPT(idFromName(name)); }
254 
255  /**
256  * returns true if the nodeId's (local or not) cpt is consistent with its
257  * parents
258  * in the fragment
259  * @throw NotFound if the id is not in the fragment
260  */
261  bool checkConsistency(NodeId id) const;
262  bool checkConsistency(const std::string& name) const {
263  return checkConsistency(idFromName(name));
264  }
265 
266  /**
267  * returns true if all nodes in the fragment are consistent
268  *
269  * @throws gum::OperatioNotAllowed if the fragment is not consistent.
270  */
271  bool checkConsistency() const;
272 
273  /// @}
274 
275 
276  /** create a brand new BayesNet from a fragment.
277  *
278  * @return the new BayesNet<GUM_SCALAR>
279  */
280  gum::BayesNet< GUM_SCALAR > toBN() const;
281 
282  using IBayesNet< GUM_SCALAR >::nodes;
283  using IBayesNet< GUM_SCALAR >::dag;
284 
285  protected:
286  // remove an arc
287  void uninstallArc_(NodeId from, NodeId to);
288 
289  // add an arc
290  void installArc_(NodeId from, NodeId to);
291 
292  // install a CPT BY COPY, create or delete arcs. Checks are made in public
293  // methods In particular, it is assumed that all the variables in the pot are
294  // in the fragment
295  void installCPT_(NodeId id, const Potential< GUM_SCALAR >& pot);
296 
297  /**
298  * uninstall a local CPT. Does nothing if no local CPT for this nodeId
299  * No check. No change in the topology. Checks are made in public methods.
300  */
301  void uninstallCPT_(NodeId id);
302  };
303 
304 
305 #ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
306  extern template class BayesNetFragment< double >;
307 #endif
308 
309 } // namespace gum
310 
311 #include <agrum/BN/BayesNetFragment_tpl.h>
312 
313 #endif // GUM_BAYES_NET_FRAGMENT_H
gum::BayesNet< GUM_SCALAR > toBN() const
create a brand new BayesNet from a fragment.
void uninstallArc_(NodeId from, NodeId to)
void installCPT(NodeId id, const Potential< GUM_SCALAR > &pot)
install a local cpt BY COPYfor a node into the fragment.
void uninstallCPT_(NodeId id)
uninstall a local CPT.
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:643
virtual void whenNodeDeleted(const void *src, NodeId id) final
the action to take when a node has just been removed from the graph
void installNode(const std::string &name)
check if a certain NodeId exists in the fragment
virtual NodeId nodeId(const DiscreteVariable &var) const final
Return id node from discrete var pointer.
void uninstallNode(NodeId id)
uninstall a node referenced by its nodeId
virtual const DiscreteVariable & variable(const std::string &name) const final
Returns the CPT of a variable.
void installCPT_(NodeId id, const Potential< GUM_SCALAR > &pot)
bool checkConsistency(const std::string &name) const
check if a certain NodeId exists in the fragment
virtual const DiscreteVariable & variable(NodeId id) const final
Returns a constant reference over a variabe given it&#39;s node id.
void installAscendants(NodeId id)
install a node and all its ascendants
virtual void whenNodeAdded(const void *src, NodeId id) final
the action to take when a new node is inserted into the graph
BayesNetFragment(BayesNetFragment< GUM_SCALAR > &&fragment)=delete
void installMarginal(NodeId id, const Potential< GUM_SCALAR > &pot)
install a local marginal BY COPY for a node into the fragment.
const VariableNodeMap & variableNodeMap() const final
Returns a constant reference to the VariableNodeMap of this BN.
virtual void whenArcAdded(const void *src, NodeId from, NodeId to) final
the action to take when a new arc is inserted into the graph
bool checkConsistency(NodeId id) const
returns true if the nodeId&#39;s (local or not) cpt is consistent with its parents in the fragment ...
virtual const DiscreteVariable & variableFromName(const std::string &name) const final
Getter by name.
const IBayesNet< GUM_SCALAR > & _bn_
The referred BayesNet.
virtual NodeId idFromName(const std::string &name) const final
Getter by name.
Portion of a BN identified by the list of nodes and a BayesNet.
void installAscendants(const std::string &name)
check if a certain NodeId exists in the fragment
void installNode(NodeId id)
install a node referenced by its nodeId
void installArc_(NodeId from, NodeId to)
bool isInstalledNode(NodeId id) const
check if a certain NodeId exists in the fragment
const Potential< GUM_SCALAR > & cpt(NodeId varId) const final
Returns the CPT of a variable.
void installMarginal(const std::string &name, const Potential< GUM_SCALAR > &pot)
check if a certain NodeId exists in the fragment
bool checkConsistency() const
returns true if all nodes in the fragment are consistent
BayesNetFragment(const BayesNetFragment< GUM_SCALAR > &fragment)=delete
NodeProperty< const Potential< GUM_SCALAR > *> _localCPTs_
Mapping between the variable&#39;s id and their CPT specific to this Fragment.
bool isInstalledNode(const std::string &name) const
check if a certain NodeId exists in the fragment
void installCPT(const std::string &name, const Potential< GUM_SCALAR > &pot)
check if a certain NodeId exists in the fragment
void uninstallNode(const std::string &name)
check if a certain NodeId exists in the fragment
void uninstallCPT(const std::string &name)
check if a certain NodeId exists in the fragment
void uninstallCPT(NodeId id)
uninstall a local CPT.
virtual void whenArcDeleted(const void *src, NodeId from, NodeId to) final
the action to take when an arc has just been removed from the graph
BayesNetFragment(const IBayesNet< GUM_SCALAR > &bn)
const Potential< GUM_SCALAR > & cpt(const std::string &name) const
Returns the CPT of a variable.
virtual std::string toDot() const final
creates a dot representing the whole referred BN hilighting the fragment.