aGrUM  0.18.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:581
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-2020 Pierre-Henri WUILLEMIN() & Christophe GONZALES() info_at_agrum_dot_org.
Virtual base class for PGMs using a DAG.
Definition: DAGmodel.h:47
Copyright 2005-2020 Pierre-Henri WUILLEMIN() & Christophe GONZALES() info_at_agrum_dot_org.
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:42
virtual Size size() const final
Returns the number of variables in this Directed Graphical Model.
Definition: DAGmodel_inl.h:39
virtual const Potential< GUM_SCALAR > & cpt(NodeId varId) const =0
Returns the CPT of a variable.
Copyright 2005-2020 Pierre-Henri WUILLEMIN() & Christophe GONZALES() info_at_agrum_dot_org.
Copyright 2005-2020 Pierre-Henri WUILLEMIN() & Christophe GONZALES() info_at_agrum_dot_org.
Base class for discrete random variable.
Class representing the minimal interface for Bayesian Network.
Definition: IBayesNet.h:62
Copyright 2005-2020 Pierre-Henri WUILLEMIN() & Christophe GONZALES() info_at_agrum_dot_org.
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.
Copyright 2005-2020 Pierre-Henri WUILLEMIN() & Christophe GONZALES() info_at_agrum_dot_org.
Copyright 2005-2020 Pierre-Henri WUILLEMIN() & Christophe GONZALES() info_at_agrum_dot_org.
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-2020 Pierre-Henri WUILLEMIN() & Christophe GONZALES() info_at_agrum_dot_org.
Copyright 2005-2020 Pierre-Henri WUILLEMIN() & Christophe GONZALES() info_at_agrum_dot_org.
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.