aGrUM  0.14.1
BayesNetFactory_tpl.h
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2005 by Christophe GONZALES and Pierre-Henri WUILLEMIN *
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  ***************************************************************************/
28 
29 #define VERBOSITY(x) \
30  { \
31  if (isVerbose()) std::cerr << "[BN factory] " << x << std::endl; \
32  }
33 
34 namespace gum {
35 
36  // Default constructor.
37  // @param bn A pointer over the BayesNet filled by this factory.
38  // @throw DuplicateElement Raised if two variables in bn share the same
39  // name.
40  template < typename GUM_SCALAR >
41  INLINE
43  __parents(0),
44  __impl(0), __bn(bn) {
45  GUM_CONSTRUCTOR(BayesNetFactory);
46  __states.push_back(factory_state::NONE);
47 
48  for (auto node : bn->nodes()) {
49  if (__varNameMap.exists(bn->variable(node).name()))
51  "Name already used: " << bn->variable(node).name());
52 
53  __varNameMap.insert(bn->variable(node).name(), node);
54  }
55 
56  resetVerbose();
57  }
58 
59  // Copy constructor.
60  // The copy will have an exact copy of the constructed BayesNet in source.
61  template < typename GUM_SCALAR >
63  const BayesNetFactory< GUM_SCALAR >& source) :
64  __parents(0),
65  __impl(0), __bn(0) {
66  GUM_CONS_CPY(BayesNetFactory);
67 
68  if (source.state() != factory_state::NONE) {
69  GUM_ERROR(OperationNotAllowed, "Illegal state to proceed make a copy.");
70  } else {
71  __states = source.__states;
72  __bn = new BayesNet< GUM_SCALAR >(*(source.__bn));
73  }
74  }
75 
76  // Destructor
77  template < typename GUM_SCALAR >
79  GUM_DESTRUCTOR(BayesNetFactory);
80 
81  if (__parents != 0) delete __parents;
82 
83  if (__impl != 0) {
84  //@todo better than throwing an exception from inside a destructor but
85  // still ...
86  std::cerr
87  << "[BN factory] Implementation defined for a variable but not used. "
88  "You should call endVariableDeclaration() before "
89  "deleting me."
90  << std::endl;
91  exit(1000);
92  }
93  }
94 
95  // Returns the BayesNet created by this factory.
96  template < typename GUM_SCALAR >
98  return __bn;
99  }
100 
101  template < typename GUM_SCALAR >
102  INLINE const DiscreteVariable&
104  return __bn->variable(id);
105  }
106 
107  // Returns the current state of the factory.
108  template < typename GUM_SCALAR >
111  // This is ok because there is alway at least the state NONE in the stack.
112  return __states.back();
113  }
114 
115  // Returns the NodeId of a variable given it's name.
116  // @throw NotFound Raised if no variable matches the name.
117  template < typename GUM_SCALAR >
118  INLINE NodeId
119  BayesNetFactory< GUM_SCALAR >::variableId(const std::string& name) const {
120  try {
121  return __varNameMap[name];
122  } catch (NotFound&) { GUM_ERROR(NotFound, name); }
123  }
124 
125  // Returns a constant reference on a variable given it's name.
126  // @throw NotFound Raised if no variable matches the name.
127  template < typename GUM_SCALAR >
128  INLINE const DiscreteVariable&
129  BayesNetFactory< GUM_SCALAR >::variable(const std::string& name) const {
130  try {
131  return __bn->variable(variableId(name));
132  } catch (NotFound&) { GUM_ERROR(NotFound, name); }
133  }
134 
135  // Returns the domainSize of the cpt for the node n.
136  // @throw NotFound raised if no such NodeId exists.
137  // @throw OperationNotAllowed if there is no bayesian networks.
138  template < typename GUM_SCALAR >
140  // (from PH) nowhere in the code, I see a check type if (__bn) __bn->. I
141  // assume
142  // __bn is forced not to be nullptr ...
143  return __bn->cpt(n).domainSize();
144  }
145 
146  // Tells the factory that we're in a network declaration.
147  template < typename GUM_SCALAR >
149  if (state() != factory_state::NONE) {
150  __illegalStateError("startNetworkDeclaration");
151  } else {
152  __states.push_back(factory_state::NETWORK);
153  }
154 
155  VERBOSITY("starting network");
156  }
157 
158  // Tells the factory to add a property to the current network.
159  template < typename GUM_SCALAR >
161  const std::string& propName, const std::string& propValue) {
162  __bn->setProperty(propName, propValue);
163  }
164 
165  // Tells the factory that we're out of a network declaration.
166  template < typename GUM_SCALAR >
168  if (state() != factory_state::NETWORK) {
169  __illegalStateError("endNetworkDeclaration");
170  } else {
171  __states.pop_back();
172  }
173 
174  VERBOSITY("network OK");
175  }
176 
177  // Tells the factory that we're in a variable declaration.
178  template < typename GUM_SCALAR >
180  if (state() != factory_state::NONE) {
181  __illegalStateError("startVariableDeclaration");
182  } else {
184  __stringBag.push_back("name");
185  __stringBag.push_back("desc");
186  }
187 
188  VERBOSITY(" starting variable");
189  }
190 
191  // Tells the factory the current variable's name.
192  template < typename GUM_SCALAR >
193  INLINE void
195  if (state() != factory_state::VARIABLE) {
196  __illegalStateError("variableName");
197  } else {
198  if (__varNameMap.exists(name)) {
199  GUM_ERROR(DuplicateElement, "Name already used: " << name);
200  }
201 
202  __foo_flag = true;
203 
204  __stringBag[0] = name;
205  VERBOSITY(" -- variable " << name);
206  }
207  }
208 
209  // Tells the factory the current variable's description.
210  template < typename GUM_SCALAR >
211  INLINE void
213  if (state() != factory_state::VARIABLE) {
214  __illegalStateError("variableDescription");
215  } else {
216  __bar_flag = true;
217  __stringBag[1] = desc;
218  }
219  }
220 
221  // Adds a modality to the current variable.
222  // @throw DuplicateElement If the current variable already has a modality
223  // with the same name.
224  template < typename GUM_SCALAR >
225  INLINE void BayesNetFactory< GUM_SCALAR >::addModality(const std::string& name) {
226  if (state() != factory_state::VARIABLE) {
227  __illegalStateError("addModality");
228  } else {
229  __checkModalityInBag(name);
230  __stringBag.push_back(name);
231  }
232  }
233 
234  // @brief Defines the implementation to use for var's Potential.
235  // @warning The implementation must be empty.
236  // @warning The pointer is always delegated to var's Potential! No copy of it
237  // is made.
238  // @todo When copy of a MultiDimImplementation is available use a copy
239  // behaviour for this method.
240  // @throw NotFound Raised if no variable matches var.
241  // @throw OperationNotAllowed Raised if impl is not empty.
242  // @throw OperationNotAllowed If an implementation is already defined for the
243  // current variable.
244  template < typename GUM_SCALAR >
246  MultiDimAdressable* adressable) {
248  dynamic_cast< MultiDimImplementation< GUM_SCALAR >* >(adressable);
249 
250  if (state() != factory_state::VARIABLE) {
251  __illegalStateError("setVariableCPTImplementation");
252  } else {
253  if (impl == 0) {
255  "An implementation for this variable is already "
256  "defined.");
257  } else if (impl->nbrDim() > 0) {
258  GUM_ERROR(OperationNotAllowed, "This implementation is not empty.");
259  }
260 
261  __impl = impl;
262  }
263  }
264 
265  // Tells the factory that we're out of a variable declaration.
266  template < typename GUM_SCALAR >
268  if (state() != factory_state::VARIABLE) {
269  __illegalStateError("endVariableDeclaration");
270  } else if (__foo_flag && (__stringBag.size() > 3)) {
272  __stringBag[0], (__bar_flag) ? __stringBag[1] : "", 0);
273 
274  for (size_t i = 2; i < __stringBag.size(); ++i) {
275  var->addLabel(__stringBag[i]);
276  }
277 
278  if (__impl != 0) {
279  __varNameMap.insert(var->name(), __bn->add(*var, __impl));
280  __impl = 0;
281  } else {
282  __varNameMap.insert(var->name(), __bn->add(*var));
283  }
284 
285  NodeId retVal = __varNameMap[var->name()];
286 
287  delete var;
288 
289  __resetParts();
290  __states.pop_back();
291 
292  VERBOSITY(" variable " << var->name() << " OK");
293  return retVal;
294  } else {
295  std::stringstream msg;
296  msg << "Not enough modalities (";
297 
298  if (__stringBag.size() > 2) {
299  msg << __stringBag.size() - 2;
300  } else {
301  msg << 0;
302  }
303 
304  msg << ") declared for variable ";
305 
306  if (__foo_flag) {
307  msg << __stringBag[0];
308  } else {
309  msg << "unknown";
310  }
311 
312  __resetParts();
313 
314  __states.pop_back();
315  GUM_ERROR(OperationNotAllowed, msg.str());
316  }
317 
318  // For noisy compilers
319  return 0;
320  }
321 
322  // Tells the factory that we're declaring parents for some variable.
323  // @var The concerned variable's name.
324  template < typename GUM_SCALAR >
326  const std::string& var) {
327  if (state() != factory_state::NONE) {
328  __illegalStateError("startParentsDeclaration");
329  } else {
330  __checkVariableName(var);
331  std::vector< std::string >::iterator iter = __stringBag.begin();
332  __stringBag.insert(iter, var);
333  __states.push_back(factory_state::PARENTS);
334  }
335 
336  VERBOSITY("starting parents for " << var);
337  }
338 
339  // Tells the factory for which variable we're declaring parents.
340  // @var The parent's name.
341  // @throw NotFound Raised if var does not exists.
342  template < typename GUM_SCALAR >
343  INLINE void BayesNetFactory< GUM_SCALAR >::addParent(const std::string& var) {
344  if (state() != factory_state::PARENTS) {
345  __illegalStateError("addParent");
346  } else {
347  __checkVariableName(var);
348  __stringBag.push_back(var);
349  }
350  }
351 
352  // Tells the factory that we've finished declaring parents for some
353  // variable. When parents exist, endParentsDeclaration creates some arcs.
354  // These arcs are created in the inverse order of the order of the parent
355  // specification.
356  template < typename GUM_SCALAR >
358  if (state() != factory_state::PARENTS) {
359  __illegalStateError("endParentsDeclaration");
360  } else {
362 
363  // PLEASE NOTE THAT THE ORDER IS INVERSE
364 
365  for (size_t i = __stringBag.size() - 1; i > 0; --i) {
366  __bn->addArc(__varNameMap[__stringBag[i]], id);
367  VERBOSITY(" adding parent " << __stringBag[i] << " for "
368  << __stringBag[0]);
369  }
370 
371  __resetParts();
372 
373  __states.pop_back();
374  }
375 
376  VERBOSITY("end of parents for " << __stringBag[0]);
377  }
378 
379  // Tells the factory that we're declaring a conditional probability table
380  // for some variable.
381  // @param var The concerned variable's name.
382  template < typename GUM_SCALAR >
384  const std::string& var) {
385  if (state() != factory_state::NONE) {
386  __illegalStateError("startRawProbabilityDeclaration");
387  } else {
388  __checkVariableName(var);
389  __stringBag.push_back(var);
390  __states.push_back(factory_state::RAW_CPT);
391  }
392 
393  VERBOSITY(" cpt starting for " << var);
394  }
395 
396  // @brief Fills the variable's table with the values in rawTable.
397  // Parse the parents in the same order in which they were added to the
398  // variable.
399  // Given a sequence [var, p_1, p_2, ...,p_n-1, p_n] of parents, modalities are
400  // parsed
401  // in the given order (if all p_i are binary):
402  // [0, 0, ..., 0, 0], [0, 0, ..., 0, 1],
403  // [0, 0, ..., 1, 0], [0, 0, ..., 1, 1],
404  // ...,
405  // [1, 1, ..., 1, 0], [1, 1, ..., 1, 1].
406  // @param rawTable The raw table.
407  template < typename GUM_SCALAR >
409  const std::vector< std::string >& variables,
410  const std::vector< float >& rawTable) {
411  if (state() != factory_state::RAW_CPT) {
412  __illegalStateError("rawConditionalTable");
413  } else {
414  __fillProbaWithValuesTable(variables, rawTable);
415  }
416  }
417 
418  template < typename GUM_SCALAR >
420  const std::vector< std::string >& variables,
421  const std::vector< float >& rawTable) {
422  const Potential< GUM_SCALAR >& table = __bn->cpt(__varNameMap[__stringBag[0]]);
423  Instantiation cptInst(table);
424 
426 
427  for (size_t i = 0; i < variables.size(); ++i) {
428  varList.pushBack(&(__bn->variable(__varNameMap[variables[i]])));
429  }
430 
431  // varList.pushFront(&(__bn->variable(__varNameMap[__stringBag[0]])));
432 
433  Idx nbrVar = varList.size();
434 
435  std::vector< Idx > modCounter;
436 
437  // initializing the array
438  for (NodeId i = 0; i < nbrVar; i++) {
439  modCounter.push_back(Idx(0));
440  }
441 
442  Idx j = 0;
443 
444  do {
445  for (NodeId i = 0; i < nbrVar; i++) {
446  cptInst.chgVal(*(varList[i]), modCounter[i]);
447  }
448 
449  if (j < rawTable.size()) {
450  table.set(cptInst, (GUM_SCALAR)rawTable[j]);
451  } else {
452  table.set(cptInst, (GUM_SCALAR)0);
453  }
454 
455  j++;
456  } while (__increment(modCounter, varList));
457  }
458 
459  template < typename GUM_SCALAR >
461  const std::vector< float >& rawTable) {
462  if (state() != factory_state::RAW_CPT) {
463  __illegalStateError("rawConditionalTable");
464  } else {
465  __fillProbaWithValuesTable(rawTable);
466  }
467  }
468 
469  template < typename GUM_SCALAR >
471  const std::vector< float >& rawTable) {
472  const Potential< GUM_SCALAR >& table = __bn->cpt(__varNameMap[__stringBag[0]]);
473 
474  Instantiation cptInst(table);
475 
476  // the main loop is on the first variables. The others are in the right
477  // order.
478  const DiscreteVariable& first = table.variable(0);
479  Idx j = 0;
480 
481  for (cptInst.setFirstVar(first); !cptInst.end(); cptInst.incVar(first)) {
482  for (cptInst.setFirstNotVar(first); !cptInst.end(); cptInst.incNotVar(first))
483  table.set(cptInst,
484  (j < rawTable.size()) ? (GUM_SCALAR)rawTable[j++]
485  : (GUM_SCALAR)0);
486 
487  cptInst.unsetEnd();
488  }
489  }
490 
491  template < typename GUM_SCALAR >
493  std::vector< gum::Idx >& modCounter,
495  bool last = true;
496 
497  for (NodeId j = 0; j < modCounter.size(); j++) {
498  last = (modCounter[j] == (varList[j]->domainSize() - 1)) && last;
499 
500  if (!last) break;
501  }
502 
503  if (last) { return false; }
504 
505  bool add = false;
506 
507  NodeId i = NodeId(varList.size() - 1);
508 
509  do {
510  if (modCounter[i] == (varList[i]->domainSize() - 1)) {
511  modCounter[i] = 0;
512  add = true;
513  } else {
514  modCounter[i] += 1;
515  add = false;
516  }
517 
518  i--;
519  } while (add);
520 
521  return true;
522  }
523 
524  // Tells the factory that we finished declaring a conditional probability
525  // table.
526  template < typename GUM_SCALAR >
528  if (state() != factory_state::RAW_CPT) {
529  __illegalStateError("endRawProbabilityDeclaration");
530  } else {
531  __resetParts();
532  __states.pop_back();
533  }
534 
535  VERBOSITY(" cpt ending for " << __stringBag[0]);
536  }
537 
538  // Tells the factory that we're starting a factorized declaration.
539  template < typename GUM_SCALAR >
541  const std::string& var) {
542  if (state() != factory_state::NONE) {
543  __illegalStateError("startFactorizedProbabilityDeclaration");
544  } else {
545  __checkVariableName(var);
546  std::vector< std::string >::iterator iter = __stringBag.begin();
547  __stringBag.insert(iter, var);
549  }
550  }
551 
552  // Tells the factory that we start an entry of a factorized conditional
553  // probability table.
554  template < typename GUM_SCALAR >
556  if (state() != factory_state::FACT_CPT) {
557  __illegalStateError("startFactorizedEntry");
558  } else {
559  __parents = new Instantiation();
561  }
562  }
563 
564  // Tells the factory that we finished declaring a conditional probability
565  // table.
566  template < typename GUM_SCALAR >
568  if (state() != factory_state::FACT_ENTRY) {
569  __illegalStateError("endFactorizedEntry");
570  } else {
571  delete __parents;
572  __parents = 0;
573  __states.pop_back();
574  }
575  }
576 
577  // Tells the factory on which modality we want to instantiate one of
578  // variable's parent.
579  template < typename GUM_SCALAR >
581  const std::string& parent, const std::string& modality) {
582  if (state() != factory_state::FACT_ENTRY) {
583  __illegalStateError("string");
584  } else {
585  __checkVariableName(parent);
586  Idx id = __checkVariableModality(parent, modality);
587  (*__parents) << __bn->variable(__varNameMap[parent]);
588  __parents->chgVal(__bn->variable(__varNameMap[parent]), id);
589  }
590  }
591 
592  // @brief Gives the values of the variable with respect to precedent
593  // parents modality.
594  // If some parents have no modality set, then we apply values for all
595  // instantiations of that parent.
596  //
597  // This means you can declare a default value for the table by doing
598  // @code
599  // BayesNetFactory factory;
600  // // Do stuff
601  // factory.startVariableDeclaration();
602  // factory.variableName("foo");
603  // factory.endVariableDeclaration();
604  // factory.startParentsDeclaration("foo");
605  // // add parents
606  // factory.endParentsDeclaration();
607  // factory.startFactorizedProbabilityDeclaration("foo");
608  // std::vector<float> seq;
609  // seq.insert(0.4); // if foo true
610  // seq.insert(O.6); // if foo false
611  // factory.setVariableValues(seq); // fills the table with a default value
612  // // finish your stuff
613  // factory.endFactorizedProbabilityDeclaration();
614  // @code
615  // as for rawProba, if value's size is different than the number of modalities
616  // of
617  // the current variable,
618  // we don't use the supplementary values and we fill by 0 the missign values.
619  template < typename GUM_SCALAR >
621  const std::vector< float >& values) {
622  if (state() != factory_state::FACT_ENTRY) {
623  __illegalStateError("setVariableValues");
624  } else {
625  const DiscreteVariable& var = __bn->variable(__varNameMap[__stringBag[0]]);
626  NodeId varId = __varNameMap[__stringBag[0]];
627 
628  if (__parents->domainSize() > 0) {
629  Instantiation inst(__bn->cpt(__varNameMap[var.name()]));
630  inst.setVals(*__parents);
631  // Creating an instantiation containing all the variables not ins
632  // __parents.
633  Instantiation inst_default;
634  inst_default << var;
635 
636  for (auto node : __bn->parents(varId)) {
637  if (!__parents->contains(__bn->variable(node))) {
638  inst_default << __bn->variable(node);
639  }
640  }
641 
642  // Filling the variable's table.
643  for (inst.setFirstIn(inst_default); !inst.end();
644  inst.incIn(inst_default)) {
645  (__bn->cpt(varId))
646  .set(inst,
647  inst.val(var) < values.size() ? (GUM_SCALAR)values[inst.val(var)]
648  : (GUM_SCALAR)0);
649  }
650  } else {
651  Instantiation inst(__bn->cpt(__varNameMap[var.name()]));
652  Instantiation var_inst;
653  var_inst << var;
654 
655  for (var_inst.setFirst(); !var_inst.end(); ++var_inst) {
656  inst.setVals(var_inst);
657 
658  for (inst.setFirstOut(var_inst); !inst.end(); inst.incOut(var_inst)) {
659  (__bn->cpt(varId))
660  .set(inst,
661  inst.val(var) < values.size()
662  ? (GUM_SCALAR)values[inst.val(var)]
663  : (GUM_SCALAR)0);
664  }
665  }
666  }
667  }
668  }
669 
670  template < typename GUM_SCALAR >
672  const std::vector< float >& values) {
673  if (state() != factory_state::FACT_ENTRY) {
674  __illegalStateError("setVariableValues");
675  } else {
676  const DiscreteVariable& var = __bn->variable(__varNameMap[__stringBag[0]]);
677  // Checking consistency between values and var.
678 
679  if (values.size() != var.domainSize()) {
681  var.name()
682  << " : invalid number of modalities: found " << values.size()
683  << " while needed " << var.domainSize());
684  }
685 
687  }
688  }
689 
690  // Tells the factory that we finished declaring a conditional probability
691  // table.
692  template < typename GUM_SCALAR >
693  INLINE void
695  if (state() != factory_state::FACT_CPT) {
696  __illegalStateError("endFactorizedProbabilityDeclaration");
697  } else {
698  __resetParts();
699  __states.pop_back();
700  }
701  }
702 
703  // @brief Define a variable.
704  // You can only call this method is the factory is in the NONE or NETWORK
705  // state.
706  // The variable is added by copy.
707  // @param var The pointer over a DiscreteVariable used to define a new
708  // variable in the built BayesNet.
709  // @throw DuplicateElement Raised if a variable with the same name already
710  // exists.
711  // @throw OperationNotAllowed Raised if redefineParents == false and if table
712  // is not a valid CPT for var in the current state
713  // of the BayesNet.
714  template < typename GUM_SCALAR >
715  INLINE void
717  if ((state() != factory_state::NONE)) {
718  __illegalStateError("setVariable");
719  } else {
720  try {
721  __checkVariableName(var.name());
722  GUM_ERROR(DuplicateElement, "Name already used: " << var.name());
723  } catch (NotFound&) {
724  // The var name is unused
725  __varNameMap.insert(var.name(), __bn->add(var));
726  }
727  }
728  }
729 
730  // @brief Define a variable's CPT.
731  // You can only call this method if the factory is in the NONE or NETWORK
732  // state.
733  // Be careful that table is given to the built BayesNet, so it will be
734  // deleted with it, and you should not directly access it after you call
735  // this method.
736  // When the redefineParents flag is set to true the constructed BayesNet's
737  // DAG is changed to fit with table's definition.
738  // @param var The name of the concerned variable.
739  // @param table A pointer over the CPT used for var.
740  // @param redefineParents If true redefine var's parents to match table's
741  // variables set.
742  //
743  // @throw NotFound Raised if no variable matches var.
744  // @throw OperationNotAllowed Raised if redefineParents == false and if table
745  // is not a valid CPT for var in the current state
746  // of the BayesNet.
747  template < typename GUM_SCALAR >
749  const std::string& varName, MultiDimAdressable* table, bool redefineParents) {
750  auto pot = dynamic_cast< Potential< GUM_SCALAR >* >(table);
751 
752  if (state() != factory_state::NONE) {
753  __illegalStateError("setVariableCPT");
754  } else {
755  __checkVariableName(varName);
756  const DiscreteVariable& var = __bn->variable(__varNameMap[varName]);
757  NodeId varId = __varNameMap[varName];
758  // If we have to change the structure of the BayesNet, then we call a sub
759  // method.
760 
761  if (redefineParents) {
762  __setCPTAndParents(var, pot);
763  } else if (pot->contains(var)) {
764  for (auto node : __bn->parents(varId)) {
765  if (!pot->contains(__bn->variable(node))) {
767  "The CPT is not valid in the current BayesNet.");
768  }
769  }
770 
771  // CPT are created when a variable is added.
772  __bn->_unsafeChangePotential(varId, pot);
773  }
774  }
775  }
776 
777  // Copy operator is illegal, use only copy constructor.
778  template < typename GUM_SCALAR >
781  GUM_ERROR(OperationNotAllowed, "Illegal!");
782  // For noisy compilers
783  return *this;
784  }
785 
786  // Raise an OperationNotAllowed with the message "Illegal state."
787  template < typename GUM_SCALAR >
788  INLINE void
790  std::string msg = "Illegal state call (";
791  msg += s;
792  msg += ") in state ";
793 
794  switch (state()) {
795  case factory_state::NONE: {
796  msg += "NONE";
797  break;
798  }
799 
800  case factory_state::NETWORK: {
801  msg += "NETWORK";
802  break;
803  }
804 
806  msg += "VARIABLE";
807  break;
808  }
809 
810  case factory_state::PARENTS: {
811  msg += "PARENTS";
812  break;
813  }
814 
815  case factory_state::RAW_CPT: {
816  msg += "RAW_CPT";
817  break;
818  }
819 
821  msg += "FACT_CPT";
822  break;
823  }
824 
826  msg += "FACT_ENTRY";
827  break;
828  }
829 
830  default: { msg += "Unknown state"; }
831  }
832 
834  }
835 
836  // Check if a variable with the given name exists, if not raise an NotFound
837  // exception.
838  template < typename GUM_SCALAR >
839  INLINE void
841  if (!__varNameMap.exists(name)) { GUM_ERROR(NotFound, name); }
842  }
843 
844  // Check if var exists and if mod is one of it's modality, if not raise an
845  // NotFound exception.
846  template < typename GUM_SCALAR >
848  const std::string& name, const std::string& mod) {
849  __checkVariableName(name);
850  const DiscreteVariable& var = __bn->variable(__varNameMap[name]);
851 
852  for (Idx i = 0; i < var.domainSize(); ++i) {
853  if (mod == var.label(i)) { return i; }
854  }
855 
856  GUM_ERROR(NotFound, mod);
857  }
858 
859  // Check if in __stringBag there is no other modality with the same name.
860  template < typename GUM_SCALAR >
861  INLINE void
863  for (size_t i = 2; i < __stringBag.size(); ++i) {
864  if (mod == __stringBag[i]) {
865  GUM_ERROR(DuplicateElement, "Label already used: " << mod);
866  }
867  }
868  }
869 
870  // Sub method of setVariableCPT() which redefine the BayesNet's DAG with
871  // respect to table.
872  template < typename GUM_SCALAR >
874  const DiscreteVariable& var, Potential< GUM_SCALAR >* table) {
875  NodeId varId = __varNameMap[var.name()];
876  __bn->_dag.eraseParents(varId);
877 
878  for (auto v : table->variablesSequence()) {
879  if (v != (&var)) {
880  __checkVariableName(v->name());
881  __bn->_dag.addArc(__varNameMap[v->name()], varId);
882  }
883  }
884 
885  // CPT are created when a variable is added.
886  __bn->_unsafeChangePotential(varId, table);
887  }
888 
889  // Reset the different parts used to constructed the BayesNet.
890  template < typename GUM_SCALAR >
892  __foo_flag = false;
893  __bar_flag = false;
894  __stringBag.clear();
895  }
896 } /* namespace gum */
aGrUM&#39;s Potential is a multi-dimensional array with tensor operators.
Definition: potential.h:57
Class representing a Bayesian Network.
Definition: BayesNet.h:76
void endRawProbabilityDeclaration() final
Tells the factory that we finished declaring a conditional probability table.
void variableName(const std::string &name) final
Tells the factory the current variable&#39;s name.
const DiscreteVariable & variable(NodeId id) const final
Returns a gum::DiscreteVariable given its gum::NodeId in the gum::BayesNet.
Definition: BayesNet_tpl.h:190
class LabelizedVariable
Size domainSize() const final
Returns the product of the variable&#39;s domain size in the Instantiation.
void endFactorizedEntry() final
Tells the factory that we end an entry of a factorized conditional probability table.
void setVariableCPTImplementation(MultiDimAdressable *adressable) final
Defines the implementation to use for var&#39;s Potential.
void startFactorizedEntry() final
Tells the factory that we start an entry of a factorized conditional probability table.
#define VERBOSITY(x)
BayesNetFactory(BayesNet< GUM_SCALAR > *bn)
Use this constructor if you want to use an already created BayesNet.
void addParent(const std::string &var) final
Tells the factory for which variable we&#39;re declaring parents.
void setVariable(const DiscreteVariable &var) final
Define a variable.
BayesNet< GUM_SCALAR > * bayesNet()
Returns the BayesNet created by this factory.
factory_state state() const final
Returns the current state of the factory.
void addNetworkProperty(const std::string &propName, const std::string &propValue) final
Tells the factory to add a property to the current network.
void startParentsDeclaration(const std::string &var) final
Tells the factory that we&#39;re declaring parents for some variable.
bool exists(const Key &key) const
Checks whether there exists an element with a given key in the hashtable.
void endParentsDeclaration() final
Tells the factory that we&#39;ve finished declaring parents for some variable.
Instantiation & chgVal(const DiscreteVariable &v, Idx newval)
Assign newval to variable v in the Instantiation.
Base class for discrete random variable.
Generic doubly linked lists.
Definition: list.h:369
void incNotVar(const DiscreteVariable &v)
Operator increment for vars which are not v.
gum is the global namespace for all aGrUM entities
Definition: agrum.h:25
void incVar(const DiscreteVariable &v)
Operator increment for variable v only.
Instantiation & setVals(const Instantiation &i)
Assign the values from i in the Instantiation.
BayesNetFactory< GUM_SCALAR > & operator=(const BayesNetFactory< GUM_SCALAR > &source)
Copy operator is illegal, use only copy constructor.
void setFirstNotVar(const DiscreteVariable &v)
Assign the first values to variables different of v.
void unsetEnd()
Alias for unsetOverflow().
void __fillProbaWithValuesTable(const std::vector< std::string > &variables, const std::vector< float > &rawTable)
Fill a potential from a raw CPT.
Idx val(Idx i) const
Returns the current value of the variable at position i.
virtual Size domainSize() const =0
void incOut(const Instantiation &i)
Operator increment for the variables not in i.
void __illegalStateError(const std::string &s)
Raise an OperationNotAllowed with the message "Illegal state.".
void setFirstIn(const Instantiation &i)
Assign the first values in the Instantiation for the variables in i.
void startFactorizedProbabilityDeclaration(const std::string &var) final
Tells the factory that we&#39;re starting a factorized declaration.
NodeId variableId(const std::string &name) const final
Returns the NodeId of a variable given it&#39;s name.
Headers of the BayesNetFactory class.
void startNetworkDeclaration() final
Tells the factory that we&#39;re in a network declaration.
void setFirstVar(const DiscreteVariable &v)
Assign the first value in the Instantiation for var v.
const NodeGraphPart & nodes() const
Returns a constant reference to the dag of this Bayes Net.
Definition: DAGmodel_inl.h:112
virtual std::string label(Idx i) const =0
get the indice-th label. This method is pure virtual.
HashTable< std::string, NodeId > __varNameMap
Mapping between a declared variable&#39;s name and it&#39;s node id.
Size size() const noexcept
Returns the number of elements in the list.
Definition: list_tpl.h:1848
void startVariableDeclaration() final
Tells the factory that we&#39;re in a variable declaration.
Val & pushBack(const Val &val)
Inserts a new element (a copy) at the end of the chained list.
Definition: list_tpl.h:1589
factory_state
The enumeration of states in which the factory can be in.
BayesNet< GUM_SCALAR > * __bn
The constructed BayesNet.
virtual const DiscreteVariable & variable(Idx) const final
Returns a const ref to the ith var.
Idx __checkVariableModality(const std::string &name, const std::string &mod)
Check if var exists and if mod is one of it&#39;s modality, if not raise an NotFound exception.
NodeId endVariableDeclaration() final
Tells the factory that we&#39;re out of a variable declaration.
void incIn(const Instantiation &i)
Operator increment for the variables in i.
std::vector< factory_state > __states
State stack.
Size cptDomainSize(NodeId n) const final
Returns the domainSize of the cpt for the node n.
void startRawProbabilityDeclaration(const std::string &var) final
Tells the factory that we&#39;re declaring a conditional probability table for some variable.
std::vector< std::string > __stringBag
Just to keep track of strings between two start/end calls.
const DiscreteVariable & varInBN(NodeId id) final
short-cut accessor for a DiscreveVariable in the BN
Abstract base class for all multi dimensionnal addressable.
void setVariableValuesUnchecked(const std::vector< float > &values) final
Gives the values of the variable with respect to precedent parents modality.
virtual Idx nbrDim() const override
Returns the number of vars in the multidimensional container.
Class for assigning/browsing values to tuples of discrete variables.
Definition: instantiation.h:80
void setVariableCPT(const std::string &varName, MultiDimAdressable *table, bool redefineParents) final
Define a variable&#39;s CPT.
void endFactorizedProbabilityDeclaration() final
Tells the factory that we finished declaring a conditional probability table.
bool contains(const DiscreteVariable &v) const final
Indicates whether a given variable belongs to the Instantiation.
bool __foo_flag
Depending on the context this flag is used for some VERY important reasons.
Instantiation * __parents
Used when a factorized CPT is built.
virtual void set(const Instantiation &i, const GUM_SCALAR &value) const final
Default implementation of MultiDimContainer::set().
void setFirst()
Assign the first values to the tuple of the Instantiation.
void variableDescription(const std::string &desc) final
Tells the factory the current variable&#39;s description.
void __checkVariableName(const std::string &name)
Check if a variable with the given name exists, if not raise an NotFound exception.
void rawConditionalTable(const std::vector< std::string > &variables, const std::vector< float > &rawTable) final
Fills the variable&#39;s table with the values in rawTable.
<agrum/multidim/multiDimImplementation.h>
Size Idx
Type for indexes.
Definition: types.h:50
void endNetworkDeclaration() final
Tells the factory that we&#39;re out of a network declaration.
const DiscreteVariable & variable(const std::string &name) const
Returns a constant reference on a variable given it&#39;s name.
void __checkModalityInBag(const std::string &mod)
Check if in __stringBag there is no other modality with the same name.
void addModality(const std::string &name) final
Adds a modality to the current variable.
bool __increment(std::vector< gum::Idx > &modCounter, List< const DiscreteVariable * > &varList)
Increment a modality counter for the __fillProbaWithValuesTable method.
bool __bar_flag
Depending on the context this flag is used for some VERY important reasons.
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Definition: types.h:45
MultiDimImplementation< GUM_SCALAR > * __impl
Implementation of variable between two startVariableDeclaration/endVariableDeclaration calls...
void __setCPTAndParents(const DiscreteVariable &var, Potential< GUM_SCALAR > *table)
Sub method of setVariableCPT() which redefine the BayesNet&#39;s DAG with respect to table.
virtual const Sequence< const DiscreteVariable *> & variablesSequence() const final
Returns a const ref to the sequence of DiscreteVariable*.
value_type & insert(const Key &key, const Val &val)
Adds a new element (actually a copy of this element) into the hash table.
const std::string & name() const
returns the name of the variable
LabelizedVariable & addLabel(const std::string &aLabel)
add a label with a new index (we assume that we will NEVER remove a label)
Size NodeId
Type for node ids.
Definition: graphElements.h:97
void setVariableValues(const std::vector< float > &values) final
same than below with gum::OperationNotAllowed exception if value&#39;s size not OK.
#define GUM_ERROR(type, msg)
Definition: exceptions.h:52
void __resetParts()
Reset the different parts used to constructed the BayesNet.
A factory class to ease BayesNet construction.
Definition: BayesNet.h:43
bool end() const
Returns true if the Instantiation reached the end.
virtual ~BayesNetFactory()
Destructor.
void setFirstOut(const Instantiation &i)
Assign the first values in the Instantiation for the variables not in i.
void setParentModality(const std::string &parent, const std::string &modality) final
Tells the factory on which modality we want to instantiate one of variable&#39;s parent.