aGrUM  0.20.2
a C++ library for (probabilistic) graphical models
UAIBNReader_tpl.h
Go to the documentation of this file.
1 /**
2  *
3  * Copyright 2005-2020 Pierre-Henri WUILLEMIN(@LIP6) & Christophe GONZALES(@AMU)
4  * 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 #ifndef DOXYGEN_SHOULD_SKIP_THIS
23 
24 namespace gum {
25 
26  template < typename GUM_SCALAR >
27  UAIBNReader< GUM_SCALAR >::UAIBNReader(BayesNet< GUM_SCALAR >* bn,
28  const std::string& filename) :
31  bn__ = bn;
33  parseDone__ = false;
34 
35  ioerror__ = false;
36 
37  try {
40  } catch (IOError&) { ioerror__ = true; }
41  }
42 
43  template < typename GUM_SCALAR >
46 
47  if (!ioerror__) {
48  // this could lead to memory leak !!
49  if (parser__) delete (parser__);
50 
51  if (scanner__) delete (scanner__);
52  }
53  }
54 
55  template < typename GUM_SCALAR >
57  if (ioerror__) { GUM_ERROR(gum::IOError, "No such file " + streamName()); }
58 
59  return *scanner__;
60  }
61 
62  template < typename GUM_SCALAR >
63  INLINE const std::string& UAIBNReader< GUM_SCALAR >::streamName() const {
64  return streamName__;
65  }
66 
67  template < typename GUM_SCALAR >
68  INLINE bool UAIBNReader< GUM_SCALAR >::trace() const {
69  return traceScanning__;
70  }
71 
72  template < typename GUM_SCALAR >
73  INLINE void UAIBNReader< GUM_SCALAR >::trace(bool b) {
75  scanner().setTrace(b);
76  }
77 
78  template < typename GUM_SCALAR >
80  if (ioerror__) { GUM_ERROR(gum::IOError, "No such file " + streamName()); }
81 
82  if (!parseDone__) {
83  try {
84  parser__->Parse();
85  parseDone__ = true;
87  } catch (gum::Exception& e) {
89  return 1 + parser__->errors().error_count;
90  }
91  }
92 
93  return (parser__->errors().error_count);
94  }
95 
96  template < typename GUM_SCALAR >
98  std::vector< std::tuple< float, int, int, int > > quartets) {
99  Idx current;
100  Size max = quartets.size();
101  if (max == 0) {
102  addWarning__(1, 1, "Empty BayesNet");
103  return;
104  }
105 
106  auto isInt = [&]() -> bool {
107  return (std::get< 0 >(quartets[current]) == -1);
108  };
109  auto lig = [&]() -> int {
110  return std::get< 2 >(quartets[current]);
111  };
112  auto col = [&]() -> int {
113  return std::get< 3 >(quartets[current]);
114  };
115 
116  auto getInt = [&]() -> int {
117  if (!isInt()) this->addFatalError__(lig(), col(), "int expected");
118  return std::get< 1 >(quartets[current]);
119  };
120  auto getVal = [&]() -> GUM_SCALAR {
121  return (isInt()) ? (std::get< 1 >(quartets[current]))
122  : (std::get< 0 >(quartets[current]));
123  };
124  auto incCurrent = [&]() {
125  current += 1;
126  if (current >= max)
127  this->addFatalError__(lig(), col(), "Not enough data in UAI file");
128  };
129 
130  current = 0;
131  Size nbrNode = (Size)getInt();
132 
133  for (NodeId i = 0; i < nbrNode; i++) {
134  incCurrent();
135  int mod = getInt();
136  if (mod < 2)
137  addError__(lig(), col(), "Number of modalities should be greater than 2.");
139  }
140 
141  incCurrent();
142  Size nbrPot = (Size)getInt();
143  if (nbrPot != nbrNode)
144  addWarning__(lig(),
145  col(),
146  "Number of CPTs should be the same as number of nodes");
147 
148  Set< NodeId > s;
149  for (NodeId i = 0; i < nbrPot; i++) {
150  incCurrent();
151  Size nbrPar = (Size)getInt();
152  if (nbrPar == 0) addError__(lig(), col(), "0 is not possible here");
153 
154  std::vector< NodeId > papas;
155  for (NodeId j = 1; j < nbrPar; j++) {
156  incCurrent();
157  NodeId papa = (NodeId)getInt();
158  if (papa >= nbrNode)
159  addError__(lig(), col(), "Not enough variables in the BayesNet");
161  }
162 
163  incCurrent();
164  NodeId nodePot = (Size)getInt();
165  if (nodePot >= nbrNode)
166  addError__(lig(), col(), "Not enough variables in the BayesNet");
167  if (s.contains(nodePot)) addError__(lig(), col(), "Parents already defined");
168  s.insert(nodePot);
169 
170  for (const auto papa: papas) {
171  bn__->addArc(papa, nodePot);
172  }
173  }
174 
175  std::vector< GUM_SCALAR > v;
176  for (NodeId i = 0; i < nbrPot; i++) {
177  incCurrent();
178  Size nbrParam = (Size)getInt();
179  if (nbrParam != bn__->cpt(i).domainSize())
181  col(),
182  "Size does not fit between parents and parameters");
183  for (Idx j = 0; j < nbrParam; j++) {
184  incCurrent();
185  v.push_back(getVal());
186  }
187  bn__->cpt(i).fillWith(v);
188  v.clear();
189  }
190 
191  if (current != max - 1) addError__(lig(), col(), "Too many data in this file");
192  }
193 
194  // @{
195  // publishing Errors API
196  template < typename GUM_SCALAR >
198  if (parseDone__)
199  return parser__->errors().error(i).line;
200  else {
201  GUM_ERROR(OperationNotAllowed, "UAI file not parsed yet");
202  }
203  }
204 
205  template < typename GUM_SCALAR >
207  if (parseDone__)
208  return parser__->errors().error(i).column;
209  else {
210  GUM_ERROR(OperationNotAllowed, "UAI file not parsed yet");
211  }
212  }
213 
214  template < typename GUM_SCALAR >
216  if (parseDone__)
217  return parser__->errors().error(i).is_error;
218  else {
219  GUM_ERROR(OperationNotAllowed, "UAI file not parsed yet");
220  }
221  }
222 
223  template < typename GUM_SCALAR >
225  if (parseDone__)
226  return parser__->errors().error(i).msg;
227  else {
228  GUM_ERROR(OperationNotAllowed, "UAI file not parsed yet");
229  }
230  }
231 
232  template < typename GUM_SCALAR >
234  if (parseDone__)
236  else {
237  GUM_ERROR(OperationNotAllowed, "UAI file not parsed yet");
238  }
239  }
240 
241  template < typename GUM_SCALAR >
242  INLINE void
244  if (parseDone__)
246  else {
247  GUM_ERROR(OperationNotAllowed, "UAI file not parsed yet");
248  }
249  }
250 
251  template < typename GUM_SCALAR >
253  if (parseDone__)
255  else {
256  GUM_ERROR(OperationNotAllowed, "UAI file not parsed yet");
257  }
258  }
259 
260  template < typename GUM_SCALAR >
262  if (parseDone__)
264  else {
265  GUM_ERROR(OperationNotAllowed, "UAI file not parsed yet");
266  }
267  }
268 
269  template < typename GUM_SCALAR >
271  return (!parseDone__) ? (Size)0 : parser__->errors().error_count;
272  }
273 
274  template < typename GUM_SCALAR >
276  return (!parseDone__) ? (Size)0 : parser__->errors().warning_count;
277  }
278 
279  template < typename GUM_SCALAR >
281  Idx col,
282  const std::string& s) {
285  }
286  template < typename GUM_SCALAR >
288  Idx col,
289  const std::string& s) {
291  }
292  template < typename GUM_SCALAR >
294  Idx col,
295  const std::string& s) {
297  }
298 
299  // @}
300 } // namespace gum
301 
302 #endif // DOXYGEN_SHOULD_SKIP_THIS
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:669