aGrUM  0.13.2
IBayesNet_tpl.h
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2005 by Pierre-Henri WUILLEMIN et Christophe GONZALES *
3  * {prenom.nom}_at_lip6.fr *
4  * *
5  * This program is free software; you can redistribute it and/or modify *
6  * it under the terms of the GNU General Public License as published by *
7  * the Free Software Foundation; either version 2 of the License, or *
8  * (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public License *
16  * along with this program; if not, write to the *
17  * Free Software Foundation, Inc., *
18  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19  ***************************************************************************/
27 #include <limits>
28 
29 #include <agrum/BN/IBayesNet.h>
30 
33 
37 
40 
41 namespace gum {
42 
43  // IBayesNet
44 
45  template < typename GUM_SCALAR >
47  GUM_CONSTRUCTOR(IBayesNet);
48  }
49 
50  template < typename GUM_SCALAR >
51  INLINE IBayesNet< GUM_SCALAR >::IBayesNet(std::string name) : DAGmodel() {
52  GUM_CONSTRUCTOR(IBayesNet);
53  this->setProperty("name", name);
54  }
55 
56  template < typename GUM_SCALAR >
58  DAGmodel(source) {
59  GUM_CONS_CPY(IBayesNet);
60  }
61 
62  template < typename GUM_SCALAR >
65  if (this != &source) { DAGmodel::operator=(source); }
66 
67  return *this;
68  }
69 
70  template < typename GUM_SCALAR >
72  GUM_DESTRUCTOR(IBayesNet);
73  }
74 
75  template < typename GUM_SCALAR >
77  Size dim = 0;
78 
79  for (auto node : nodes()) {
80  Size q = 1;
81 
82  for (auto parent : parents(node))
83  q *= variable(parent).domainSize();
84 
85  dim += (variable(node).domainSize() - 1) * q;
86  }
87 
88  return dim;
89  }
90 
91  template < typename GUM_SCALAR >
93  Size res = 0;
94  for (auto node : nodes()) {
95  auto v = variable(node).domainSize();
96  if (v > res) { res = v; }
97  }
98  return res;
99  }
100 
101  template < typename GUM_SCALAR >
103  GUM_SCALAR res = 1.0;
104  for (auto node : nodes()) {
105  auto v = cpt(node).min();
106  if (v < res) { res = v; }
107  }
108  return res;
109  }
110 
111  template < typename GUM_SCALAR >
113  GUM_SCALAR res = 1.0;
114  for (auto node : nodes()) {
115  auto v = cpt(node).max();
116  if (v > res) { res = v; }
117  }
118  return res;
119  }
120 
121  template < typename GUM_SCALAR >
123  GUM_SCALAR res = 1.0;
124  for (auto node : nodes()) {
125  auto v = cpt(node).minNonZero();
126  if (v < res) { res = v; }
127  }
128  return res;
129  }
130 
131  template < typename GUM_SCALAR >
133  GUM_SCALAR res = 0.0;
134  for (auto node : nodes()) {
135  auto v = cpt(node).maxNonOne();
136  if (v > res) { res = v; }
137  }
138  return res;
139  }
140 
141  template < typename GUM_SCALAR >
142  INLINE std::string IBayesNet< GUM_SCALAR >::toString() const {
143  Size param = 0;
144  double dSize = log10DomainSize();
145 
146  for (auto node : nodes())
147  param += cpt(node).content()->realSize();
148 
149  double compressionRatio = log10(1.0 * param) - dSize;
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 << ", parameters: " << param << ", compression ratio: ";
160 
161  if (compressionRatio > -3)
162  s << trunc(100.0 - std::pow(10.0, compressionRatio + 2.0));
163  else
164  s << "100-10^" << compressionRatio + 2.0;
165 
166  s << "% }";
167 
168  return s.str();
169  }
170 
171  template < typename GUM_SCALAR >
172  std::string IBayesNet< GUM_SCALAR >::toDot() const {
173  std::stringstream output;
174  output << "digraph \"";
175 
176  std::string bn_name;
177 
178  try {
179  bn_name = this->property("name");
180  } catch (NotFound&) { bn_name = "no_name"; }
181 
182  output << bn_name << "\" {" << std::endl;
183  output << " graph [bgcolor=transparent,label=\"" << bn_name << "\"];"
184  << std::endl;
185  output << " node [style=filled fillcolor=\"#ffffaa\"];" << std::endl
186  << std::endl;
187 
188  for (auto node : nodes())
189  output << "\"" << variable(node).name() << "\" [comment=\"" << node << ":"
190  << variable(node).toStringWithDescription() << "\"];" << std::endl;
191 
192  output << std::endl;
193 
194  std::string tab = " ";
195 
196  for (auto node : nodes()) {
197  if (children(node).size() > 0) {
198  for (auto child : children(node)) {
199  output << tab << "\"" << variable(node).name() << "\" -> "
200  << "\"" << variable(child).name() << "\";" << std::endl;
201  }
202  } else if (parents(node).size() == 0) {
203  output << tab << "\"" << variable(node).name() << "\";" << std::endl;
204  }
205  }
206 
207  output << "}" << std::endl;
208 
209  return output.str();
210  }
211 
215  template < typename GUM_SCALAR >
216  GUM_SCALAR
218  auto value = (GUM_SCALAR)1.0;
219 
220  GUM_SCALAR tmp;
221 
222  for (auto node : nodes()) {
223  if ((tmp = cpt(node)[i]) == (GUM_SCALAR)0) { return (GUM_SCALAR)0; }
224 
225  value *= tmp;
226  }
227 
228  return value;
229  }
230 
234  template < typename GUM_SCALAR >
235  GUM_SCALAR
237  auto value = (GUM_SCALAR)0.0;
238 
239  GUM_SCALAR tmp;
240 
241  for (auto node : nodes()) {
242  if ((tmp = cpt(node)[i]) == (GUM_SCALAR)0) {
243  return (GUM_SCALAR)(-std::numeric_limits< double >::infinity());
244  }
245 
246  value += log2(cpt(node)[i]);
247  }
248 
249  return value;
250  }
251 
252  template < typename GUM_SCALAR >
254  if (size() != from.size()) { return false; }
255 
256  if (sizeArcs() != from.sizeArcs()) { return false; }
257 
258  // alignment of variables between the 2 BNs
260 
261  for (auto node : nodes()) {
262  try {
263  alignment.insert(&variable(node),
264  &from.variableFromName(variable(node).name()));
265  } catch (NotFound&) {
266  // a name is not found in from
267  return false;
268  }
269  }
270 
271  for (auto node : nodes()) {
272  NodeId fromnode = from.idFromName(variable(node).name());
273 
274  if (cpt(node).nbrDim() != from.cpt(fromnode).nbrDim()) { return false; }
275 
276  if (cpt(node).domainSize() != from.cpt(fromnode).domainSize()) {
277  return false;
278  }
279 
280  Instantiation i(cpt(node));
281  Instantiation j(from.cpt(fromnode));
282 
283  for (i.setFirst(); !i.end(); i.inc()) {
284  for (Idx indice = 0; indice < cpt(node).nbrDim(); ++indice) {
285  const DiscreteVariable* p = &(i.variable(indice));
286  j.chgVal(*(alignment.second(p)), i.val(*p));
287  }
288 
289  if (std::pow(cpt(node).get(i) - from.cpt(fromnode).get(j), (GUM_SCALAR)2)
290  > (GUM_SCALAR)1e-6) {
291  return false;
292  }
293  }
294  }
295 
296  return true;
297  }
298 
299  template < typename GUM_SCALAR >
301  return !this->operator==(from);
302  }
303 
304  // visit the nodes and add some of node from soids in minimal
305  template < typename GUM_SCALAR >
307  NodeId node,
308  const NodeSet& soids,
309  NodeSet& minimal,
310  NodeSet& alreadyVisitedUp,
311  NodeSet& alreadyVisitedDn) const {
312  if (alreadyVisitedUp.contains(node)) return;
313  alreadyVisitedUp << node;
314 
315  if (soids.contains(node)) {
316  minimal << node;
317  } else {
318  for (auto fath : _dag.parents(node))
320  fath, soids, minimal, alreadyVisitedUp, alreadyVisitedDn);
321  for (auto chil : _dag.children(node))
323  chil, soids, minimal, alreadyVisitedUp, alreadyVisitedDn);
324  }
325  }
326 
327  // visit the nodes and add some of node from soids in minimal
328  template < typename GUM_SCALAR >
330  NodeId node,
331  const NodeSet& soids,
332  NodeSet& minimal,
333  NodeSet& alreadyVisitedUp,
334  NodeSet& alreadyVisitedDn) const {
335  if (alreadyVisitedDn.contains(node)) return;
336  alreadyVisitedDn << node;
337 
338  if (soids.contains(node)) {
339  minimal << node;
340  for (auto fath : _dag.parents(node))
342  fath, soids, minimal, alreadyVisitedUp, alreadyVisitedDn);
343  } else {
344  for (auto chil : _dag.children(node))
346  chil, soids, minimal, alreadyVisitedUp, alreadyVisitedDn);
347  }
348  }
349 
350 
351  template < typename GUM_SCALAR >
353  const NodeSet& soids) const {
354  if (soids.contains(target)) return NodeSet({target});
355 
356  NodeSet res;
357  NodeSet alreadyVisitedUp;
358  NodeSet alreadyVisitedDn;
359  alreadyVisitedDn << target;
360  alreadyVisitedUp << target;
361 
362  for (auto fath : _dag.parents(target))
364  fath, soids, res, alreadyVisitedUp, alreadyVisitedDn);
365  for (auto chil : _dag.children(target))
367  chil, soids, res, alreadyVisitedUp, alreadyVisitedDn);
368  return res;
369  }
370 
371  template < typename GUM_SCALAR >
373  const NodeSet& soids) const {
374  NodeSet res;
375  for (auto node : targets) {
376  res += minimalCondSet(node, soids);
377  }
378  return res;
379  }
380 
381  template < typename GUM_SCALAR >
382  INLINE std::ostream& operator<<(std::ostream& output,
383  const IBayesNet< GUM_SCALAR >& bn) {
384  output << bn.toString();
385  return output;
386  }
387 
388 } /* namespace gum */
Size size() const
Returns the number of variables in this Directed Graphical Model.
Definition: DAGmodel_inl.h:94
DAGmodel & operator=(const DAGmodel &source)
Private copy operator.
Definition: DAGmodel.cpp:75
void insert(const T1 &first, const T2 &second)
Inserts a new association in the gum::Bijection.
GUM_SCALAR jointProbability(const Instantiation &i) const
Compute a parameter of the joint probability for the BN (given an instantiation of the vars) ...
unsigned long Size
In aGrUM, hashed values are unsigned long int.
Definition: types.h:50
Abstract class for generating Conditional Probability Tables.
Virtual base class for PGMs using a DAG.
Definition: DAGmodel.h:45
const DAG & dag() const
Returns a constant reference to the dag of this Bayes Net.
Definition: DAGmodel_inl.h:61
const T2 & second(const T1 &first) const
Returns the second value of a pair given its first value.
unsigned int NodeId
Type for node ids.
Definition: graphElements.h:97
void __minimalCondSetVisitDn(NodeId node, const NodeSet &soids, NodeSet &minimal, NodeSet &alreadyVisitedUp, NodeSet &alreadyVisitedDn) const
Size dim() const
Returns the dimension (the number of free parameters) in this bayes net.
Definition: IBayesNet_tpl.h:76
class for NoisyOR-net implementation as multiDim
Set< NodeId > NodeSet
Some typdefs and define for shortcuts ...
bool operator==(const IBayesNet< GUM_SCALAR > &from) const
This operator compares 2 BNs !
virtual const Potential< GUM_SCALAR > & cpt(NodeId varId) const =0
Returns the CPT of a variable.
Class representing Bayesian networks.
IBayesNet< GUM_SCALAR > & operator=(const IBayesNet< GUM_SCALAR > &source)
Copy operator.
Definition: IBayesNet_tpl.h:64
GUM_SCALAR maxNonOneParam() const
class for multiDimNoisyORCompound
Base class for discrete random variable.
Size sizeArcs() const
Returns the number of arcs in this Directed Graphical Model.
Definition: DAGmodel_inl.h:100
bool contains(const Key &k) const
Indicates whether a given elements belong to the set.
Definition: set_tpl.h:581
const NodeSet & children(const NodeId id) const
returns the set of nodes with arc outgoing from a given node
Definition: DAGmodel_inl.h:109
Class representing the minimal interface for Bayesian Network.
Definition: IBayesNet.h:59
gum is the global namespace for all aGrUM entities
Definition: agrum.h:25
GUM_SCALAR maxParam() const
bool operator!=(const IBayesNet< GUM_SCALAR > &from) const
virtual std::string toDot() const
virtual NodeId idFromName(const std::string &name) const =0
Getter by name.
virtual Size domainSize() const =0
GUM_SCALAR log2JointProbability(const Instantiation &i) const
Compute a parameter of the log joint probability for the BN (given an instantiation of the vars) ...
const std::string toStringWithDescription() const
string version of *this using description attribute instead of name.
DAG _dag
The DAG of this Directed Graphical Model.
Definition: DAGmodel.h:200
virtual const DiscreteVariable & variable(NodeId id) const =0
Returns a constant reference over a variable given it&#39;s node id.
Header of the Potential class.
const NodeSet & parents(const NodeId id) const
returns the set of nodes with arc ingoing to a given node
std::ostream & operator<<(std::ostream &output, const BayesNet< GUM_SCALAR > &bn)
Prints map&#39;s DAG in output using the Graphviz-dot format.
Definition: BayesNet_tpl.h:573
or aggregator
void inc()
Operator increment.
GUM_SCALAR minNonZeroParam() const
NodeSet minimalCondSet(NodeId target, const NodeSet &soids) const
void setProperty(const std::string &name, const std::string &value)
Add or change a property of this DAGModel.
Definition: DAGmodel_inl.h:54
std::string toString() const
virtual const DiscreteVariable & variableFromName(const std::string &name) const =0
Getter by name.
GUM_SCALAR minParam() const
Set of pairs of elements with fast search for both elements.
Definition: bijection.h:1803
virtual ~IBayesNet()
Destructor.
Definition: IBayesNet_tpl.h:71
bool end() const
Returns true if the Instantiation reached the end.
const NodeSet & parents(const NodeId id) const
returns the set of nodes with arc ingoing to a given node
Definition: DAGmodel_inl.h:104
Class for assigning/browsing values to tuples of discrete variables.
Definition: instantiation.h:80
const NodeSet & children(const NodeId id) const
returns the set of nodes with arc outgoing from a given node
Size sizeArcs() const
indicates the number of arcs stored within the ArcGraphPart
count aggregator
class for NoisyAND-net implementation as multiDim
void __minimalCondSetVisitUp(NodeId node, const NodeSet &soids, NodeSet &minimal, NodeSet &alreadyVisitedUp, NodeSet &alreadyVisitedDn) const
double log10DomainSize() const
Definition: DAGmodel_inl.h:73
void setFirst()
Assign the first values to the tuple of the Instantiation.
IBayesNet()
Default constructor.
Definition: IBayesNet_tpl.h:46
const std::string & property(const std::string &name) const
Return the value of the property name of this DAGModel.
Definition: DAGmodel_inl.h:35
const NodeGraphPart & nodes() const
Returns a constant reference to the dag of this Bayes Net.
Definition: DAGmodel_inl.h:113
unsigned long Idx
Type for indexes.
Definition: types.h:43
const std::string & name() const
returns the name of the variable
const DiscreteVariable & variable(Idx i) const final
Returns the variable at position i in the tuple.
Size maxVarDomainSize() const
Definition: IBayesNet_tpl.h:92
Idx val(Idx i) const
Returns the current value of the variable at position i.