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