aGrUM  0.20.3
a C++ library for (probabilistic) graphical models
IBayesNet_tpl.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 Template implementation of bns/bayesNet.h classes.
25  *
26  * @author Pierre-Henri WUILLEMIN(@LIP6) and Lionel TORTI
27  */
28 
29 #include <limits>
30 #include <cmath>
31 
32 #include <agrum/BN/IBayesNet.h>
33 
34 #include <agrum/tools/multidim/aggregators/and.h>
35 #include <agrum/tools/multidim/aggregators/or.h>
36 
37 #include <agrum/tools/multidim/ICIModels/multiDimNoisyAND.h>
38 #include <agrum/tools/multidim/ICIModels/multiDimNoisyORCompound.h>
39 #include <agrum/tools/multidim/ICIModels/multiDimNoisyORNet.h>
40 
41 #include <agrum/BN/generator/simpleCPTGenerator.h>
42 #include <agrum/tools/multidim/potential.h>
43 
44 namespace gum {
45 
46  // IBayesNet
47 
48  template < typename GUM_SCALAR >
49  INLINE IBayesNet< GUM_SCALAR >::IBayesNet() : DAGmodel() {
51  }
52 
53  template < typename GUM_SCALAR >
56  this->setProperty("name", name);
57  }
58 
59  template < typename GUM_SCALAR >
62  }
63 
64  template < typename GUM_SCALAR >
67  if (this != &source) { DAGmodel::operator=(source); }
68 
69  return *this;
70  }
71 
72  template < typename GUM_SCALAR >
75  }
76 
77  template < typename GUM_SCALAR >
78  Size IBayesNet< GUM_SCALAR >::dim() const {
79  Size dim = 0;
80 
81  for (auto node: nodes()) {
82  Size q = 1;
83 
84  for (auto parent: parents(node))
86 
87  dim += (variable(node).domainSize() - 1) * q;
88  }
89 
90  return dim;
91  }
92 
93  template < typename GUM_SCALAR >
95  Size res = 0;
96  for (auto node: nodes()) {
97  auto v = variable(node).domainSize();
98  if (v > res) { res = v; }
99  }
100  return res;
101  }
102 
103  template < typename GUM_SCALAR >
105  GUM_SCALAR res = 1.0;
106  for (auto node: nodes()) {
107  auto v = cpt(node).min();
108  if (v < res) { res = v; }
109  }
110  return res;
111  }
112 
113  template < typename GUM_SCALAR >
115  GUM_SCALAR res = 1.0;
116  for (auto node: nodes()) {
117  auto v = cpt(node).max();
118  if (v > res) { res = v; }
119  }
120  return res;
121  }
122 
123  template < typename GUM_SCALAR >
125  GUM_SCALAR res = 1.0;
126  for (auto node: nodes()) {
127  auto v = cpt(node).minNonZero();
128  if (v < res) { res = v; }
129  }
130  return res;
131  }
132 
133  template < typename GUM_SCALAR >
135  GUM_SCALAR res = 0.0;
136  for (auto node: nodes()) {
137  auto v = cpt(node).maxNonOne();
138  if (v > res) { res = v; }
139  }
140  return res;
141  }
142 
143  template < typename GUM_SCALAR >
145  Size param = 0;
146  double dSize = log10DomainSize();
147 
148  for (auto node: nodes())
149  param += cpt(node).content()->realSize();
150 
151  std::stringstream s;
152  s << "BN{nodes: " << size() << ", arcs: " << dag().sizeArcs() << ", ";
153 
154  if (dSize > 6)
155  s << "domainSize: 10^" << dSize;
156  else
157  s << "domainSize: " << std::round(std::pow(10.0, dSize));
158 
159  s << ", dim: " << param << "}";
160 
161  return s.str();
162  }
163 
164  template < typename GUM_SCALAR >
167  output << "digraph \"";
168 
169  std::string bn_name;
170 
171  try {
172  bn_name = this->property("name");
173  } catch (NotFound&) { bn_name = "no_name"; }
174 
175  output << bn_name << "\" {" << std::endl;
176  output << " graph [bgcolor=transparent,label=\"" << bn_name << "\"];" << std::endl;
177  output << " node [style=filled fillcolor=\"#ffffaa\"];" << std::endl << std::endl;
178 
179  for (auto node: nodes())
180  output << "\"" << variable(node).name() << "\" [comment=\"" << node << ":"
181  << variable(node).toStringWithDescription() << "\"];" << std::endl;
182 
183  output << std::endl;
184 
185  std::string tab = " ";
186 
187  for (auto node: nodes()) {
188  if (children(node).size() > 0) {
189  for (auto child: children(node)) {
190  output << tab << "\"" << variable(node).name() << "\" -> "
191  << "\"" << variable(child).name() << "\";" << std::endl;
192  }
193  } else if (parents(node).size() == 0) {
194  output << tab << "\"" << variable(node).name() << "\";" << std::endl;
195  }
196  }
197 
198  output << "}" << std::endl;
199 
200  return output.str();
201  }
202 
203  /// Compute a parameter of the joint probability for the BN (given an
204  /// instantiation
205  /// of the vars)
206  template < typename GUM_SCALAR >
208  auto value = (GUM_SCALAR)1.0;
209 
210  GUM_SCALAR tmp;
211 
212  for (auto node: nodes()) {
213  if ((tmp = cpt(node)[i]) == (GUM_SCALAR)0) { return (GUM_SCALAR)0; }
214 
215  value *= tmp;
216  }
217 
218  return value;
219  }
220 
221  /// Compute a parameter of the joint probability for the BN (given an
222  /// instantiation
223  /// of the vars)
224  template < typename GUM_SCALAR >
226  auto value = (GUM_SCALAR)0.0;
227 
228  GUM_SCALAR tmp;
229 
230  for (auto node: nodes()) {
231  if ((tmp = cpt(node)[i]) == (GUM_SCALAR)0) {
232  return (GUM_SCALAR)(-std::numeric_limits< double >::infinity());
233  }
234 
235  value += std::log2(cpt(node)[i]);
236  }
237 
238  return value;
239  }
240 
241  template < typename GUM_SCALAR >
242  bool IBayesNet< GUM_SCALAR >::operator==(const IBayesNet& from) const {
243  if (size() != from.size()) { return false; }
244 
245  if (sizeArcs() != from.sizeArcs()) { return false; }
246 
247  // alignment of variables between the 2 BNs
249 
250  for (auto node: nodes()) {
251  try {
253  } catch (NotFound&) {
254  // a name is not found in from
255  return false;
256  }
257  }
258 
259  for (auto node: nodes()) {
261 
262  if (cpt(node).nbrDim() != from.cpt(fromnode).nbrDim()) { return false; }
263 
264  if (cpt(node).domainSize() != from.cpt(fromnode).domainSize()) { return false; }
265 
268 
269  for (i.setFirst(); !i.end(); i.inc()) {
270  for (Idx indice = 0; indice < cpt(node).nbrDim(); ++indice) {
271  const DiscreteVariable* p = &(i.variable(indice));
272  j.chgVal(*(alignment.second(p)), i.val(*p));
273  }
274 
275  if (std::pow(cpt(node).get(i) - from.cpt(fromnode).get(j), (GUM_SCALAR)2)
276  > (GUM_SCALAR)1e-6) {
277  return false;
278  }
279  }
280  }
281 
282  return true;
283  }
284 
285  template < typename GUM_SCALAR >
286  bool IBayesNet< GUM_SCALAR >::operator!=(const IBayesNet& from) const {
287  return !this->operator==(from);
288  }
289 
290  // visit the nodes and add some of node from soids in minimal
291  template < typename GUM_SCALAR >
293  const NodeSet& soids,
294  NodeSet& minimal,
296  NodeSet& alreadyVisitedDn) const {
297  if (alreadyVisitedUp.contains(node)) return;
299 
300  if (soids.contains(node)) {
301  minimal << node;
302  } else {
303  for (auto fath: dag_.parents(node))
305  for (auto chil: dag_.children(node))
307  }
308  }
309 
310  // visit the nodes and add some of node from soids in minimal
311  template < typename GUM_SCALAR >
313  const NodeSet& soids,
314  NodeSet& minimal,
316  NodeSet& alreadyVisitedDn) const {
317  if (alreadyVisitedDn.contains(node)) return;
319 
320  if (soids.contains(node)) {
321  minimal << node;
322  for (auto fath: dag_.parents(node))
324  } else {
325  for (auto chil: dag_.children(node))
327  }
328  }
329 
330 
331  template < typename GUM_SCALAR >
333  if (soids.contains(target)) return NodeSet({target});
334 
335  NodeSet res;
340 
341  for (auto fath: dag_.parents(target))
343  for (auto chil: dag_.children(target))
345  return res;
346  }
347 
348  template < typename GUM_SCALAR >
350  const NodeSet& soids) const {
351  NodeSet res;
352  for (auto node: targets) {
354  }
355  return res;
356  }
357 
358  template < typename GUM_SCALAR >
360  output << bn.toString();
361  return output;
362  }
363 
364 } /* namespace gum */
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:643