aGrUM  0.13.2
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()))
50  GUM_ERROR(DuplicateElement, bn->variable(node).name());
51 
52  __varNameMap.insert(bn->variable(node).name(), node);
53  }
54 
55  resetVerbose();
56  }
57 
58  // Copy constructor.
59  // The copy will have an exact copy of the constructed BayesNet in source.
60  template < typename GUM_SCALAR >
62  const BayesNetFactory< GUM_SCALAR >& source) :
63  __parents(0),
64  __impl(0), __bn(0) {
65  GUM_CONS_CPY(BayesNetFactory);
66 
67  if (source.state() != factory_state::NONE) {
68  GUM_ERROR(OperationNotAllowed, "Illegal state to proceed make a copy.");
69  } else {
70  __states = source.__states;
71  __bn = new BayesNet< GUM_SCALAR >(*(source.__bn));
72  }
73  }
74 
75  // Destructor
76  template < typename GUM_SCALAR >
78  GUM_DESTRUCTOR(BayesNetFactory);
79 
80  if (__parents != 0) delete __parents;
81 
82  if (__impl != 0) {
83  //@todo better than throwing an exception from inside a destructor but
84  // still ...
85  std::cerr
86  << "[BN factory] Implementation defined for a variable but not used. "
87  "You should call endVariableDeclaration() before "
88  "deleting me."
89  << std::endl;
90  exit(1000);
91  }
92  }
93 
94  // Returns the BayesNet created by this factory.
95  template < typename GUM_SCALAR >
97  return __bn;
98  }
99 
100  template < typename GUM_SCALAR >
101  INLINE const DiscreteVariable&
103  return __bn->variable(id);
104  }
105 
106  // Returns the current state of the factory.
107  template < typename GUM_SCALAR >
110  // This is ok because there is alway at least the state NONE in the stack.
111  return __states.back();
112  }
113 
114  // Returns the NodeId of a variable given it's name.
115  // @throw NotFound Raised if no variable matches the name.
116  template < typename GUM_SCALAR >
117  INLINE NodeId
118  BayesNetFactory< GUM_SCALAR >::variableId(const std::string& name) const {
119  try {
120  return __varNameMap[name];
121  } catch (NotFound&) { GUM_ERROR(NotFound, name); }
122  }
123 
124  // Returns a constant reference on a variable given it's name.
125  // @throw NotFound Raised if no variable matches the name.
126  template < typename GUM_SCALAR >
127  INLINE const DiscreteVariable&
128  BayesNetFactory< GUM_SCALAR >::variable(const std::string& name) const {
129  try {
130  return __bn->variable(variableId(name));
131  } catch (NotFound&) { GUM_ERROR(NotFound, name); }
132  }
133 
134  // Returns the domainSize of the cpt for the node n.
135  // @throw NotFound raised if no such NodeId exists.
136  // @throw OperationNotAllowed if there is no bayesian networks.
137  template < typename GUM_SCALAR >
139  // (from PH) nowhere in the code, I see a check type if (__bn) __bn->. I
140  // assume
141  // __bn is forced not to be nullptr ...
142  return __bn->cpt(n).domainSize();
143  }
144 
145  // Tells the factory that we're in a network declaration.
146  template < typename GUM_SCALAR >
148  if (state() != factory_state::NONE) {
149  __illegalStateError("startNetworkDeclaration");
150  } else {
151  __states.push_back(factory_state::NETWORK);
152  }
153 
154  VERBOSITY("starting network");
155  }
156 
157  // Tells the factory to add a property to the current network.
158  template < typename GUM_SCALAR >
160  const std::string& propName, const std::string& propValue) {
161  __bn->setProperty(propName, propValue);
162  }
163 
164  // Tells the factory that we're out of a network declaration.
165  template < typename GUM_SCALAR >
167  if (state() != factory_state::NETWORK) {
168  __illegalStateError("endNetworkDeclaration");
169  } else {
170  __states.pop_back();
171  }
172 
173  VERBOSITY("network OK");
174  }
175 
176  // Tells the factory that we're in a variable declaration.
177  template < typename GUM_SCALAR >
179  if (state() != factory_state::NONE) {
180  __illegalStateError("startVariableDeclaration");
181  } else {
183  __stringBag.push_back("name");
184  __stringBag.push_back("desc");
185  }
186 
187  VERBOSITY(" starting variable");
188  }
189 
190  // Tells the factory the current variable's name.
191  template < typename GUM_SCALAR >
192  INLINE void
194  if (state() != factory_state::VARIABLE) {
195  __illegalStateError("variableName");
196  } else {
197  if (__varNameMap.exists(name)) {
198  std::string str = "Name already used: ";
199  GUM_ERROR(DuplicateElement, str + 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(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 >
580  INLINE void
582  const std::string& modality) {
583  if (state() != factory_state::FACT_ENTRY) {
584  __illegalStateError("string");
585  } else {
586  __checkVariableName(parent);
587  Idx id = __checkVariableModality(parent, modality);
588  (*__parents) << __bn->variable(__varNameMap[parent]);
589  __parents->chgVal(__bn->variable(__varNameMap[parent]), id);
590  }
591  }
592 
593  // @brief Gives the values of the variable with respect to precedent
594  // parents modality.
595  // If some parents have no modality set, then we apply values for all
596  // instantiations of that parent.
597  //
598  // This means you can declare a default value for the table by doing
599  // @code
600  // BayesNetFactory factory;
601  // // Do stuff
602  // factory.startVariableDeclaration();
603  // factory.variableName("foo");
604  // factory.endVariableDeclaration();
605  // factory.startParentsDeclaration("foo");
606  // // add parents
607  // factory.endParentsDeclaration();
608  // factory.startFactorizedProbabilityDeclaration("foo");
609  // std::vector<float> seq;
610  // seq.insert(0.4); // if foo true
611  // seq.insert(O.6); // if foo false
612  // factory.setVariableValues(seq); // fills the table with a default value
613  // // finish your stuff
614  // factory.endFactorizedProbabilityDeclaration();
615  // @code
616  // as for rawProba, if value's size is different than the number of modalities
617  // of
618  // the current variable,
619  // we don't use the supplementary values and we fill by 0 the missign values.
620  template < typename GUM_SCALAR >
622  const std::vector< float >& values) {
623  if (state() != factory_state::FACT_ENTRY) {
624  __illegalStateError("setVariableValues");
625  } else {
626  const DiscreteVariable& var = __bn->variable(__varNameMap[__stringBag[0]]);
627  NodeId varId = __varNameMap[__stringBag[0]];
628 
629  if (__parents->domainSize() > 0) {
630  Instantiation inst(__bn->cpt(__varNameMap[var.name()]));
631  inst.setVals(*__parents);
632  // Creating an instantiation containing all the variables not ins
633  // __parents.
634  Instantiation inst_default;
635  inst_default << var;
636 
637  for (auto node : __bn->parents(varId)) {
638  if (!__parents->contains(__bn->variable(node))) {
639  inst_default << __bn->variable(node);
640  }
641  }
642 
643  // Filling the variable's table.
644  for (inst.setFirstIn(inst_default); !inst.end();
645  inst.incIn(inst_default)) {
646  (__bn->cpt(varId))
647  .set(inst,
648  inst.val(var) < values.size() ? (GUM_SCALAR)values[inst.val(var)]
649  : (GUM_SCALAR)0);
650  }
651  } else {
652  Instantiation inst(__bn->cpt(__varNameMap[var.name()]));
653  Instantiation var_inst;
654  var_inst << var;
655 
656  for (var_inst.setFirst(); !var_inst.end(); ++var_inst) {
657  inst.setVals(var_inst);
658 
659  for (inst.setFirstOut(var_inst); !inst.end(); inst.incOut(var_inst)) {
660  (__bn->cpt(varId))
661  .set(inst,
662  inst.val(var) < values.size()
663  ? (GUM_SCALAR)values[inst.val(var)]
664  : (GUM_SCALAR)0);
665  }
666  }
667  }
668  }
669  }
670 
671  template < typename GUM_SCALAR >
673  const std::vector< float >& values) {
674  if (state() != factory_state::FACT_ENTRY) {
675  __illegalStateError("setVariableValues");
676  } else {
677  const DiscreteVariable& var = __bn->variable(__varNameMap[__stringBag[0]]);
678  // Checking consistency between values and var.
679 
680  if (values.size() != var.domainSize()) {
682  var.name()
683  << " : invalid number of modalities: found " << values.size()
684  << " while needed " << var.domainSize());
685  }
686 
688  }
689  }
690 
691  // Tells the factory that we finished declaring a conditional probability
692  // table.
693  template < typename GUM_SCALAR >
694  INLINE void
696  if (state() != factory_state::FACT_CPT) {
697  __illegalStateError("endFactorizedProbabilityDeclaration");
698  } else {
699  __resetParts();
700  __states.pop_back();
701  }
702  }
703 
704  // @brief Define a variable.
705  // You can only call this method is the factory is in the NONE or NETWORK
706  // state.
707  // The variable is added by copy.
708  // @param var The pointer over a DiscreteVariable used to define a new
709  // variable in the built BayesNet.
710  // @throw DuplicateElement Raised if a variable with the same name already
711  // exists.
712  // @throw OperationNotAllowed Raised if redefineParents == false and if table
713  // is not a valid CPT for var in the current state
714  // of the BayesNet.
715  template < typename GUM_SCALAR >
716  INLINE void
718  if ((state() != factory_state::NONE)) {
719  __illegalStateError("setVariable");
720  } else {
721  try {
722  __checkVariableName(var.name());
724  } catch (NotFound&) {
725  // The var name is unused
726  __varNameMap.insert(var.name(), __bn->add(var));
727  }
728  }
729  }
730 
731  // @brief Define a variable's CPT.
732  // You can only call this method if the factory is in the NONE or NETWORK
733  // state.
734  // Be careful that table is given to the built BayesNet, so it will be
735  // deleted with it, and you should not directly access it after you call
736  // this method.
737  // When the redefineParents flag is set to true the constructed BayesNet's
738  // DAG is changed to fit with table's definition.
739  // @param var The name of the concerned variable.
740  // @param table A pointer over the CPT used for var.
741  // @param redefineParents If true redefine var's parents to match table's
742  // variables set.
743  //
744  // @throw NotFound Raised if no variable matches var.
745  // @throw OperationNotAllowed Raised if redefineParents == false and if table
746  // is not a valid CPT for var in the current state
747  // of the BayesNet.
748  template < typename GUM_SCALAR >
750  const std::string& varName, MultiDimAdressable* table, bool redefineParents) {
751  auto pot = dynamic_cast< Potential< GUM_SCALAR >* >(table);
752 
753  if (state() != factory_state::NONE) {
754  __illegalStateError("setVariableCPT");
755  } else {
756  __checkVariableName(varName);
757  const DiscreteVariable& var = __bn->variable(__varNameMap[varName]);
758  NodeId varId = __varNameMap[varName];
759  // If we have to change the structure of the BayesNet, then we call a sub
760  // method.
761 
762  if (redefineParents) {
763  __setCPTAndParents(var, pot);
764  } else if (pot->contains(var)) {
765  for (auto node : __bn->parents(varId)) {
766  if (!pot->contains(__bn->variable(node))) {
768  "The CPT is not valid in the current BayesNet.");
769  }
770  }
771 
772  // CPT are created when a variable is added.
773  __bn->_unsafeChangePotential(varId, pot);
774  }
775  }
776  }
777 
778  // Copy operator is illegal, use only copy constructor.
779  template < typename GUM_SCALAR >
782  GUM_ERROR(OperationNotAllowed, "Illegal!");
783  // For noisy compilers
784  return *this;
785  }
786 
787  // Raise an OperationNotAllowed with the message "Illegal state."
788  template < typename GUM_SCALAR >
789  INLINE void
791  std::string msg = "Illegal state call (";
792  msg += s;
793  msg += ") in state ";
794 
795  switch (state()) {
796  case factory_state::NONE: {
797  msg += "NONE";
798  break;
799  }
800 
801  case factory_state::NETWORK: {
802  msg += "NETWORK";
803  break;
804  }
805 
807  msg += "VARIABLE";
808  break;
809  }
810 
811  case factory_state::PARENTS: {
812  msg += "PARENTS";
813  break;
814  }
815 
816  case factory_state::RAW_CPT: {
817  msg += "RAW_CPT";
818  break;
819  }
820 
822  msg += "FACT_CPT";
823  break;
824  }
825 
827  msg += "FACT_ENTRY";
828  break;
829  }
830 
831  default: { msg += "Unknown state"; }
832  }
833 
835  }
836 
837  // Check if a variable with the given name exists, if not raise an NotFound
838  // exception.
839  template < typename GUM_SCALAR >
840  INLINE void
842  if (!__varNameMap.exists(name)) { GUM_ERROR(NotFound, name); }
843  }
844 
845  // Check if var exists and if mod is one of it's modality, if not raise an
846  // NotFound exception.
847  template < typename GUM_SCALAR >
849  const std::string& name, const std::string& mod) {
850  __checkVariableName(name);
851  const DiscreteVariable& var = __bn->variable(__varNameMap[name]);
852 
853  for (Idx i = 0; i < var.domainSize(); ++i) {
854  if (mod == var.label(i)) { return i; }
855  }
856 
857  GUM_ERROR(NotFound, mod);
858  }
859 
860  // Check if in __stringBag there is no other modality with the same name.
861  template < typename GUM_SCALAR >
862  INLINE void
864  for (size_t i = 2; i < __stringBag.size(); ++i) {
865  if (mod == __stringBag[i]) { GUM_ERROR(DuplicateElement, mod); }
866  }
867  }
868 
869  // Sub method of setVariableCPT() which redefine the BayesNet's DAG with
870  // respect to table.
871  template < typename GUM_SCALAR >
873  const DiscreteVariable& var, Potential< GUM_SCALAR >* table) {
874  NodeId varId = __varNameMap[var.name()];
875  __bn->_dag.eraseParents(varId);
876 
877  for (auto v : table->variablesSequence()) {
878  if (v != (&var)) {
879  __checkVariableName(v->name());
880  __bn->_dag.addArc(__varNameMap[v->name()], varId);
881  }
882  }
883 
884  // CPT are created when a variable is added.
885  __bn->_unsafeChangePotential(varId, table);
886  }
887 
888  // Reset the different parts used to constructed the BayesNet.
889  template < typename GUM_SCALAR >
891  __foo_flag = false;
892  __bar_flag = false;
893  __stringBag.clear();
894  }
895 } /* 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
unsigned long Size
In aGrUM, hashed values are unsigned long int.
Definition: types.h:50
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.
unsigned int NodeId
Type for node ids.
Definition: graphElements.h:97
const DiscreteVariable & variable(NodeId id) const final
Returns a gum::DiscreteVariable given its gum::NodeId in the gum::BayesNet.
Definition: BayesNet_tpl.h:189
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.
bool exists(const Key &key) const
Checks whether there exists an element with a given key in the hashtable.
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.
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.
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.
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.
const DiscreteVariable & variable(const std::string &name) const
Returns a constant reference on a variable given it&#39;s name.
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.
virtual const Sequence< const DiscreteVariable * > & variablesSequence() const final
Returns a const ref to the sequence of DiscreteVariable*.
bool end() const
Returns true if the Instantiation reached the end.
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>
void endNetworkDeclaration() final
Tells the factory that we&#39;re out of a network declaration.
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.
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.
value_type & insert(const Key &key, const Val &val)
Adds a new element (actually a copy of this element) into the hash table.
const NodeGraphPart & nodes() const
Returns a constant reference to the dag of this Bayes Net.
Definition: DAGmodel_inl.h:113
LabelizedVariable & addLabel(const std::string &aLabel)
add a label with a new index (we assume that we will NEVER remove a label)
unsigned long Idx
Type for indexes.
Definition: types.h:43
const std::string & name() const
returns the name of the variable
Idx val(Idx i) const
Returns the current value of the variable at position i.
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:66
void __resetParts()
Reset the different parts used to constructed the BayesNet.
A factory class to ease BayesNet construction.
Definition: BayesNet.h:43
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.