aGrUM  0.20.2
a C++ library for (probabilistic) graphical models
CNLoopyPropagation.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 implementing loopy-propagation with binary networks - L2U
25  * algorithm.
26  * @author Matthieu HOURBRACQ and Pierre-Henri WUILLEMIN(@LIP6)
27  */
28 
29 #ifndef __CN_LOOPY_PROPAGATION__H__
30 #define __CN_LOOPY_PROPAGATION__H__
31 
32 #include <cstdlib>
33 #include <ctime>
34 #include <limits>
35 
36 #include <agrum/CN/credalNet.h>
37 #include <agrum/CN/inference/inferenceEngine.h>
38 #include <agrum/tools/core/approximations/approximationScheme.h>
39 #include <agrum/tools/core/math/pow.h>
40 #include <agrum/tools/core/sequence.h>
41 
42 #define INF_ std::numeric_limits< GUM_SCALAR >::infinity()
43 
44 namespace gum {
45  namespace credal {
46 
47  /**
48  * @class CNLoopyPropagation CNLoopyPropagation.h
49  * <agrum/CN/CNLoopyPropagation.h>
50  * @ingroup cn_group
51  * @brief Class implementing loopy-propagation with binary networks - L2U
52  * algorithm.
53  * @tparam GUM_SCALAR A floating type ( float, double, long double ... ).
54  * @author Matthieu HOURBRACQ and Pierre-Henri WUILLEMIN(@LIP6)
55  */
56  template < typename GUM_SCALAR >
58  public:
59  using msg = std::vector< Potential< GUM_SCALAR >* >;
60  using cArcP = const Arc*;
61 
62  /**
63  * Inference type to be used by the algorithm.
64  */
65  enum class InferenceType : char
66  {
67  nodeToNeighbours, /**< Uses a node-set so we don't iterate on nodes that
68  can't send a new message. Should be the fastest
69  inference type. A step is going through the
70  node-set. */
71 
72  ordered, /**< Chooses an arc ordering and sends messages accordingly at
73  all
74  steps. Avoid it since it can give slightly worse results
75  than
76  other inference types. A step is going through all arcs. */
77 
78  randomOrder /**< Chooses a random arc ordering and sends messages
79  accordingly. A new order is set at each step. A step is
80  going
81  through all arcs. */
82  };
83 
84  /// @name Public algorithm methods
85  /// @{
86 
87  /** Starts the inference. */
88  void makeInference();
89 
90  /// @}
91 
92  /// @name Getters and setters
93  /// @{
94 
95  /**
96  * %Set the inference type.
97  * @param inft The choosen \c InferenceType.
98  */
99  void inferenceType(InferenceType inft);
100 
101  /**
102  * Get the inference type.
103  * @return The inference type.
104  */
106 
107  /// @}
108 
109  /// @name Post-inference methods
110  /// @{
111 
112  /**
113  * Erase all inference related data to perform another one. You need to
114  * insert
115  * evidence again if needed but modalities are kept. You can insert new
116  * ones by
117  * using the appropriate method which will delete the old ones.
118  */
119  void eraseAllEvidence();
120 
121  /**
122  * @deprecated
123  * Use saveMarginals() from InferenceEngine instead.
124  * This one is easier to read but harder for scripts to parse.
125  * @param path The path to the file to save marginals.
126  */
127  void saveInference(const std::string& path);
128 
129  /// @}
130 
131  /// @name Constructors / Destructors
132  /// @{
133  /**
134  * Constructor.
135  * @param cnet The CredalNet to be used with this algorithm.
136  */
137  explicit CNLoopyPropagation(const CredalNet< GUM_SCALAR >& cnet);
138  /** Destructor. */
139  virtual ~CNLoopyPropagation();
140  /// @}
141 
142  protected:
143  /// @name Protected initialization methods
144  /// @{
145 
146  /** Topological forward propagation to initialize old marginals &
147  * messages. */
148  void initialize_();
149 
150  /// @}
151 
152  /// @name Protected algorithm methods
153  /// @{
154  /** Starts the inference with this inference type. */
156  /** Starts the inference with this inference type. */
158  /** Starts the inference with this inference type. */
160 
161  /** Compute marginals from up-to-date messages. */
162  void updateMarginals_();
163 
164  /**
165  * Sends a message to one's parent, i.e. X is sending a message to a
166  * demanding_parent.
167  * @param X The constant node id of the node sending the message.
168  * @param demanding_parent The constant node id of the node receiving the
169  * message.
170  */
171  void msgL_(
172  const NodeId X,
173  const NodeId demanding_parent); // allways sent from X to demanding_X
174 
175  /**
176  * Used by msgL_. Compute the final message for the given parent's message
177  * and
178  * likelihood (children's messages), numerators & denominators.
179  * @param msg_l_min The reference to the current lower value of the
180  * message to
181  * be sent.
182  * @param msg_l_max The reference to the current upper value of the
183  * message to
184  * be sent.
185  * @param lx The lower and upper likelihood.
186  * @param num_min The reference to the previously computed lower
187  * numerator.
188  * @param num_max The reference to the previously computed upper
189  * numerator.
190  * @param den_min The reference to the previously computed lower
191  * denominator.
192  * @param den_max The reference to the previously computed upper
193  * denominator.
194  */
195  void compute_ext_(GUM_SCALAR& msg_l_min,
196  GUM_SCALAR& msg_l_max,
197  std::vector< GUM_SCALAR >& lx,
198  GUM_SCALAR& num_min,
199  GUM_SCALAR& num_max,
200  GUM_SCALAR& den_min,
201  GUM_SCALAR& den_max);
202 
203  /**
204  * Used by msgL_. Compute the numerators & denominators for the given
205  * parent's
206  * message and likelihood (children's messages). Marginalisation.
207  * @param combi_msg_p The parent's choosen message.
208  * @param id The constant id of the node sending the message.
209  * @param msg_l_min The reference to the current lower value of the
210  * message to
211  * be sent.
212  * @param msg_l_max The reference to the current upper value of the
213  * message to
214  * be sent.
215  * @param lx The lower and upper likelihood.
216  * @param pos The position of the parent node to receive the message in
217  * the CPT
218  * of the one sending the message ( first parent, second ... ).
219  */
221  const NodeId& id,
224  std::vector< GUM_SCALAR >& lx,
225  const Idx& pos);
226 
227  /**
228  * Used by msgL_. Enumerate parent's messages.
229  * @param msgs_p All the messages from the parents which will be
230  * enumerated.
231  * @param id The constant id of the node sending the message.
232  * @param msg_l_min The reference to the current lower value of the
233  * message to
234  * be sent.
235  * @param msg_l_max The reference to the current upper value of the
236  * message to
237  * be sent.
238  * @param lx The lower and upper likelihood.
239  * @param pos The position of the parent node to receive the message in
240  * the CPT
241  * of the one sending the message ( first parent, second ... ).
242  */
243  void enum_combi_(
245  const NodeId& id,
248  std::vector< GUM_SCALAR >& lx,
249  const Idx& pos);
250 
251  /**
252  * Sends a message to one's child, i.e. X is sending a message to a
253  * demanding_child.
254  * @param X The constant node id of the node sending the message.
255  * @param demanding_child The constant node id of the node receiving the
256  * message.
257  */
258  void msgP_(const NodeId X, const NodeId demanding_child);
259 
260  /**
261  * Used by msgP_. Enumerate parent's messages.
262  * @param msgs_p All the messages from the parents which will be
263  * enumerated.
264  * @param id The constant id of the node sending the message.
265  * @param msg_p_min The reference to the current lower value of the
266  * message to
267  * be sent.
268  * @param msg_p_max The reference to the current upper value of the
269  * message to
270  * be sent.
271  */
272  void enum_combi_(
274  const NodeId& id,
277 
278  /**
279  * Used by msgP_. Marginalisation.
280  * @param combi_msg_p The parent's choosen message.
281  * @param id The constant id of the node sending the message.
282  * @param msg_p_min The reference to the current lower value of the
283  * message to
284  * be sent.
285  * @param msg_p_max The reference to the current upper value of the
286  * message to
287  * be sent.
288  */
290  const NodeId& id,
293 
294  /** Get the last messages from one's parents and children. */
295  void refreshLMsPIs_(bool refreshIndic = false);
296 
297  /**
298  * Compute epsilon.
299  * @return Epsilon.
300  */
301  GUM_SCALAR calculateEpsilon_();
302 
303  /// @}
304 
305  /// @name Post-inference protected methods
306  /// @{
307 
308  /** Since the network is binary, expectations can be computed from the
309  * final
310  * marginals which give us the credal set vertices. */
311  void computeExpectations_();
312 
313  /** @brief Only update indicatrices variables at the end of computations (
314  * calls msgP_ ). */
315  void updateIndicatrices_();
316 
317  /// @}
318 
319  /** Used to keep track of which node needs to update it's information
320  * coming
321  * from it's parents. */
323  /** Used to keep track of which node needs to update it's information
324  * coming
325  * from it's children. */
327 
328  /** The current node-set to iterate through at this current step. */
330  /** The next node-set, i.e. the nodes that will send messages at the next
331  * step.
332  */
334 
335  /** Used to keep track of one's messages sent to it's parents. */
337 
338  /** "Lower" information \f$ \Lambda \f$ coming from one's children. */
340  /** "Lower" information \f$ \pi \f$ coming from one's parent. */
342  /** "Lower" node information \f$ \Lambda \f$ obtained by combinaison of
343  * children messages. */
345  /** "Lower" node information \f$ \pi \f$ obtained by combinaison of
346  * parent's
347  * messages. */
349 
350  /** "Upper" information \f$ \Lambda \f$ coming from one's children. */
352  /** "Upper" information \f$ \pi \f$ coming from one's parent. */
354  /** "Upper" node information \f$ \Lambda \f$ obtained by combinaison of
355  * children messages. */
357  /** "Upper" node information \f$ \pi \f$ obtained by combinaison of
358  * parent's
359  * messages. */
361 
362  /** \c TRUE if inference has already been performed, \c FALSE otherwise.
363  */
365 
366  private:
367  /** To easily access InferenceEngine< GUM_SCALAR > methods. */
369 
370  /** The choosen inference type. nodeToNeighbours by Default. */
372 
373  /** A pointer to the CredalNet to be used. */
375 
376  /** A pointer to it's IBayesNet used as a DAG. */
378 
379  // typedef const CredalNet< GUM_SCALAR > * (infE::*cnfunc) ();
380  // cnfunc getCN = &infE::getCN;
381  public:
382  virtual void insertEvidenceFile(const std::string& path) {
383  InferenceEngine< GUM_SCALAR >::insertEvidenceFile(path);
384  };
385  };
386 
387 
388 #ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
389  extern template class CNLoopyPropagation< double >;
390 #endif
391  } // namespace credal
392 } // namespace gum
393 
394 #include <agrum/CN/inference/CNLoopyPropagation_tpl.h>
395 
396 #endif
void refreshLMsPIs_(bool refreshIndic=false)
Get the last messages from one&#39;s parents and children.
NodeProperty< NodeSet *> msg_l_sent_
Used to keep track of one&#39;s messages sent to it&#39;s parents.
void makeInferenceByOrderedArcs_()
Starts the inference with this inference type.
GUM_SCALAR calculateEpsilon_()
Compute epsilon.
NodeProperty< bool > update_l_
Used to keep track of which node needs to update it&#39;s information coming from it&#39;s children...
virtual void insertEvidenceFile(const std::string &path)
Insert evidence from file.
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:669
void makeInferenceNodeToNeighbours_()
Starts the inference with this inference type.
void eraseAllEvidence()
Erase all inference related data to perform another one.
ArcProperty< GUM_SCALAR > ArcsP_min_
"Lower" information coming from one&#39;s parent.
NodeSet active_nodes_set
The current node-set to iterate through at this current step.
ArcProperty< GUM_SCALAR > ArcsL_max_
"Upper" information coming from one&#39;s children.
NodeProperty< GUM_SCALAR > NodesL_min_
"Lower" node information obtained by combinaison of children messages.
NodeProperty< GUM_SCALAR > NodesP_max_
"Upper" node information obtained by combinaison of parent&#39;s messages.
<agrum/CN/CNLoopyPropagation.h>
Chooses an arc ordering and sends messages accordingly at all steps.
NodeProperty< GUM_SCALAR > NodesP_min_
"Lower" node information obtained by combinaison of parent&#39;s messages.
void compute_ext_(std::vector< std::vector< GUM_SCALAR > > &combi_msg_p, const NodeId &id, GUM_SCALAR &msg_p_min, GUM_SCALAR &msg_p_max)
Used by msgP_.
NodeProperty< bool > update_p_
Used to keep track of which node needs to update it&#39;s information coming from it&#39;s parents...
ArcProperty< GUM_SCALAR > ArcsP_max_
"Upper" information coming from one&#39;s parent.
InferenceType inferenceType()
Get the inference type.
const IBayesNet< GUM_SCALAR > * bnet__
A pointer to it&#39;s IBayesNet used as a DAG.
NodeProperty< GUM_SCALAR > NodesL_max_
"Upper" node information obtained by combinaison of children messages.
CNLoopyPropagation(const CredalNet< GUM_SCALAR > &cnet)
Constructor.
bool InferenceUpToDate_
TRUE if inference has already been performed, FALSE otherwise.
Uses a node-set so we don&#39;t iterate on nodes that can&#39;t send a new message.
void msgP_(const NodeId X, const NodeId demanding_child)
Sends a message to one&#39;s child, i.e.
void saveInference(const std::string &path)
void makeInferenceByRandomOrder_()
Starts the inference with this inference type.
void makeInference()
Starts the inference.
void initialize_()
Topological forward propagation to initialize old marginals & messages.
void enum_combi_(std::vector< std::vector< std::vector< GUM_SCALAR > > > &msgs_p, const NodeId &id, GUM_SCALAR &msg_p_min, GUM_SCALAR &msg_p_max)
Used by msgP_.
void inferenceType(InferenceType inft)
Set the inference type.
void updateIndicatrices_()
Only update indicatrices variables at the end of computations ( calls msgP_ ).
void compute_ext_(GUM_SCALAR &msg_l_min, GUM_SCALAR &msg_l_max, std::vector< GUM_SCALAR > &lx, GUM_SCALAR &num_min, GUM_SCALAR &num_max, GUM_SCALAR &den_min, GUM_SCALAR &den_max)
Used by msgL_.
void updateMarginals_()
Compute marginals from up-to-date messages.
InferenceType inferenceType__
The choosen inference type.
InferenceType
Inference type to be used by the algorithm.
void msgL_(const NodeId X, const NodeId demanding_parent)
Sends a message to one&#39;s parent, i.e.
Chooses a random arc ordering and sends messages accordingly.
const CredalNet< GUM_SCALAR > * cn__
A pointer to the CredalNet to be used.
NodeSet next_active_nodes_set
The next node-set, i.e.
void computeExpectations_()
Since the network is binary, expectations can be computed from the final marginals which give us the ...
namespace for all credal networks entities
Definition: LpInterface.cpp:37
ArcProperty< GUM_SCALAR > ArcsL_min_
"Lower" information coming from one&#39;s children.