aGrUM  0.20.3
a C++ library for (probabilistic) graphical models
UAIBNReader_tpl.h
Go to the documentation of this file.
1 /**
2  *
3  * Copyright (c) 2005-2021 by 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, const std::string& filename) :
30  _bn_ = bn;
32  _parseDone_ = false;
33 
34  _ioerror_ = false;
35 
36  try {
39  } catch (IOError&) { _ioerror_ = true; }
40  }
41 
42  template < typename GUM_SCALAR >
45 
46  if (!_ioerror_) {
47  // this could lead to memory leak !!
48  if (_parser_) delete (_parser_);
49 
50  if (_scanner_) delete (_scanner_);
51  }
52  }
53 
54  template < typename GUM_SCALAR >
56  if (_ioerror_) { GUM_ERROR(gum::IOError, "No such file " + streamName()) }
57 
58  return *_scanner_;
59  }
60 
61  template < typename GUM_SCALAR >
62  INLINE const std::string& UAIBNReader< GUM_SCALAR >::streamName() const {
63  return _streamName_;
64  }
65 
66  template < typename GUM_SCALAR >
67  INLINE bool UAIBNReader< GUM_SCALAR >::trace() const {
68  return _traceScanning_;
69  }
70 
71  template < typename GUM_SCALAR >
72  INLINE void UAIBNReader< GUM_SCALAR >::trace(bool b) {
74  scanner().setTrace(b);
75  }
76 
77  template < typename GUM_SCALAR >
79  if (_ioerror_) { GUM_ERROR(gum::IOError, "No such file " + streamName()) }
80 
81  if (!_parseDone_) {
82  try {
83  _parser_->Parse();
84  _parseDone_ = true;
86  } catch (gum::Exception& e) {
88  return 1 + _parser_->errors().error_count;
89  }
90  }
91 
92  return (_parser_->errors().error_count);
93  }
94 
95  template < typename GUM_SCALAR >
97  std::vector< std::tuple< float, int, int, int > > quartets) {
98  Idx current;
99  Size max = quartets.size();
100  if (max == 0) {
101  _addWarning_(1, 1, "Empty BayesNet");
102  return;
103  }
104 
105  auto isInt = [&]() -> bool {
106  return (std::get< 0 >(quartets[current]) == -1);
107  };
108  auto lig = [&]() -> int {
109  return std::get< 2 >(quartets[current]);
110  };
111  auto col = [&]() -> int {
112  return std::get< 3 >(quartets[current]);
113  };
114 
115  auto getInt = [&]() -> int {
116  if (!isInt()) this->_addFatalError_(lig(), col(), "int expected");
117  return std::get< 1 >(quartets[current]);
118  };
119  auto getVal = [&]() -> GUM_SCALAR {
120  return (isInt()) ? (std::get< 1 >(quartets[current])) : (std::get< 0 >(quartets[current]));
121  };
122  auto incCurrent = [&]() {
123  current += 1;
124  if (current >= max) this->_addFatalError_(lig(), col(), "Not enough data in UAI file");
125  };
126 
127  current = 0;
128  Size nbrNode = (Size)getInt();
129 
130  for (NodeId i = 0; i < nbrNode; i++) {
131  incCurrent();
132  int mod = getInt();
133  if (mod < 2) _addError_(lig(), col(), "Number of modalities should be greater than 2.");
135  }
136 
137  incCurrent();
138  Size nbrPot = (Size)getInt();
139  if (nbrPot != nbrNode)
140  _addWarning_(lig(), col(), "Number of CPTs should be the same as number of nodes");
141 
142  Set< NodeId > s;
143  for (NodeId i = 0; i < nbrPot; i++) {
144  incCurrent();
145  Size nbrPar = (Size)getInt();
146  if (nbrPar == 0) _addError_(lig(), col(), "0 is not possible here");
147 
148  std::vector< NodeId > papas;
149  for (NodeId j = 1; j < nbrPar; j++) {
150  incCurrent();
151  NodeId papa = (NodeId)getInt();
152  if (papa >= nbrNode) _addError_(lig(), col(), "Not enough variables in the BayesNet");
154  }
155 
156  incCurrent();
157  NodeId nodePot = (Size)getInt();
158  if (nodePot >= nbrNode) _addError_(lig(), col(), "Not enough variables in the BayesNet");
159  if (s.contains(nodePot)) _addError_(lig(), col(), "Parents already defined");
160  s.insert(nodePot);
161 
162  for (const auto papa: papas) {
163  _bn_->addArc(papa, nodePot);
164  }
165  }
166 
167  std::vector< GUM_SCALAR > v;
168  for (NodeId i = 0; i < nbrPot; i++) {
169  incCurrent();
170  Size nbrParam = (Size)getInt();
171  if (nbrParam != _bn_->cpt(i).domainSize())
172  _addFatalError_(lig(), col(), "Size does not fit between parents and parameters");
173  for (Idx j = 0; j < nbrParam; j++) {
174  incCurrent();
175  v.push_back(getVal());
176  }
177  _bn_->cpt(i).fillWith(v);
178  v.clear();
179  }
180 
181  if (current != max - 1) _addError_(lig(), col(), "Too many data in this file");
182  }
183 
184  // @{
185  // publishing Errors API
186  template < typename GUM_SCALAR >
188  if (_parseDone_)
189  return _parser_->errors().error(i).line;
190  else {
191  GUM_ERROR(OperationNotAllowed, "UAI file not parsed yet")
192  }
193  }
194 
195  template < typename GUM_SCALAR >
197  if (_parseDone_)
198  return _parser_->errors().error(i).column;
199  else {
200  GUM_ERROR(OperationNotAllowed, "UAI file not parsed yet")
201  }
202  }
203 
204  template < typename GUM_SCALAR >
206  if (_parseDone_)
207  return _parser_->errors().error(i).is_error;
208  else {
209  GUM_ERROR(OperationNotAllowed, "UAI file not parsed yet")
210  }
211  }
212 
213  template < typename GUM_SCALAR >
215  if (_parseDone_)
216  return _parser_->errors().error(i).msg;
217  else {
218  GUM_ERROR(OperationNotAllowed, "UAI file not parsed yet")
219  }
220  }
221 
222  template < typename GUM_SCALAR >
224  if (_parseDone_)
226  else {
227  GUM_ERROR(OperationNotAllowed, "UAI file not parsed yet")
228  }
229  }
230 
231  template < typename GUM_SCALAR >
233  if (_parseDone_)
235  else {
236  GUM_ERROR(OperationNotAllowed, "UAI file not parsed yet")
237  }
238  }
239 
240  template < typename GUM_SCALAR >
242  if (_parseDone_)
244  else {
245  GUM_ERROR(OperationNotAllowed, "UAI file not parsed yet")
246  }
247  }
248 
249  template < typename GUM_SCALAR >
251  if (_parseDone_)
253  else {
254  GUM_ERROR(OperationNotAllowed, "UAI file not parsed yet")
255  }
256  }
257 
258  template < typename GUM_SCALAR >
260  return (!_parseDone_) ? (Size)0 : _parser_->errors().error_count;
261  }
262 
263  template < typename GUM_SCALAR >
265  return (!_parseDone_) ? (Size)0 : _parser_->errors().warning_count;
266  }
267 
268  template < typename GUM_SCALAR >
272  }
273  template < typename GUM_SCALAR >
276  }
277  template < typename GUM_SCALAR >
280  }
281 
282  // @}
283 } // namespace gum
284 
285 #endif // DOXYGEN_SHOULD_SKIP_THIS
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:643