aGrUM  0.20.3
a C++ library for (probabilistic) graphical models
IMarkovNet_tpl.h
Go to the documentation of this file.
1 /**
2  *
3  * Copyright (c) 2005-2021 by Pierre-Henri WUILLEMIN(@LIP6) et Christophe GONZALES(@AMU)
4  * (@AMU) 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 
31 #include <agrum/MN/IMarkovNet.h>
32 #include <agrum/tools/multidim/potential.h>
33 
34 #define EF get
35 namespace gum {
36 
37  // IMarkovNet
38 
39  template < typename GUM_SCALAR >
40  INLINE IMarkovNet< GUM_SCALAR >::IMarkovNet() : UGmodel() {
42  }
43 
44  template < typename GUM_SCALAR >
47  this->setProperty("name", name);
48  }
49 
50  template < typename GUM_SCALAR >
53  }
54 
55  template < typename GUM_SCALAR >
58  if (this != &source) { UGmodel::operator=(source); }
59 
60  return *this;
61  }
62 
63  template < typename GUM_SCALAR >
66  }
67 
68  template < typename GUM_SCALAR >
70  Size res = 0;
71  for (auto f: factors()) {
72  res += f.second->domainSize();
73  }
74  return res;
75  }
76 
77  template < typename GUM_SCALAR >
79  Size res = 0;
80  for (auto node: nodes()) {
81  auto v = variable(node).domainSize();
82  if (v > res) { res = v; }
83  }
84  return res;
85  }
86 
87  template < typename GUM_SCALAR >
89  GUM_SCALAR res = 1.0;
90  for (auto elt: factors()) {
91  auto v = elt.second->min();
92  if (v < res) { res = v; }
93  }
94  return res;
95  }
96 
97  template < typename GUM_SCALAR >
99  GUM_SCALAR res = 1.0;
100  for (auto elt: factors()) {
101  auto v = elt.second->max();
102  if (v > res) { res = v; }
103  }
104  return res;
105  }
106 
107  template < typename GUM_SCALAR >
109  GUM_SCALAR res = 1.0;
110  for (auto elt: factors()) {
111  auto v = elt.second->minNonZero();
112  if (v < res) { res = v; }
113  }
114  return res;
115  }
116 
117  template < typename GUM_SCALAR >
119  GUM_SCALAR res = 0.0;
120  for (auto elt: factors()) {
121  auto v = elt.second->maxNonOne();
122  if (v > res) { res = v; }
123  }
124  return res;
125  }
126 
127  template < typename GUM_SCALAR >
129  Size param = 0;
130  double dSize = log10DomainSize();
131 
132  for (auto factor: factors())
134 
135  std::stringstream s;
136  s << "MN{nodes: " << size() << ", edges: " << graph().sizeEdges() << ", ";
137 
138  if (dSize > 6)
139  s << "domainSize: 10^" << dSize;
140  else
141  s << "domainSize: " << std::round(std::pow(10.0, dSize));
142 
143  s << ", dim: " << param << "}";
144 
145  return s.str();
146  }
147 
148  template < typename GUM_SCALAR >
151  output << "graph \"";
152 
153  std::string mn_name;
154 
155  try {
156  mn_name = this->property("name");
157  } catch (NotFound&) { mn_name = "no_name"; }
158 
159  output << mn_name << "\" {" << std::endl;
160  output << " graph [bgcolor=transparent,label=\"" << mn_name << "\"];" << std::endl;
161  output << " node [style=filled fillcolor=\"#ffffaa\"];" << std::endl << std::endl;
162 
163  for (auto node: nodes())
164  output << " \"" << variable(node).name() << "\" [comment=\"" << node << ":"
165  << variable(node).toStringWithDescription() << "\"];" << std::endl;
166 
167  output << std::endl;
168 
169  std::string tab = " ";
170 
171  for (auto node: nodes()) {
172  if (neighbours(node).size() > 0) {
173  for (auto nei: neighbours(node)) {
174  if (variable(node).name() < variable(nei).name()) {
175  output << tab << "\"" << variable(node).name() << "\" -- "
176  << "\"" << variable(nei).name() << "\";" << std::endl;
177  }
178  }
179  } else {
180  output << tab << "\"" << variable(node).name() << "\";" << std::endl;
181  }
182  }
183 
184  output << "}" << std::endl;
185 
186  return output.str();
187  }
188 
189 
190  template < typename GUM_SCALAR >
193  std::string mn_name;
194  try {
195  mn_name = this->property("name");
196  } catch (NotFound&) { mn_name = "no_name"; }
197 
198  output << "graph FG_" << mn_name << " {" << std::endl;
199  output << " layout=neato;" << std::endl;
200  output << " graph [bgcolor=transparent,label=\"factor graph for " << mn_name << "\"];"
201  << std::endl;
202 
203  // the variables
204  output << " node [shape=rectangle,margin=0.04,width=0,height=0, "
205  "style=filled,color=\"coral\"];"
206  << std::endl;
207  for (auto nod: nodes()) {
208  output << "\"" << variable(nod).name() << "\";" << std::endl;
209  }
210  output << std::endl;
211 
212  // the factor
213  output << "node[shape = point,width = 0.1,height = 0.1,style = filled,color = "
214  "\"burlywood\"];"
215  << std::endl;
216  for (const auto& kv: factors()) {
217  output << " \"f";
218  for (NodeId nod: kv.first) {
219  output << "#" << variable(nod).name();
220  }
221  output << "\";" << std::endl;
222  }
223 
224  // the link variable--factors
225  output << " edge[len = 0.7];" << std::endl;
226  for (const auto& kv: factors()) {
227  std::string clicname = "\"f";
228  for (NodeId nod: kv.first) {
229  clicname += "#";
230  clicname += variable(nod).name();
231  }
232  clicname += "\"";
233 
234  for (NodeId nod: kv.first)
235  output << " " << clicname << " -- \"" << variable(nod).name() << "\";" << std::endl;
236  }
237  output << "}" << std::endl;
238 
239  return output.str();
240  }
241 
242  template < typename GUM_SCALAR >
243  bool IMarkovNet< GUM_SCALAR >::operator==(const IMarkovNet& from) const {
244  if (size() != from.size()) { return false; }
245 
246  if (sizeEdges() != from.sizeEdges()) { return false; }
247 
248  // alignment of variables between the 2 BNs
250 
251  for (auto node: nodes()) {
252  try {
254  } catch (NotFound&) {
255  // a name is not found in from
256  return false;
257  }
258  }
259 
260  for (const auto& elt: factors()) {
261  const auto& key = elt.first;
262  const auto& factor = *elt.second;
263 
265  for (const auto n: key)
267 
268  if (!from.factors().exists(fromkey)) { return false; }
269 
270  const auto& fromfactor = from.factor(fromkey);
271 
274  for (i.setFirst(); !i.end(); i.inc()) {
275  for (Idx indice = 0; indice < factor.nbrDim(); ++indice) {
276  const DiscreteVariable* p = &(i.variable(indice));
277  j.chgVal(*(alignment.second(p)), i.val(*p));
278  }
279 
280  if (std::pow(factor.get(i) - fromfactor.get(j), (GUM_SCALAR)2) > (GUM_SCALAR)1e-6) {
281  return false;
282  }
283  }
284  }
285  return true;
286  }
287 
288  template < typename GUM_SCALAR >
289  INLINE bool IMarkovNet< GUM_SCALAR >::operator!=(const IMarkovNet& from) const {
290  return !this->operator==(from);
291  }
292 
293  template < typename GUM_SCALAR >
295  output << bn.toString();
296  return output;
297  }
298 
299  template < typename GUM_SCALAR >
300  INLINE const NodeSet&
302  try {
304  } catch (NotFound) { GUM_ERROR(NotFound, "No factor containing the variable <" << name << ">") }
305  }
306 
307  // visit the nodes and add some of node from soids in minimal
308  template < typename GUM_SCALAR >
310  const NodeSet& soids,
311  NodeSet& minimal,
312  NodeSet& alreadyVisited) const {
313  if (alreadyVisited.contains(node)) return;
314  alreadyVisited << node;
315 
316  if (soids.contains(node)) {
317  minimal << node;
318  } else {
319  for (auto neig: graph_.neighbours(node))
321  }
322  }
323 
324 
325  template < typename GUM_SCALAR >
327  if (soids.contains(target)) return NodeSet({target});
328 
329  NodeSet res;
332 
333  for (auto neig: graph_.neighbours(target))
335  return res;
336  }
337 
338  template < typename GUM_SCALAR >
340  const NodeSet& soids) const {
341  NodeSet res;
342  for (auto node: targets) {
344  }
345  return res;
346  }
347 } /* namespace gum */
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:643