aGrUM  0.16.0
netWriter_tpl.h
Go to the documentation of this file.
1 
23 #ifndef DOXYGEN_SHOULD_SKIP_THIS
24 
25 // to ease parsing in IDE
27 
28 namespace gum {
29  /* =========================================================================*/
30  /* === GUM_BN_WRITER === */
31  /* =========================================================================*/
32  // Default constructor.
33  template < typename GUM_SCALAR >
35  GUM_CONSTRUCTOR(NetWriter);
36  }
37 
38  // Default destructor.
39  template < typename GUM_SCALAR >
41  GUM_DESTRUCTOR(NetWriter);
42  }
43 
44  //
45  // Writes a Bayesian Network in the output stream using the BN format.
46  //
47  // @param ouput The output stream.
48  // @param bn The Bayesian Network writen in output.
49  // @throws Raised if an I/O error occurs.
50  template < typename GUM_SCALAR >
51  INLINE void NetWriter< GUM_SCALAR >::write(std::ostream& output,
52  const IBayesNet< GUM_SCALAR >& bn) {
53  if (!output.good())
54  GUM_ERROR(IOError, "Stream states flags are not all unset.");
55 
56  output << __header(bn) << std::endl;
57 
58  for (auto node : bn.nodes())
59  output << __variableBloc(bn.variable(node)) << std::endl;
60 
61  for (auto node : bn.nodes())
62  output << __variableCPT(bn.cpt(node));
63 
64  output << std::endl;
65 
66  output.flush();
67 
68  if (output.fail()) { GUM_ERROR(IOError, "Writting in the ostream failed."); }
69  }
70 
71  // Writes a Bayesian Network in the referenced file using the BN format.
72  // If the file doesn't exists, it is created.
73  // If the file exists, it's content will be erased.
74  //
75  // @param filePath The path to the file used to write the Bayesian Network.
76  // @param bn The Bayesian Network writed in the file.
77  // @throws Raised if an I/O error occurs.
78  template < typename GUM_SCALAR >
79  INLINE void NetWriter< GUM_SCALAR >::write(const std::string& filePath,
80  const IBayesNet< GUM_SCALAR >& bn) {
81  std::ofstream output(filePath.c_str(), std::ios_base::trunc);
82 
83  if (!output.good()) {
84  GUM_ERROR(IOError, "Stream states flags are not all unset.");
85  }
86 
87  output << __header(bn) << std::endl;
88 
89  for (auto node : bn.nodes())
90  output << __variableBloc(bn.variable(node)) << std::endl;
91 
92  for (auto node : bn.nodes())
93  output << __variableCPT(bn.cpt(node));
94 
95  output << std::endl;
96 
97  output.flush();
98  output.close();
99 
100  if (output.fail()) { GUM_ERROR(IOError, "Writting in the ostream failed."); }
101  }
102 
103  // Returns a bloc defining a variable's CPT in the BN format.
104  template < typename GUM_SCALAR >
105  INLINE std::string
106  NetWriter< GUM_SCALAR >::__variableCPT(const Potential< GUM_SCALAR >& cpt) {
107  std::stringstream str;
108  std::string tab = " "; // poor tabulation
109 
110  Instantiation inst(cpt);
111  if (cpt.nbrDim() == 1) {
112  str << "potential (" << cpt.variable(0).name() << ") {" << std::endl
113  << tab << "data = ( ";
114 
115  for (inst.setFirst(); !inst.end(); ++inst) {
116  str << " " << cpt[inst];
117  }
118 
119  str << ");";
120  } else { // cpt.domainSize() > 1
121  const Sequence< const DiscreteVariable* >& varsSeq = cpt.variablesSequence();
122 
123  Instantiation conds;
124  for (Idx i = 1; i < varsSeq.size(); i++)
125  conds.add(*varsSeq[i]);
126 
127  str << "potential ( " << (varsSeq[(Idx)0])->name() << " | ";
128  for (Idx i = 1; i < varsSeq.size(); i++)
129  str << varsSeq[i]->name() << " ";
130  str << ") {" << std::endl << tab << "data = \n";
131 
132  std::string comment;
133  conds.setFirst();
134  while (true) {
135  str << tab << "(";
136  for (Idx i = 0; i < conds.nbrDim(); i++) {
137  if (conds.val(i) != 0) break;
138  str << "(";
139  }
140 
141  inst.setVals(conds);
142  for (inst.setFirstVar(*varsSeq[0]); !inst.end(); inst.incVar(*varsSeq[0]))
143  str << tab << cpt[inst];
144 
145  comment = tab + "% ";
146  for (Idx i = 0; i < conds.nbrDim(); i++) {
147  comment += conds.variable(i).name() + "="
148  + conds.variable(i).label(conds.val(i)) + tab;
149  }
150 
151  ++conds;
152  if (conds.end()) {
153  for (Idx i = 0; i < inst.nbrDim(); i++) {
154  str << ")";
155  }
156  str << ";" << comment;
157  break;
158  } else {
159  for (Idx i = 0; i < conds.nbrDim(); i++) {
160  str << ")";
161  if (conds.val(i) != 0) break;
162  }
163  str << comment << "\n";
164  }
165  }
166  }
167  str << "\n}\n" << std::endl;
168  return str.str();
169  }
170 
171  // Returns the header of the BN file.
172  template < typename GUM_SCALAR >
173  INLINE std::string
174  NetWriter< GUM_SCALAR >::__header(const IBayesNet< GUM_SCALAR >& bn) {
175  std::stringstream str;
176  std::string tab = " "; // poor tabulation
177  str << std::endl << "net {" << std::endl;
178  str << " name = " << bn.propertyWithDefault("name", "unnamedBN") << ";"
179  << std::endl;
180  str << " software = \"aGrUM " << GUM_VERSION << "\";" << std::endl;
181  str << " node_size = (50 50);" << std::endl;
182  str << "}" << std::endl;
183  return str.str();
184  }
185 
186  // Returns a bloc defining a variable in the BN format.
187  template < typename GUM_SCALAR >
188  INLINE std::string
189  NetWriter< GUM_SCALAR >::__variableBloc(const DiscreteVariable& var) {
190  std::stringstream str;
191  std::string tab = " "; // poor tabulation
192  str << "node " << var.name() << " {" << std::endl;
193  str << tab << "states = (";
194 
195  for (Idx i = 0; i < var.domainSize(); i++) {
196  str << var.label(i) << " ";
197  }
198 
199  str << ");" << std::endl;
200  str << tab << "label = \"" << var.name() << "\";" << std::endl;
201  str << tab << "ID = \"" << var.name() << "\";" << std::endl;
202 
203  str << "}" << std::endl;
204 
205  return str.str();
206  }
207 } /* namespace gum */
208 
209 #endif // DOXYGEN_SHOULD_SKIP_THIS
NetWriter()
Default constructor.
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
Definition: agrum.h:25
std::string __header(const IBayesNet< GUM_SCALAR > &bn)
void write(std::ostream &output, const IBayesNet< GUM_SCALAR > &bn) final
Writes a Bayesian Network in the output stream using the BN format.
~NetWriter() final
Destructor.
std::string __variableCPT(const Potential< GUM_SCALAR > &cpt)
Size Idx
Type for indexes.
Definition: types.h:53
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
std::string __variableBloc(const DiscreteVariable &var)
#define GUM_ERROR(type, msg)
Definition: exceptions.h:55