aGrUM  0.13.2
BIFWriter_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  ***************************************************************************/
20 
21 #ifndef DOXYGEN_SHOULD_SKIP_THIS
22 
23 # include <agrum/agrum.h>
24 
25 // to ease parsing in IDE
27 
28 namespace gum {
29 
30  /* =========================================================================*/
31  /* === GUM_BIF_WRITER === */
32  /* =========================================================================*/
33  // Default constructor.
34  template < typename GUM_SCALAR >
36  GUM_CONSTRUCTOR(BIFWriter);
37  }
38 
39  // Default destructor.
40  template < typename GUM_SCALAR >
42  GUM_DESTRUCTOR(BIFWriter);
43  }
44 
45  //
46  // Writes a Bayesian Network in the output stream using the BIF format.
47  //
48  // @param ouput The output stream.
49  // @param bn The Bayesian Network writen in output.
50  // @throws Raised if an I/O error occurs.
51  template < typename GUM_SCALAR >
52  INLINE void BIFWriter< GUM_SCALAR >::write(std::ostream& output,
53  const IBayesNet< GUM_SCALAR >& bn) {
54  if (!output.good()) {
55  GUM_ERROR(IOError, "Stream states flags are not all unset.");
56  }
57 
58  output << __header(bn) << std::endl;
59 
60  for (const auto node : bn.nodes()) {
61  output << __variableBloc(bn.variable(node)) << std::endl;
62  }
63 
64  for (const auto node : bn.nodes()) {
65  const Potential< GUM_SCALAR >& proba = bn.cpt(node);
66  output << __variableCPT(proba);
67  }
68 
69  output << std::endl;
70 
71  output.flush();
72 
73  if (output.fail()) { GUM_ERROR(IOError, "Writting in the ostream failed."); }
74  }
75 
76  // Writes a Bayesian Network in the referenced file using the BIF format.
77  // If the file doesn't exists, it is created.
78  // If the file exists, it's content will be erased.
79  //
80  // @param filePath The path to the file used to write the Bayesian Network.
81  // @param bn The Bayesian Network writed in the file.
82  // @throws Raised if an I/O error occurs.
83  template < typename GUM_SCALAR >
84  INLINE void BIFWriter< GUM_SCALAR >::write(const std::string& filePath,
85  const IBayesNet< GUM_SCALAR >& bn) {
86  std::ofstream output(filePath.c_str(), std::ios_base::trunc);
87 
88  if (!output.good()) {
89  GUM_ERROR(IOError, "Stream states flags are not all unset.");
90  }
91 
92  output << __header(bn) << std::endl;
93 
94  for (const auto node : bn.nodes()) {
95  output << __variableBloc(bn.variable(node)) << std::endl;
96  }
97 
98  for (const auto node : bn.nodes()) {
99  const Potential< GUM_SCALAR >& proba = bn.cpt(node);
100  output << __variableCPT(proba);
101  }
102 
103  output << std::endl;
104 
105  output.flush();
106  output.close();
107 
108  if (output.fail()) { GUM_ERROR(IOError, "Writting in the ostream failed."); }
109  }
110 
111  // Returns a bloc defining a variable's CPT in the BIF format.
112  template < typename GUM_SCALAR >
113  INLINE std::string
114  BIFWriter< GUM_SCALAR >::__variableCPT(const Potential< GUM_SCALAR >& cpt) {
115  std::stringstream str;
116  std::string tab = " "; // poor tabulation
117 
118  if (cpt.nbrDim() == 1) {
119  Instantiation inst(cpt);
120  str << "probability (" << cpt.variable(0).name() << ") {" << std::endl;
121  str << tab << "default";
122 
123  for (inst.setFirst(); !inst.end(); ++inst) {
124  str << " " << cpt[inst];
125  }
126 
127  str << ";" << std::endl << "}" << std::endl;
128  } else if (cpt.domainSize() > 1) {
129  Instantiation inst(cpt);
130  Instantiation condVars; // Instantiation on the conditioning variables
131  const Sequence< const DiscreteVariable* >& varsSeq = cpt.variablesSequence();
132  str << "probability (" << (varsSeq[(Idx)0])->name() << " | ";
133 
134  for (Idx i = 1; i < varsSeq.size() - 1; i++) {
135  str << varsSeq[i]->name() << ", ";
136  condVars << *(varsSeq[i]);
137  }
138 
139  str << varsSeq[varsSeq.size() - 1]->name() << ") {" << std::endl;
140 
141  condVars << *(varsSeq[varsSeq.size() - 1]);
142 
143  for (inst.setFirstIn(condVars); !inst.end(); inst.incIn(condVars)) {
144  str << tab << "(" << __variablesLabels(varsSeq, inst) << ")";
145  // Writing the probabilities of the variable
146 
147  for (inst.setFirstOut(condVars); !inst.end(); inst.incOut(condVars)) {
148  str << " " << cpt[inst];
149  }
150 
151  str << ";" << std::endl;
152 
153  inst.unsetOverflow();
154  }
155 
156  str << "}" << std::endl;
157  }
158 
159  return str.str();
160  }
161 
162  // Returns the header of the BIF file.
163  template < typename GUM_SCALAR >
164  INLINE std::string
165  BIFWriter< GUM_SCALAR >::__header(const IBayesNet< GUM_SCALAR >& bn) {
166  std::stringstream str;
167  std::string tab = " "; // poor tabulation
168  str << "network \"" << bn.propertyWithDefault("name", "unnamedBN") << "\" {"
169  << std::endl;
170  str << "// written by aGrUM " << GUM_VERSION << std::endl;
171  str << "}" << std::endl;
172  return str.str();
173  }
174 
175  // Returns a bloc defining a variable in the BIF format.
176  template < typename GUM_SCALAR >
177  INLINE std::string
178  BIFWriter< GUM_SCALAR >::__variableBloc(const DiscreteVariable& var) {
179  std::stringstream str;
180  std::string tab = " "; // poor tabulation
181  str << "variable " << var.name() << " {" << std::endl;
182  str << tab << "type discrete[" << var.domainSize() << "] {";
183 
184  for (Idx i = 0; i < var.domainSize() - 1; i++) {
185  str << var.label(i) << ", ";
186  }
187 
188  str << var.label(var.domainSize() - 1) << "};" << std::endl;
189 
190  str << "}" << std::endl;
191  return str.str();
192  }
193 
194  // Returns the modalities labels of the variables in varsSeq
195  template < typename GUM_SCALAR >
197  const Sequence< const DiscreteVariable* >& varsSeq,
198  const Instantiation& inst) {
199  std::stringstream str;
200  const DiscreteVariable* varPtr = nullptr;
201 
202  for (Idx i = 1; i < varsSeq.size() - 1; i++) {
203  varPtr = varsSeq[i];
204  str << varPtr->label(inst.val(*varPtr)) << ", ";
205  }
206 
207  varPtr = varsSeq[varsSeq.size() - 1];
208 
209  str << varPtr->label(inst.val(*varPtr));
210  return str.str();
211  }
212 
213 } /* namespace gum */
214 
215 #endif // DOXYGEN_SHOULD_SKIP_THIS
~BIFWriter() final
Destructor.
std::string __variableBloc(const DiscreteVariable &var)
void write(std::ostream &output, const IBayesNet< GUM_SCALAR > &bn) final
Writes a Bayesian Network in the output stream using the BIF format.
gum is the global namespace for all aGrUM entities
Definition: agrum.h:25
std::string __variableCPT(const Potential< GUM_SCALAR > &cpt)
Definition of classe for BIF file output manipulation.
std::string __variablesLabels(const Sequence< const DiscreteVariable * > &varsSeq, const Instantiation &inst)
std::string __header(const IBayesNet< GUM_SCALAR > &bn)
unsigned long Idx
Type for indexes.
Definition: types.h:43
BIFWriter()
Default constructor.
#define GUM_ERROR(type, msg)
Definition: exceptions.h:66