aGrUM  0.17.1
a C++ library for (probabilistic) graphical models
IBayesNet_tpl.h
Go to the documentation of this file.
1 
30 #include <limits>
31 
32 #include <agrum/BN/IBayesNet.h>
33 
36 
40 
43 
44 namespace gum {
45 
46  // IBayesNet
47 
48  template < typename GUM_SCALAR >
50  GUM_CONSTRUCTOR(IBayesNet);
51  }
52 
53  template < typename GUM_SCALAR >
54  INLINE IBayesNet< GUM_SCALAR >::IBayesNet(std::string name) : DAGmodel() {
55  GUM_CONSTRUCTOR(IBayesNet);
56  this->setProperty("name", name);
57  }
58 
59  template < typename GUM_SCALAR >
61  DAGmodel(source) {
62  GUM_CONS_CPY(IBayesNet);
63  }
64 
65  template < typename GUM_SCALAR >
68  if (this != &source) { DAGmodel::operator=(source); }
69 
70  return *this;
71  }
72 
73  template < typename GUM_SCALAR >
75  GUM_DESTRUCTOR(IBayesNet);
76  }
77 
78  template < typename GUM_SCALAR >
80  Size dim = 0;
81 
82  for (auto node: nodes()) {
83  Size q = 1;
84 
85  for (auto parent: parents(node))
86  q *= variable(parent).domainSize();
87 
88  dim += (variable(node).domainSize() - 1) * q;
89  }
90 
91  return dim;
92  }
93 
94  template < typename GUM_SCALAR >
96  Size res = 0;
97  for (auto node: nodes()) {
98  auto v = variable(node).domainSize();
99  if (v > res) { res = v; }
100  }
101  return res;
102  }
103 
104  template < typename GUM_SCALAR >
106  GUM_SCALAR res = 1.0;
107  for (auto node: nodes()) {
108  auto v = cpt(node).min();
109  if (v < res) { res = v; }
110  }
111  return res;
112  }
113 
114  template < typename GUM_SCALAR >
116  GUM_SCALAR res = 1.0;
117  for (auto node: nodes()) {
118  auto v = cpt(node).max();
119  if (v > res) { res = v; }
120  }
121  return res;
122  }
123 
124  template < typename GUM_SCALAR >
126  GUM_SCALAR res = 1.0;
127  for (auto node: nodes()) {
128  auto v = cpt(node).minNonZero();
129  if (v < res) { res = v; }
130  }
131  return res;
132  }
133 
134  template < typename GUM_SCALAR >
136  GUM_SCALAR res = 0.0;
137  for (auto node: nodes()) {
138  auto v = cpt(node).maxNonOne();
139  if (v > res) { res = v; }
140  }
141  return res;
142  }
143 
144  template < typename GUM_SCALAR >
145  INLINE std::string IBayesNet< GUM_SCALAR >::toString() const {
146  Size param = 0;
147  double dSize = log10DomainSize();
148 
149  for (auto node: nodes())
150  param += cpt(node).content()->realSize();
151 
152  std::stringstream s;
153  s << "BN{nodes: " << size() << ", arcs: " << dag().sizeArcs() << ", ";
154 
155  if (dSize > 6)
156  s << "domainSize: 10^" << dSize;
157  else
158  s << "domainSize: " << std::round(std::pow(10.0, dSize));
159 
160  s << ", dim: " << param << "}";
161 
162  return s.str();
163  }
164 
165  template < typename GUM_SCALAR >
166  std::string IBayesNet< GUM_SCALAR >::toDot() const {
167  std::stringstream output;
168  output << "digraph \"";
169 
170  std::string bn_name;
171 
172  try {
173  bn_name = this->property("name");
174  } catch (NotFound&) { bn_name = "no_name"; }
175 
176  output << bn_name << "\" {" << std::endl;
177  output << " graph [bgcolor=transparent,label=\"" << bn_name << "\"];"
178  << std::endl;
179  output << " node [style=filled fillcolor=\"#ffffaa\"];" << std::endl
180  << std::endl;
181 
182  for (auto node: nodes())
183  output << "\"" << variable(node).name() << "\" [comment=\"" << node << ":"
184  << variable(node).toStringWithDescription() << "\"];" << std::endl;
185 
186  output << std::endl;
187 
188  std::string tab = " ";
189 
190  for (auto node: nodes()) {
191  if (children(node).size() > 0) {
192  for (auto child: children(node)) {
193  output << tab << "\"" << variable(node).name() << "\" -> "
194  << "\"" << variable(child).name() << "\";" << std::endl;
195  }
196  } else if (parents(node).size() == 0) {
197  output << tab << "\"" << variable(node).name() << "\";" << std::endl;
198  }
199  }
200 
201  output << "}" << std::endl;
202 
203  return output.str();
204  }
205 
209  template < typename GUM_SCALAR >
210  GUM_SCALAR
212  auto value = (GUM_SCALAR)1.0;
213 
214  GUM_SCALAR tmp;
215 
216  for (auto node: nodes()) {
217  if ((tmp = cpt(node)[i]) == (GUM_SCALAR)0) { return (GUM_SCALAR)0; }
218 
219  value *= tmp;
220  }
221 
222  return value;
223  }
224 
228  template < typename GUM_SCALAR >
229  GUM_SCALAR
231  auto value = (GUM_SCALAR)0.0;
232 
233  GUM_SCALAR tmp;
234 
235  for (auto node: nodes()) {
236  if ((tmp = cpt(node)[i]) == (GUM_SCALAR)0) {
237  return (GUM_SCALAR)(-std::numeric_limits< double >::infinity());
238  }
239 
240  value += log2(cpt(node)[i]);
241  }
242 
243  return value;
244  }
245 
246  template < typename GUM_SCALAR >
248  if (size() != from.size()) { return false; }
249 
250  if (sizeArcs() != from.sizeArcs()) { return false; }
251 
252  // alignment of variables between the 2 BNs
254 
255  for (auto node: nodes()) {
256  try {
257  alignment.insert(&variable(node),
258  &from.variableFromName(variable(node).name()));
259  } catch (NotFound&) {
260  // a name is not found in from
261  return false;
262  }
263  }
264 
265  for (auto node: nodes()) {
266  NodeId fromnode = from.idFromName(variable(node).name());
267 
268  if (cpt(node).nbrDim() != from.cpt(fromnode).nbrDim()) { return false; }
269 
270  if (cpt(node).domainSize() != from.cpt(fromnode).domainSize()) {
271  return false;
272  }
273 
274  Instantiation i(cpt(node));
275  Instantiation j(from.cpt(fromnode));
276 
277  for (i.setFirst(); !i.end(); i.inc()) {
278  for (Idx indice = 0; indice < cpt(node).nbrDim(); ++indice) {
279  const DiscreteVariable* p = &(i.variable(indice));
280  j.chgVal(*(alignment.second(p)), i.val(*p));
281  }
282 
283  if (std::pow(cpt(node).get(i) - from.cpt(fromnode).get(j), (GUM_SCALAR)2)
284  > (GUM_SCALAR)1e-6) {
285  return false;
286  }
287  }
288  }
289 
290  return true;
291  }
292 
293  template < typename GUM_SCALAR >
295  return !this->operator==(from);
296  }
297 
298  // visit the nodes and add some of node from soids in minimal
299  template < typename GUM_SCALAR >
301  NodeId node,
302  const NodeSet& soids,
303  NodeSet& minimal,
304  NodeSet& alreadyVisitedUp,
305  NodeSet& alreadyVisitedDn) const {
306  if (alreadyVisitedUp.contains(node)) return;
307  alreadyVisitedUp << node;
308 
309  if (soids.contains(node)) {
310  minimal << node;
311  } else {
312  for (auto fath: _dag.parents(node))
313  __minimalCondSetVisitUp(
314  fath, soids, minimal, alreadyVisitedUp, alreadyVisitedDn);
315  for (auto chil: _dag.children(node))
316  __minimalCondSetVisitDn(
317  chil, soids, minimal, alreadyVisitedUp, alreadyVisitedDn);
318  }
319  }
320 
321  // visit the nodes and add some of node from soids in minimal
322  template < typename GUM_SCALAR >
324  NodeId node,
325  const NodeSet& soids,
326  NodeSet& minimal,
327  NodeSet& alreadyVisitedUp,
328  NodeSet& alreadyVisitedDn) const {
329  if (alreadyVisitedDn.contains(node)) return;
330  alreadyVisitedDn << node;
331 
332  if (soids.contains(node)) {
333  minimal << node;
334  for (auto fath: _dag.parents(node))
335  __minimalCondSetVisitUp(
336  fath, soids, minimal, alreadyVisitedUp, alreadyVisitedDn);
337  } else {
338  for (auto chil: _dag.children(node))
339  __minimalCondSetVisitDn(
340  chil, soids, minimal, alreadyVisitedUp, alreadyVisitedDn);
341  }
342  }
343 
344 
345  template < typename GUM_SCALAR >
347  const NodeSet& soids) const {
348  if (soids.contains(target)) return NodeSet({target});
349 
350  NodeSet res;
351  NodeSet alreadyVisitedUp;
352  NodeSet alreadyVisitedDn;
353  alreadyVisitedDn << target;
354  alreadyVisitedUp << target;
355 
356  for (auto fath: _dag.parents(target))
357  __minimalCondSetVisitUp(
358  fath, soids, res, alreadyVisitedUp, alreadyVisitedDn);
359  for (auto chil: _dag.children(target))
360  __minimalCondSetVisitDn(
361  chil, soids, res, alreadyVisitedUp, alreadyVisitedDn);
362  return res;
363  }
364 
365  template < typename GUM_SCALAR >
367  const NodeSet& soids) const {
368  NodeSet res;
369  for (auto node: targets) {
370  res += minimalCondSet(node, soids);
371  }
372  return res;
373  }
374 
375  template < typename GUM_SCALAR >
376  INLINE std::ostream& operator<<(std::ostream& output,
377  const IBayesNet< GUM_SCALAR >& bn) {
378  output << bn.toString();
379  return output;
380  }
381 
382 } /* namespace gum */
bool contains(const Key &k) const
Indicates whether a given elements belong to the set.
Definition: set_tpl.h:583
void insert(const T1 &first, const T2 &second)
Inserts a new association in the gum::Bijection.
const T2 & second(const T1 &first) const
Returns the second value of a pair given its first value.
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
Virtual base class for PGMs using a DAG.
Definition: DAGmodel.h:48
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
Set< NodeId > NodeSet
Some typdefs and define for shortcuts ...
Size sizeArcs() const
Returns the number of arcs in this Directed Graphical Model.
Definition: DAGmodel_inl.h:102
virtual const Potential< GUM_SCALAR > & cpt(NodeId varId) const =0
Returns the CPT of a variable.
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
Base class for discrete random variable.
Class representing the minimal interface for Bayesian Network.
Definition: IBayesNet.h:62
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
Definition: agrum.h:25
virtual NodeId idFromName(const std::string &name) const =0
Getter by name.
Idx val(Idx i) const
Returns the current value of the variable at position i.
Size size() const
Returns the number of variables in this Directed Graphical Model.
Definition: DAGmodel_inl.h:96
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
void inc()
Operator increment.
virtual const DiscreteVariable & variableFromName(const std::string &name) const =0
Getter by name.
bool operator==(const TiXmlString &a, const TiXmlString &b)
Definition: tinystr.h:243
Set of pairs of elements with fast search for both elements.
Definition: bijection.h:1805
Class for assigning/browsing values to tuples of discrete variables.
Definition: instantiation.h:83
std::string toString() const
INLINE std::ostream & operator<<(std::ostream &output, const IBayesNet< GUM_SCALAR > &bn)
Prints map&#39;s DAG in output using the Graphviz-dot format.
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
bool operator!=(const TiXmlString &a, const TiXmlString &b)
Definition: tinystr.h:251
void setFirst()
Assign the first values to the tuple of the Instantiation.
IBayesNet()
Default constructor.
Definition: IBayesNet_tpl.h:49
Size Idx
Type for indexes.
Definition: types.h:53
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Definition: types.h:48
const DiscreteVariable & variable(Idx i) const final
Returns the variable at position i in the tuple.
Size NodeId
Type for node ids.
Definition: graphElements.h:98
bool end() const
Returns true if the Instantiation reached the end.