aGrUM  0.20.2
a C++ library for (probabilistic) graphical models
BayesNetFragment.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 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  public IBayesNet< GUM_SCALAR >,
74  public gum::DiGraphListener {
75  private:
76  /// The referred BayesNet
78 
79  /// Mapping between the variable's id and their CPT specific to this
80  /// Fragment.
82 
83  public:
84  /// @name Constructors / Destructors
85  /// @{
86  BayesNetFragment() = delete;
87  BayesNetFragment(const BayesNetFragment< GUM_SCALAR >& fragment) = delete;
88  BayesNetFragment(BayesNetFragment< GUM_SCALAR >&& fragment) = delete;
89 
90  explicit BayesNetFragment(const IBayesNet< GUM_SCALAR >& bn);
91 
92  virtual ~BayesNetFragment();
93  /// @}
94 
95  /// @name signals
96  /// @{
97 
98  /// the action to take when a new node is inserted into the graph
99  /** @param src the object that sent the signal
100  * @param id the id of the new node inserted into the graph */
101  virtual void whenNodeAdded(const void* src, NodeId id) final;
102 
103  /// the action to take when a node has just been removed from the graph
104  /** @param src the object that sent the signal
105  * @param id the id of the node has just been removed from the graph */
106  virtual void whenNodeDeleted(const void* src, NodeId id) final;
107 
108  /// the action to take when a new arc is inserted into the graph
109  /** @param src the object that sent the signal
110  * @param from the id of tail of the new arc inserted into the graph
111  * @param to the id of head of the new arc inserted into the graph */
112  virtual void whenArcAdded(const void* src, NodeId from, NodeId to) final;
113 
114  /// the action to take when an arc has just been removed from the graph
115  /** @param src the object that sent the signal
116  * @param from the id of tail of the arc removed from the graph
117  * @param to the id of head of the arc removed from the graph */
118  virtual void whenArcDeleted(const void* src, NodeId from, NodeId to) final;
119  /// @}
120 
121  /// @name IBayesNet interface
122  /// @{
123 
124  /**
125  * Returns the CPT of a variable.
126  *
127  * @throw NotFound If no variable's id matches varId.
128  */
129  const Potential< GUM_SCALAR >& cpt(NodeId varId) const final;
130  const Potential< GUM_SCALAR >& cpt(const std::string& name) const {
131  return cpt(idFromName(name));
132  };
133 
134  /**
135  * Returns a constant reference to the VariableNodeMap of this BN
136  */
137  const VariableNodeMap& variableNodeMap() const final;
138 
139  /**
140  * Returns a constant reference over a variabe given it's node id.
141  *
142  * @throw NotFound If no variable's id matches varId.
143  */
144  virtual const DiscreteVariable& variable(NodeId id) const final;
145  virtual const DiscreteVariable& variable(const std::string& name) const final {
146  return variable(idFromName(name));
147  };
148 
149  /**
150  * Return id node from discrete var pointer.
151  *
152  * @throw NotFound If no variable matches var.
153  */
154  virtual NodeId nodeId(const DiscreteVariable& var) const final;
155 
156  /**
157  * Getter by name
158  *
159  * @throw NotFound if no such name exists in the graph.
160  */
161  virtual NodeId idFromName(const std::string& name) const final;
162 
163  /**
164  * Getter by name
165  *
166  * @throw NotFound if no such name exists in the graph.
167  */
168  virtual const DiscreteVariable&
169  variableFromName(const std::string& name) const final;
170 
171  /**
172  * creates a dot representing the whole referred BN hilighting the fragment.
173  * @return Returns a dot representation of this fragment
174  */
175  virtual std::string toDot() const final;
176 
177  /// @}
178 
179  /// @name API for Fragment
180  /// @{
181 
182  /**
183  * check if a certain NodeId exists in the fragment
184  */
185  bool isInstalledNode(NodeId id) const;
186  bool isInstalledNode(const std::string& name) const {
187  return isInstalledNode(idFromName(name));
188  };
189 
190  /**
191  * install a node referenced by its nodeId
192  *
193  * @throw NotFound if the node does not exist in the referred BN
194  * @warning nothing happens if the node is already installed
195  */
196  void installNode(NodeId id);
197  void installNode(const std::string& name) {
198  installNode(bn__.idFromName(name));
199  }
200 
201  /**
202  * install a node and all its ascendants
203  *
204  * @throw NotFound if the node does not exist in the referred BN
205  * @warning nothing happens if the node is already installed
206  */
207  void installAscendants(NodeId id);
208  void installAscendants(const std::string& name) {
209  installAscendants(bn__.idFromName(name));
210  }
211 
212  /**
213  * uninstall a node referenced by its nodeId
214  *
215  * @warning nothing happens if the node is not installed
216  */
217  void uninstallNode(NodeId id);
218  void uninstallNode(const std::string& name) {
219  uninstallNode(idFromName(name));
220  }
221 
222  /**
223  * install a local marginal BY COPY for a node into the fragment.
224  * This function will remove all the arcs from the parents to the node.
225  * @param id the nodeId
226  * @param pot the potential
227  * @throw NotFound if the id is not in the fragment
228  * @throw OperationNotAllowed if the potential is not compliant with the
229  *variable
230  *(or is not a marginal)
231  **/
232  void installMarginal(NodeId id, const Potential< GUM_SCALAR >& pot);
233  void installMarginal(const std::string& name,
234  const Potential< GUM_SCALAR >& pot) {
235  installMarginal(bn__.idFromName(name), pot);
236  }
237 
238  /**
239  * install a local cpt BY COPYfor a node into the fragment.
240  * This function will change the arcs from the parents to the node in order
241  *to be
242  * consistent with the new local potential.
243  * @param id the nodeId
244  * @param pot the potential to be copied
245  *
246  * @throw NotFound if the id is not in the fragment
247  * @throw OperationNotAllowed if the potential is not compliant with the
248  *variable or if a variable in the CPT is not a parent in the referred bn.
249  **/
250  void installCPT(NodeId id, const Potential< GUM_SCALAR >& pot);
251  void installCPT(const std::string& name, const Potential< GUM_SCALAR >& pot) {
252  installCPT(bn__.idFromName(name), pot);
253  };
254 
255  /**
256  * uninstall a local CPT.
257  *
258  * @warning Nothing happens if no local CPT for this nodeId or if the node
259  *is
260  *not installed.
261  */
262  void uninstallCPT(NodeId id);
263  void uninstallCPT(const std::string& name) { uninstallCPT(idFromName(name)); }
264 
265  /**
266  * returns true if the nodeId's (local or not) cpt is consistent with its
267  * parents
268  * in the fragment
269  * @throw NotFound if the id is not in the fragment
270  */
271  bool checkConsistency(NodeId id) const;
272  bool checkConsistency(const std::string& name) const {
273  return checkConsistency(idFromName(name));
274  }
275 
276  /**
277  * returns true if all nodes in the fragment are consistent
278  *
279  * @throws gum::OperatioNotAllowed if the fragment is not consistent.
280  */
281  bool checkConsistency() const;
282 
283  /// @}
284 
285 
286  /** create a brand new BayesNet from a fragment.
287  *
288  * @return the new BayesNet<GUM_SCALAR>
289  */
290  gum::BayesNet< GUM_SCALAR > toBN() const;
291 
292  using IBayesNet< GUM_SCALAR >::nodes;
293  using IBayesNet< GUM_SCALAR >::dag;
294 
295  protected:
296  // remove an arc
297  void uninstallArc_(NodeId from, NodeId to);
298 
299  // add an arc
300  void installArc_(NodeId from, NodeId to);
301 
302  // install a CPT BY COPY, create or delete arcs. Checks are made in public
303  // methods In particular, it is assumed that all the variables in the pot are
304  // in the fragment
305  void installCPT_(NodeId id, const Potential< GUM_SCALAR >& pot);
306 
307  /**
308  * uninstall a local CPT. Does nothing if no local CPT for this nodeId
309  * No check. No change in the topology. Checks are made in public methods.
310  */
311  void uninstallCPT_(NodeId id);
312  };
313 
314 
315 #ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
316  extern template class BayesNetFragment< double >;
317 #endif
318 
319 } // namespace gum
320 
321 #include <agrum/BN/BayesNetFragment_tpl.h>
322 
323 #endif // GUM_BAYES_NET_FRAGMENT_H
gum::BayesNet< GUM_SCALAR > toBN() const
create a brand new BayesNet from a fragment.
const IBayesNet< GUM_SCALAR > & bn__
The referred BayesNet.
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:669
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.
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
NodeProperty< const Potential< GUM_SCALAR > *> localCPTs__
Mapping between the variable&#39;s id and their CPT specific to this Fragment.
bool checkConsistency() const
returns true if all nodes in the fragment are consistent
BayesNetFragment(const BayesNetFragment< GUM_SCALAR > &fragment)=delete
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.