aGrUM  0.16.0
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  double compressionRatio = log10(1.0 * param) - dSize;
153 
154  std::stringstream s;
155  s << "BN{nodes: " << size() << ", arcs: " << dag().sizeArcs() << ", ";
156 
157  if (dSize > 6)
158  s << "domainSize: 10^" << dSize;
159  else
160  s << "domainSize: " << std::round(std::pow(10.0, dSize));
161 
162  s << ", parameters: " << param << ", compression ratio: ";
163 
164  if (compressionRatio > -3)
165  s << trunc(100.0 - std::pow(10.0, compressionRatio + 2.0));
166  else
167  s << "100-10^" << compressionRatio + 2.0;
168 
169  s << "% }";
170 
171  return s.str();
172  }
173 
174  template < typename GUM_SCALAR >
175  std::string IBayesNet< GUM_SCALAR >::toDot() const {
176  std::stringstream output;
177  output << "digraph \"";
178 
179  std::string bn_name;
180 
181  try {
182  bn_name = this->property("name");
183  } catch (NotFound&) { bn_name = "no_name"; }
184 
185  output << bn_name << "\" {" << std::endl;
186  output << " graph [bgcolor=transparent,label=\"" << bn_name << "\"];"
187  << std::endl;
188  output << " node [style=filled fillcolor=\"#ffffaa\"];" << std::endl
189  << std::endl;
190 
191  for (auto node : nodes())
192  output << "\"" << variable(node).name() << "\" [comment=\"" << node << ":"
193  << variable(node).toStringWithDescription() << "\"];" << std::endl;
194 
195  output << std::endl;
196 
197  std::string tab = " ";
198 
199  for (auto node : nodes()) {
200  if (children(node).size() > 0) {
201  for (auto child : children(node)) {
202  output << tab << "\"" << variable(node).name() << "\" -> "
203  << "\"" << variable(child).name() << "\";" << std::endl;
204  }
205  } else if (parents(node).size() == 0) {
206  output << tab << "\"" << variable(node).name() << "\";" << std::endl;
207  }
208  }
209 
210  output << "}" << std::endl;
211 
212  return output.str();
213  }
214 
218  template < typename GUM_SCALAR >
219  GUM_SCALAR
221  auto value = (GUM_SCALAR)1.0;
222 
223  GUM_SCALAR tmp;
224 
225  for (auto node : nodes()) {
226  if ((tmp = cpt(node)[i]) == (GUM_SCALAR)0) { return (GUM_SCALAR)0; }
227 
228  value *= tmp;
229  }
230 
231  return value;
232  }
233 
237  template < typename GUM_SCALAR >
238  GUM_SCALAR
240  auto value = (GUM_SCALAR)0.0;
241 
242  GUM_SCALAR tmp;
243 
244  for (auto node : nodes()) {
245  if ((tmp = cpt(node)[i]) == (GUM_SCALAR)0) {
246  return (GUM_SCALAR)(-std::numeric_limits< double >::infinity());
247  }
248 
249  value += log2(cpt(node)[i]);
250  }
251 
252  return value;
253  }
254 
255  template < typename GUM_SCALAR >
257  if (size() != from.size()) { return false; }
258 
259  if (sizeArcs() != from.sizeArcs()) { return false; }
260 
261  // alignment of variables between the 2 BNs
263 
264  for (auto node : nodes()) {
265  try {
266  alignment.insert(&variable(node),
267  &from.variableFromName(variable(node).name()));
268  } catch (NotFound&) {
269  // a name is not found in from
270  return false;
271  }
272  }
273 
274  for (auto node : nodes()) {
275  NodeId fromnode = from.idFromName(variable(node).name());
276 
277  if (cpt(node).nbrDim() != from.cpt(fromnode).nbrDim()) { return false; }
278 
279  if (cpt(node).domainSize() != from.cpt(fromnode).domainSize()) {
280  return false;
281  }
282 
283  Instantiation i(cpt(node));
284  Instantiation j(from.cpt(fromnode));
285 
286  for (i.setFirst(); !i.end(); i.inc()) {
287  for (Idx indice = 0; indice < cpt(node).nbrDim(); ++indice) {
288  const DiscreteVariable* p = &(i.variable(indice));
289  j.chgVal(*(alignment.second(p)), i.val(*p));
290  }
291 
292  if (std::pow(cpt(node).get(i) - from.cpt(fromnode).get(j), (GUM_SCALAR)2)
293  > (GUM_SCALAR)1e-6) {
294  return false;
295  }
296  }
297  }
298 
299  return true;
300  }
301 
302  template < typename GUM_SCALAR >
304  return !this->operator==(from);
305  }
306 
307  // visit the nodes and add some of node from soids in minimal
308  template < typename GUM_SCALAR >
310  NodeId node,
311  const NodeSet& soids,
312  NodeSet& minimal,
313  NodeSet& alreadyVisitedUp,
314  NodeSet& alreadyVisitedDn) const {
315  if (alreadyVisitedUp.contains(node)) return;
316  alreadyVisitedUp << node;
317 
318  if (soids.contains(node)) {
319  minimal << node;
320  } else {
321  for (auto fath : _dag.parents(node))
322  __minimalCondSetVisitUp(
323  fath, soids, minimal, alreadyVisitedUp, alreadyVisitedDn);
324  for (auto chil : _dag.children(node))
325  __minimalCondSetVisitDn(
326  chil, soids, minimal, alreadyVisitedUp, alreadyVisitedDn);
327  }
328  }
329 
330  // visit the nodes and add some of node from soids in minimal
331  template < typename GUM_SCALAR >
333  NodeId node,
334  const NodeSet& soids,
335  NodeSet& minimal,
336  NodeSet& alreadyVisitedUp,
337  NodeSet& alreadyVisitedDn) const {
338  if (alreadyVisitedDn.contains(node)) return;
339  alreadyVisitedDn << node;
340 
341  if (soids.contains(node)) {
342  minimal << node;
343  for (auto fath : _dag.parents(node))
344  __minimalCondSetVisitUp(
345  fath, soids, minimal, alreadyVisitedUp, alreadyVisitedDn);
346  } else {
347  for (auto chil : _dag.children(node))
348  __minimalCondSetVisitDn(
349  chil, soids, minimal, alreadyVisitedUp, alreadyVisitedDn);
350  }
351  }
352 
353 
354  template < typename GUM_SCALAR >
356  const NodeSet& soids) const {
357  if (soids.contains(target)) return NodeSet({target});
358 
359  NodeSet res;
360  NodeSet alreadyVisitedUp;
361  NodeSet alreadyVisitedDn;
362  alreadyVisitedDn << target;
363  alreadyVisitedUp << target;
364 
365  for (auto fath : _dag.parents(target))
366  __minimalCondSetVisitUp(
367  fath, soids, res, alreadyVisitedUp, alreadyVisitedDn);
368  for (auto chil : _dag.children(target))
369  __minimalCondSetVisitDn(
370  chil, soids, res, alreadyVisitedUp, alreadyVisitedDn);
371  return res;
372  }
373 
374  template < typename GUM_SCALAR >
376  const NodeSet& soids) const {
377  NodeSet res;
378  for (auto node : targets) {
379  res += minimalCondSet(node, soids);
380  }
381  return res;
382  }
383 
384  template < typename GUM_SCALAR >
385  INLINE std::ostream& operator<<(std::ostream& output,
386  const IBayesNet< GUM_SCALAR >& bn) {
387  output << bn.toString();
388  return output;
389  }
390 
391 } /* 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-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.