aGrUM  0.20.2
a C++ library for (probabilistic) graphical models
credalNet_tpl.h
Go to the documentation of this file.
1 /**
2  *
3  * Copyright 2005-2020 Pierre-Henri WUILLEMIN(@LIP6) & Christophe GONZALES(@AMU)
4  * info_at_agrum_dot_org
5  *
6  * This library is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this library. If not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 
22 #include <agrum/agrum.h>
23 
24 #include <agrum/tools/core/utils_string.h>
25 #include <agrum/CN/credalNet.h>
26 
27 namespace gum {
28  namespace credal {
29 
30  template < typename GUM_SCALAR >
31  CredalNet< GUM_SCALAR >::CredalNet() {
32  initParams__();
33 
34  src_bn__ = BayesNet< GUM_SCALAR >();
35  src_bn_min__ = BayesNet< GUM_SCALAR >();
36  src_bn_max__ = BayesNet< GUM_SCALAR >();
37 
38  GUM_CONSTRUCTOR(CredalNet);
39  }
40 
41  template < typename GUM_SCALAR >
43  const Size& card) {
44  LabelizedVariable var(name, "node " + name, card);
45 
46  NodeId a = src_bn__.add(var);
49 
50  if (a != b || a != c /*|| b != c*/)
52  "addVariable : not the same id over all networks : "
53  << a << ", " << b << ", " << c);
54 
55  return a;
56  }
57 
58  template < typename GUM_SCALAR >
59  void CredalNet< GUM_SCALAR >::addArc(const NodeId& tail, const NodeId& head) {
63  }
64 
65  template < typename GUM_SCALAR >
67  const NodeId& id,
68  const std::vector< std::vector< std::vector< GUM_SCALAR > > >& cpt) {
69  const Potential< GUM_SCALAR >* const potential(&src_bn__.cpt(id));
70 
73 
74  if (cpt.size() != entry_size)
76  "setCPTs : entry sizes of cpts does not match for node id : "
77  << id << " : " << cpt.size() << " != " << entry_size);
78 
79  for (const auto& cset: cpt) {
80  if (cset.size() == 0)
81  GUM_ERROR(
82  SizeError,
83  "setCPTs : vertices in credal set does not match for node id : "
84  << id << " with 0 vertices");
85 
86  for (const auto& vertex: cset) {
87  if (vertex.size() != var_dSize)
89  "setCPTs : variable modalities in cpts does "
90  "not match for node id : "
91  << id << " with vertex " << vertex << " : "
92  << vertex.size() << " != " << var_dSize);
93 
94  GUM_SCALAR sum = 0;
95 
96  for (const auto& prob: vertex) {
97  sum += prob;
98  }
99 
100  if (std::fabs(sum - 1) > 1e-6)
102  "setCPTs : a vertex coordinates does not "
103  "sum to one for node id : "
104  << id << " with vertex " << vertex);
105  }
106  }
107 
109  }
110 
111  template < typename GUM_SCALAR >
113  const NodeId& id,
114  Size& entry,
115  const std::vector< std::vector< GUM_SCALAR > >& cpt) {
116  const Potential< GUM_SCALAR >* const potential(&src_bn__.cpt(id));
117 
120 
121  if (entry >= entry_size)
123  "setCPT : entry is greater or equal than entry size "
124  "(entries start at 0 up to entry_size - 1) : "
125  << entry << " >= " << entry_size);
126 
127  if (cpt.size() == 0)
128  GUM_ERROR(SizeError, "setCPT : empty credal set for entry : " << entry);
129 
130  for (const auto& vertex: cpt) {
131  if (vertex.size() != var_dSize)
133  "setCPT : variable modalities in cpts does not "
134  "match for node id : "
135  << id << " with vertex " << vertex << " at entry " << entry
136  << " : " << vertex.size() << " != " << var_dSize);
137 
138  GUM_SCALAR sum = 0;
139 
140  for (const auto& prob: vertex) {
141  sum += prob;
142  }
143 
144  if (std::fabs(sum - 1) > 1e-6)
145  GUM_ERROR(
146  CPTNoSumTo1,
147  "setCPT : a vertex coordinates does not sum to one for node id : "
148  << id << " at entry " << entry << " with vertex " << vertex);
149  }
150 
151  // !! auto does NOT use adress (if available) unless explicitly asked !!
153  id,
155 
156  if (node_cpt[entry].size() != 0)
158  "setCPT : vertices of entry id "
159  << entry << " already set to : " << node_cpt[entry]
160  << ", cannot insert : " << cpt);
161 
162  node_cpt[entry] = cpt;
163 
164  ///__credalNet_src_cpt.set ( id, node_cpt );
165  }
166 
167  template < typename GUM_SCALAR >
169  const NodeId& id,
171  const std::vector< std::vector< GUM_SCALAR > >& cpt) {
172  const Potential< GUM_SCALAR >* const potential(&src_bn__.cpt(id));
173 
176 
177  // to be sure of entry index reorder ins according to the bayes net
178  // potentials
179  // ( of the credal net )
180  // it WONT throw an error if the sequences are not equal not because of
181  // order
182  // but content, so we double check (before & after order correction)
183  // beware of slaves & master
185  ref.forgetMaster();
186 
187  ins.forgetMaster();
188 
189  const auto& vseq = ref.variablesSequence();
190 
191  if (ins.variablesSequence() != vseq) {
192  ins.reorder(ref);
193 
194  if (ins.variablesSequence() != vseq)
196  "setCPT : instantiation : "
197  << ins << " is not valid for node id " << id
198  << " which accepts instantiations such as (order is not "
199  "important) : "
200  << ref);
201  }
202 
203  Idx entry = 0, jump = 1;
204 
205  for (Idx i = 0, end = ins.nbrDim(); i < end; i++) {
206  if (src_bn__.nodeId(ins.variable(i)) == id) continue;
207 
208  entry += ins.val(i) * jump;
209 
210  jump *= ins.variable(i).domainSize();
211  }
212 
213  if (entry >= entry_size)
215  "setCPT : entry is greater or equal than entry size "
216  "(entries start at 0 up to entry_size - 1) : "
217  << entry << " >= " << entry_size);
218 
219  if (cpt.size() == 0)
220  GUM_ERROR(SizeError, "setCPT : empty credal set for entry : " << entry);
221 
222  for (const auto& vertex: cpt) {
223  if (vertex.size() != var_dSize)
225  "setCPT : variable modalities in cpts does not "
226  "match for node id : "
227  << id << " with vertex " << vertex << " at entry " << entry
228  << " : " << vertex.size() << " != " << var_dSize);
229 
230  GUM_SCALAR sum = 0;
231 
232  for (const auto& prob: vertex) {
233  sum += prob;
234  }
235 
236  if (std::fabs(sum - 1) > 1e-6)
237  GUM_ERROR(
238  CPTNoSumTo1,
239  "setCPT : a vertex coordinates does not sum to one for node id : "
240  << id << " at entry " << entry << " with vertex " << vertex);
241  }
242 
244  id,
246 
247  if (node_cpt[entry].size() != 0)
249  "setCPT : vertices of entry : "
250  << ins << " id " << entry << " already set to : "
251  << node_cpt[entry] << ", cannot insert : " << cpt);
252 
253  node_cpt[entry] = cpt;
254 
255  ///__credalNet_src_cpt.set ( id, node_cpt );
256  }
257 
258  template < typename GUM_SCALAR >
260  const NodeId& id,
261  const std::vector< GUM_SCALAR >& lower,
262  const std::vector< GUM_SCALAR >& upper) {
263  try {
266  } catch (const SizeError&) {
267  GUM_ERROR(
268  SizeError,
269  "fillConstraints : sizes does not match in fillWith for node id : "
270  << id);
271  }
272  }
273 
274  template < typename GUM_SCALAR >
276  const NodeId& id,
277  const Idx& entry,
278  const std::vector< GUM_SCALAR >& lower,
279  const std::vector< GUM_SCALAR >& upper) {
281  const_cast< Potential< GUM_SCALAR >* const >(&src_bn_min__.cpt(id)));
283  const_cast< Potential< GUM_SCALAR >* const >(&src_bn_max__.cpt(id)));
284 
286 
287  if (lower.size() != var_dSize || upper.size() != var_dSize)
288  GUM_ERROR(
289  SizeError,
290  "setCPT : variable modalities in cpts does not match for node id : "
291  << id << " with sizes of constraints : ( " << lower.size() << " || "
292  << upper.size() << " ) != " << var_dSize);
293 
295 
296  if (entry >= entry_size)
298  "setCPT : entry is greater or equal than entry size "
299  "(entries start at 0 up to entry_size - 1) : "
300  << entry << " >= " << entry_size);
301 
304  min.setFirst();
305  max.setFirst();
306 
307  Idx pos = 0;
308 
309  while (pos != entry) {
310  ++min;
311  ++max;
312  ++pos;
313  }
314 
315  for (Size i = 0; i < var_dSize; i++) {
318  ++min;
319  ++max;
320  }
321  }
322 
323  template < typename GUM_SCALAR >
325  const NodeId& id,
327  const std::vector< GUM_SCALAR >& lower,
328  const std::vector< GUM_SCALAR >& upper) {
329  const Potential< GUM_SCALAR >* const potential(&src_bn__.cpt(id));
330  /*
331  auto var_dSize = src_bn__.variable ( id ).domainSize();
332  auto entry_size = potential->domainSize() / var_dSize;
333  */
334  // to be sure of entry index reorder ins according to the bayes net
335  // potentials
336  // ( of the credal net )
337  // it WONT throw an error if the sequences are not equal not because of
338  // order
339  // but content, so we double check (before & after order correction)
340  // beware of slaves & master
342  ref.forgetMaster();
343 
344  ins.forgetMaster();
345 
346  const auto& vseq = ref.variablesSequence();
347 
348  if (ins.variablesSequence() != vseq) {
349  ins.reorder(ref);
350 
351  if (ins.variablesSequence() != vseq)
353  "setCPT : instantiation : "
354  << ins << " is not valid for node id " << id
355  << " which accepts instantiations such as (order is not "
356  "important) : "
357  << ref);
358  }
359 
360  Idx entry = 0, jump = 1;
361 
362  for (Idx i = 0, end = ins.nbrDim(); i < end; i++) {
363  if (src_bn__.nodeId(ins.variable(i)) == id) continue;
364 
365  entry += ins.val(i) * jump;
366 
367  jump *= ins.variable(i).domainSize();
368  }
369 
370  /*
371  if ( entry >= entry_size )
372  GUM_ERROR ( SizeError, "setCPT : entry is greater or equal than entry
373  size
374  (entries start at 0 up to entry_size - 1) : " << entry << " >= " <<
375  entry_size
376  );
377 
378  if ( lower.size() != var_dSize || upper.size() != var_dSize )
379  GUM_ERROR ( SizeError, "setCPT : variable modalities in cpts does not
380  match
381  for node id : " << id << " with sizes of constraints : ( "<< lower.size()
382  << "
383  || " << upper.size() << " ) != " << var_dSize );
384  */
386  }
387 
388  ////////////////////////////////////////////////
389  /// bnet accessors / shortcuts
390 
391  template < typename GUM_SCALAR >
393  return Instantiation(src_bn__.cpt(id));
394  }
395 
396  template < typename GUM_SCALAR >
398  return src_bn__.variable(id).domainSize();
399  }
400 
401  ///////////////////////////////////////////////
402 
403  template < typename GUM_SCALAR >
405  const std::string& src_max_den) {
406  initParams__();
408 
410  }
411 
412  template < typename GUM_SCALAR >
414  const BayesNet< GUM_SCALAR >& src_max_den) {
415  initParams__();
417 
419  }
420 
421  template < typename GUM_SCALAR >
423  if (current_bn__ != nullptr) delete current_bn__;
424 
425  if (credalNet_current_cpt__ != nullptr) delete credalNet_current_cpt__;
426 
427  if (current_nodeType__ != nullptr) delete current_nodeType__;
428 
430  }
431 
432  // from BNs with numerators & denominators or cpts & denominators to credal
433  template < typename GUM_SCALAR >
435  const bool oneNet,
436  const bool keepZeroes) {
437  GUM_SCALAR epsi_min = 1.;
438  GUM_SCALAR epsi_max = 0.;
439  GUM_SCALAR epsi_moy = 0.;
440  GUM_SCALAR epsi_den = 0.;
441 
442  for (auto node: src_bn().nodes()) {
443  const Potential< GUM_SCALAR >* const potential(&src_bn__.cpt(node));
444 
446  const_cast< Potential< GUM_SCALAR >* const >(&src_bn_min__.cpt(node)));
448  const_cast< Potential< GUM_SCALAR >* const >(&src_bn_max__.cpt(node)));
449 
452 
456 
457  ins.setFirst();
458  ins_min.setFirst();
459  ins_max.setFirst();
460 
462 
463  for (Size entry = 0; entry < entry_size; entry++) {
464  GUM_SCALAR den;
465 
466  if (oneNet)
467  den = 0;
468  else
470 
471  Size nbm = 0;
472 
473  for (Size modality = 0; modality < var_dSize; modality++) {
475 
476  if (oneNet) {
477  den += vertex[modality];
478 
479  if (vertex[modality] < 1 && vertex[modality] > 0)
481  "bnToCredal : the BayesNet contains "
482  "probabilities and not event counts "
483  "although user precised oneNet = "
484  << oneNet);
485  }
486 
487  if (vertex[modality] > 0) nbm++;
488 
489  ++ins;
490  }
491 
492  /// check sum is 1 if not oneNet (we are not using counts)
493  if (!oneNet) {
494  GUM_SCALAR sum = 0;
495 
496  for (auto modality = vertex.cbegin(), theEnd = vertex.cend();
497  modality != theEnd;
498  ++modality) {
499  sum += *modality;
500  }
501 
502  if (std::fabs(1. - sum) > epsRedund__) {
504  src_bn__.variable(node).name() << "(" << epsRedund__ << ")"
505  << " " << entry << std::endl
506  << vertex << std::endl
507  << ins << std::endl);
508  }
509  }
510 
511  /// end check sum is 1
512 
514 
515  if (beta == 0)
516  epsilon = 0;
517  else if (den == 0 || beta == 1)
518  epsilon = GUM_SCALAR(1.0);
519  else
521 
522  epsi_moy += epsilon;
523  epsi_den += 1;
524 
525  if (epsilon > epsi_max) epsi_max = epsilon;
526 
527  if (epsilon < epsi_min) epsi_min = epsilon;
528 
529  GUM_SCALAR min, max;
530 
531  for (Size modality = 0; modality < var_dSize; modality++) {
532  if ((vertex[modality] > 0 && nbm > 1) || !keepZeroes) {
533  min = GUM_SCALAR((1. - epsilon) * vertex[modality]);
534 
535  if (oneNet) min = GUM_SCALAR(min * 1.0 / den);
536 
537  max = GUM_SCALAR(min + epsilon);
538  } else { // if ( ( vertex[modality] == 0 && keepZeroes ) || (
539  // vertex[modality] > 0 && nbm <= 1 ) || ( vertex[modality] == 0
540  // && nbm <= 1 ) ) {
541  min = vertex[modality];
542 
543  if (oneNet) min = GUM_SCALAR(min * 1.0 / den);
544 
545  max = min;
546  }
547 
550 
551  ++ins_min;
552  ++ins_max;
553  } // end of : for each modality
554 
555  } // end of : for each entry
556 
557  } // end of : for each variable
558 
562 
564  }
565 
566  template < typename GUM_SCALAR >
568  for (auto node: src_bn__.nodes()) {
569  const Potential< GUM_SCALAR >* const potential(&src_bn__.cpt(node));
570 
573 
575 
576  ins.setFirst();
577 
579 
580  for (Size entry = 0; entry < entry_size; entry++) {
581  GUM_SCALAR den = 0;
582  bool zeroes = false;
584 
585  for (Size modality = 0; modality < var_dSize; modality++) {
587 
588  if (vertex[modality] < 1 && vertex[modality] > 0)
590  "lagrangeNormalization : the BayesNet "
591  "contains probabilities and not event "
592  "counts.");
593 
594  den += vertex[modality];
595 
596  if (!zeroes && vertex[modality] == 0) { zeroes = true; }
597 
598  ++ins;
599  }
600 
601  if (zeroes) {
602  ins = ins_prev;
603 
604  for (Size modality = 0; modality < var_dSize; modality++) {
605  potential->set(ins, potential->get(ins) + 1);
606  ++ins;
607  }
608  }
609 
610  } // end of : for each entry
611 
612  } // end of : for each variable
613  }
614 
615  template < typename GUM_SCALAR >
616  void CredalNet< GUM_SCALAR >::idmLearning(const Idx s, const bool keepZeroes) {
617  for (auto node: src_bn__.nodes()) {
618  const Potential< GUM_SCALAR >* const potential(&src_bn__.cpt(node));
619 
621  const_cast< Potential< GUM_SCALAR >* const >(&src_bn_min__.cpt(node)));
623  const_cast< Potential< GUM_SCALAR >* const >(&src_bn_max__.cpt(node)));
624 
627 
631 
632  ins.setFirst();
633  ins_min.setFirst();
634  ins_max.setFirst();
635 
637 
638  for (Size entry = 0; entry < entry_size; entry++) {
639  GUM_SCALAR den = 0;
640  Size nbm = 0;
641 
642  for (Size modality = 0; modality < var_dSize; modality++) {
644 
645  if (vertex[modality] < 1 && vertex[modality] > 0)
647  "idmLearning : the BayesNet contains "
648  "probabilities and not event counts.");
649 
650  den += vertex[modality];
651 
652  if (vertex[modality] > 0) nbm++;
653 
654  ++ins;
655  }
656 
657  if (nbm > 1 || !keepZeroes) den += s;
658 
659  GUM_SCALAR min, max;
660 
661  for (Size modality = 0; modality < var_dSize; modality++) {
662  min = vertex[modality];
663  max = min;
664 
665  if ((vertex[modality] > 0 && nbm > 1) || !keepZeroes) { max += s; }
666 
667  min = GUM_SCALAR(min * 1.0 / den);
668  max = GUM_SCALAR(max * 1.0 / den);
669 
672 
673  ++ins_min;
674  ++ins_max;
675  } // end of : for each modality
676 
677  } // end of : for each entry
678 
679  } // end of : for each variable
680 
685  }
686 
687  /* no need for lrs : (max ... min ... max) vertices from bnToCredal() */
688  template < typename GUM_SCALAR >
691 
693 
694  for (auto node: src_bn__.nodes()) {
695  const Potential< GUM_SCALAR >* const potential_min(
696  &src_bn_min__.cpt(node));
697  const Potential< GUM_SCALAR >* const potential_max(
698  &src_bn_max__.cpt(node));
699 
702 
704  entry_size);
705 
708 
709  ins_min.setFirst();
710  ins_max.setFirst();
711 
714 
715  for (Size entry = 0; entry < entry_size; entry++) {
716  for (Size modality = 0; modality < var_dSize;
717  modality++, ++ins_min, ++ins_max) {
720  }
721 
722  bool all_equals = true;
724 
725  for (Size modality = 0; modality < var_dSize; modality++) {
726  if (std::fabs(upper[modality] - lower[modality]) < 1e-6) continue;
727 
728  all_equals = false;
731 
732  for (Size mod = 0; mod < var_dSize; mod++) {
733  if (modality != mod) vertex[mod] = lower[mod];
734  }
735 
736  GUM_SCALAR total = 0;
737 
738  auto vsize = vertex.size();
739 
740  for (Size i = 0; i < vsize; i++)
741  total += vertex[i];
742 
743  if (std::fabs(total - 1.) > 1e-6)
745  src_bn__.variable(node).name() << " " << entry << std::endl
746  << vertex << std::endl);
747 
749  }
750 
751  if (all_equals) {
753 
754  for (Size modality = 0; modality < var_dSize; modality++)
756 
757  GUM_SCALAR total = 0.;
758 
759  auto vsize = vertex.size();
760 
761  for (Size i = 0; i < vsize; i++)
762  total += vertex[i];
763 
764  if (std::fabs(total - 1.) > 1e-6)
766  src_bn__.variable(node).name() << " " << entry << std::endl
767  << vertex << std::endl);
768 
770  }
771 
773  }
774 
776 
777  } // end of : for each variable (node)
778 
779  // get precise/credal/vacuous status of each variable
780  sort_varType__();
781  separatelySpecified__ = true;
782  }
783 
784  /* uses lrsWrapper */
785  template < typename GUM_SCALAR >
788 
790 
792 
793  for (auto node: src_bn__.nodes()) {
794  const Potential< GUM_SCALAR >* const potential_min(
795  &src_bn_min__.cpt(node));
796  const Potential< GUM_SCALAR >* const potential_max(
797  &src_bn_max__.cpt(node));
798 
801 
803  entry_size);
804 
807 
808  ins_min.setFirst();
809  ins_max.setFirst();
810 
812 
813  for (Size entry = 0; entry < entry_size; entry++) {
814  for (Size modality = 0; modality < var_dSize; modality++) {
817  "For variable " << src_bn__.variable(node).name()
818  << " (at " << ins_min
819  << "), the min is greater than the max : "
820  << potential_min->get(ins_min) << ">"
821  << potential_max->get(ins_max) << ".");
822  }
825  modality);
826  ++ins_min;
827  ++ins_max;
828  }
829 
830  lrsWrapper.H2V();
833  }
834 
836 
837  } // end of : for each variable (node)
838 
839  // get precise/credal/vacuous status of each variable
840  sort_varType__();
841  separatelySpecified__ = true;
842  }
843 
844  /* call lrs */
845  template < typename GUM_SCALAR >
848 
850 
851  for (auto node: src_bn__.nodes()) {
852  const Potential< GUM_SCALAR >* const potential_min(
853  &src_bn_min__.cpt(node));
854  const Potential< GUM_SCALAR >* const potential_max(
855  &src_bn_max__.cpt(node));
856 
859 
861  entry_size);
862 
865 
866  ins_min.setFirst();
867  ins_max.setFirst();
868 
869  // use iterator
870  for (Size entry = 0; entry < entry_size; entry++) {
872  std::vector< GUM_SCALAR > vertex(var_dSize); // if not interval
873 
875  var_dSize * 2,
876  std::vector< GUM_SCALAR >(var_dSize + 1, 0));
877 
878  std::vector< GUM_SCALAR > sum_ineq1(var_dSize + 1, -1);
880  sum_ineq1[0] = 1;
881  sum_ineq2[0] = -1;
882 
883  bool isInterval = false;
884 
885  for (Size modality = 0; modality < var_dSize; modality++) {
888  inequalities[modality * 2][modality + 1] = 1;
889  inequalities[modality * 2 + 1][modality + 1] = -1;
890 
891  vertex[modality] = inequalities[modality * 2 + 1][0];
892 
893  if (!isInterval
894  && (-inequalities[modality * 2][0]
895  != inequalities[modality * 2 + 1][0]))
896  isInterval = true;
897 
898  ++ins_min;
899  ++ins_max;
900  }
901 
904 
905  if (!isInterval) {
907  } else {
908  try {
910  //__H2Vcdd ( inequalities, vertices );
911  } catch (const std::exception& err) {
912  std::cout << err.what() << std::endl;
913  throw;
914  }
915 
916  } // end of : is interval
917 
918  if (entry == 0 && vertices.size() >= 2) {
919  auto tmp = vertices[0];
920  vertices[0] = vertices[1];
921  vertices[1] = tmp;
922  }
923 
925 
926  } // end of : for each entry
927 
929  // std::cout << src_bn__.variable(node_idIt).name() << std::endl;
930  // std::cout << var_cpt << std::endl;
931 
932  } // end of : for each variable (node)
933 
934  // get precise/credal/vacuous status of each variable
935  sort_varType__();
936  separatelySpecified__ = true;
937  }
938 
939  /**
940  * to call after bnToCredal( GUM_SCALAR beta )
941  * save a BN with lower probabilities and a BN with upper ones
942  */
943  template < typename GUM_SCALAR >
944  void
946  const std::string& max_path) const {
948 
949  std::string minfilename = min_path; //"min.bif";
950  std::string maxfilename = max_path; //"max.bif";
953 
954  if (!min_file.good())
955  GUM_ERROR(
956  IOError,
957  "bnToCredal() : could not open stream : min_file : " << minfilename);
958 
959  if (!max_file.good()) {
960  min_file.close();
961  GUM_ERROR(
962  IOError,
963  "bnToCredal() : could not open stream : min_file : " << maxfilename);
964  }
965 
966  try {
969  } catch (Exception& err) {
971  min_file.close();
972  max_file.close();
973  throw(err);
974  }
975 
976  min_file.close();
977  max_file.close();
978  }
979 
980  template < typename GUM_SCALAR >
982  // don't forget to delete the old one (current__), if necessary at the end
983  auto bin_bn = new BayesNet< GUM_SCALAR >();
984 
985  //__bnCopy ( *bin_bn__ );
986  // delete old one too
987  auto credalNet_bin_cpt = new NodeProperty<
988  std::vector< std::vector< std::vector< GUM_SCALAR > > > >();
989 
990  // delete old one too
991  auto bin_nodeType = new NodeProperty< NodeType >();
992 
993  const BayesNet< GUM_SCALAR >* current_bn;
994  // const NodeProperty< nodeType > *current_nodeType__;
995  const NodeProperty<
996  std::vector< std::vector< std::vector< GUM_SCALAR > > > >*
998 
999  if (this->current_bn__ == nullptr)
1000  current_bn = &this->src_bn__;
1001  else
1002  current_bn = this->current_bn__;
1003 
1004  if (this->credalNet_current_cpt__ == nullptr)
1006  else
1008 
1009  /*if ( this->current_nodeType__ == nullptr )
1010  current_nodeType__ = & this->nodeType__;
1011  else
1012  current_nodeType__ = this->current_nodeType__;*/
1013 
1014  if (!var_bits__.empty()) var_bits__.clear();
1015 
1017 
1018  for (auto node: current_bn->nodes()) {
1020 
1021  if (var_dSize != 2) {
1022  unsigned long b, c;
1023  superiorPow((unsigned long)var_dSize, b, c);
1024  Size nb_bits{Size(b)};
1025 
1026  std::string bit_name;
1027  std::vector< NodeId > bits(nb_bits);
1028 
1029  for (Size bit = 0; bit < nb_bits; bit++) {
1030  bit_name = current_bn->variable(node).name() + "-b";
1031  std::stringstream ss;
1032  ss << bit;
1033  bit_name += ss.str();
1034 
1035  LabelizedVariable var_bit(bit_name, "node " + bit_name, 2);
1036  NodeId iD = bin_bn->add(var_bit);
1037 
1038  bits[bit] = iD;
1039  } // end of : for each bit
1040 
1042 
1043  } // end of : if variable is not binary
1044  else {
1046  LabelizedVariable var_bit(bit_name, "node " + bit_name, 2);
1047  NodeId iD = bin_bn->add(var_bit);
1048 
1049  var_bits__.insert(node, std::vector< NodeId >(1, iD));
1050  }
1051 
1052  } // end of : for each original variable
1053 
1054  for (auto node: current_bn->nodes()) {
1056 
1057  if (!parents.empty()) {
1058  for (auto par: current_bn->parents(node)) {
1059  for (Size parent_bit = 0, spbits = Size(var_bits__[par].size());
1060  parent_bit < spbits;
1061  parent_bit++)
1062  for (Size var_bit = 0, mbits = Size(var_bits__[node].size());
1063  var_bit < mbits;
1064  var_bit++)
1066  var_bits__[node][var_bit]);
1067  }
1068  }
1069 
1070  // arcs with one's bits
1071  auto bitsize = var_bits__[node].size();
1072 
1073  for (Size bit_c = 1; bit_c < bitsize; bit_c++)
1074  for (Size bit_p = 0; bit_p < bit_c; bit_p++)
1076 
1077  } // end of : for each original variable
1078 
1080 
1081  // binarization of cpts
1082 
1083  auto varsize = current_bn->size();
1084 
1085  for (Size var = 0; var < varsize; var++) {
1086  auto bitsize = var_bits__[var].size();
1087 
1088  for (Size i = 0; i < bitsize; i++) {
1089  Potential< GUM_SCALAR > const* potential(
1090  &bin_bn->cpt(var_bits__[var][i]));
1092  ins.setFirst();
1093 
1094  auto entry_size = potential->domainSize() / 2;
1096  entry_size);
1097 
1098  Size old_conf = 0;
1099 
1100  for (Size conf = 0; conf < entry_size; conf++) {
1103 
1105  const std::vector< GUM_SCALAR >& vertex
1107  auto vertexsize = vertex.size();
1108 
1109  std::vector< Idx > incc(vertexsize, 0);
1110 
1111  for (Size preced = 0; preced < i; preced++) {
1113  auto val = ins.val(bit_pos);
1114 
1115  Size pas = Size(int2Pow((unsigned long)preced));
1116  Size elem;
1117 
1118  if (val == 0)
1119  elem = 0;
1120  else
1121  elem = pas;
1122 
1123  while (elem < vertexsize) {
1124  incc[elem]++;
1125  elem++;
1126 
1127  if (elem % pas == 0) elem += pas;
1128  }
1129  }
1130 
1131  Size pas = Size(int2Pow((unsigned long)i));
1132 
1133  std::vector< GUM_SCALAR > distri(2, 0);
1134  int pos = 1;
1135 
1136  for (Size elem = 0; elem < vertexsize; elem++) {
1137  if (elem % pas == 0) pos = -pos;
1138 
1139  if (incc[elem] == i)
1140  (pos < 0) ? (distri[0] += vertex[elem])
1141  : (distri[1] += vertex[elem]);
1142  }
1143 
1144  if (i > 0) {
1145  GUM_SCALAR den = distri[0] + distri[1];
1146 
1147  if (den == 0) {
1148  distri[0] = 0;
1149  distri[1] = 0;
1150  } else {
1151  distri[0] /= den;
1152  distri[1] /= den;
1153  }
1154  }
1155 
1157 
1158  } // end of old distris
1159 
1160  // get min/max approx, 2 vertices
1162  2,
1163  std::vector< GUM_SCALAR >(2, 1));
1164  vertices[1][1] = 0;
1165 
1166  auto new_verticessize = pvar_cpt.size();
1167 
1168  for (Size v = 0; v < new_verticessize; v++) {
1169  if (pvar_cpt[v][1] < vertices[0][1]) vertices[0][1] = pvar_cpt[v][1];
1170 
1171  if (pvar_cpt[v][1] > vertices[1][1]) vertices[1][1] = pvar_cpt[v][1];
1172  }
1173 
1174  vertices[0][0] = 1 - vertices[0][1];
1175  vertices[1][0] = 1 - vertices[1][1];
1176 
1177  pvar_cpt = vertices;
1178 
1179  var_cpt[conf] = pvar_cpt;
1180 
1181  ++ins;
1182  ++ins;
1183 
1184  old_conf++;
1185 
1186  if (old_conf == (*credalNet_current_cpt)[var].size()) old_conf = 0;
1187 
1188  } // end of new parent conf
1189 
1191 
1192  } // end of bit i
1193 
1194  } // end of old variable
1195 
1197 
1198  /* indicatrices variables */
1199  auto old_varsize = var_bits__.size();
1200 
1201  for (Size i = 0; i < old_varsize; i++) {
1202  auto bitsize = var_bits__[i].size();
1203 
1204  // binary variable
1205  if (bitsize == 1) continue;
1206 
1208 
1209  for (Size mod = 0; mod < old_card; mod++) {
1210  std::stringstream ss;
1211  ss << src_bn__.variable(i).name();
1212  ss << "-v";
1213  ss << mod;
1214 
1215  LabelizedVariable var(ss.str(), "node " + ss.str(), 2);
1216  const NodeId indic = bin_bn->add(var);
1217 
1218  // arcs from one's bits
1219  for (Size bit = 0; bit < bitsize; bit++)
1221 
1222  // cpt
1223  Size num = Size(int2Pow(long(bitsize)));
1224 
1225  std::vector< std::vector< std::vector< GUM_SCALAR > > > icpt(num);
1226 
1227  for (Size entry = 0; entry < num; entry++) {
1229  1,
1230  std::vector< GUM_SCALAR >(2, 0));
1231 
1232  if (mod == entry)
1233  vertices[0][1] = 1;
1234  else
1235  vertices[0][0] = 1;
1236 
1237  icpt[entry] = vertices;
1238  }
1239 
1241 
1243  } // end of each modality, i.e. as many indicatrice
1244  }
1245 
1247 
1248  if (this->current_bn__ != nullptr) delete this->current_bn__;
1249 
1250  this->current_bn__ = bin_bn;
1251 
1252  if (this->credalNet_current_cpt__ != nullptr)
1253  delete this->credalNet_current_cpt__;
1254 
1256 
1257  if (this->current_nodeType__ != nullptr) delete this->current_nodeType__;
1258 
1260 
1261  sort_varType__(); // will fill bin_nodeType__ except for NodeType::Indic
1262  // variables
1263 
1265  }
1266 
1267  template < typename GUM_SCALAR >
1268  const NodeProperty< std::vector< std::vector< std::vector< GUM_SCALAR > > > >&
1270  if (credalNet_current_cpt__ != nullptr) return *credalNet_current_cpt__;
1271 
1272  return credalNet_src_cpt__;
1273  }
1274 
1275  template < typename GUM_SCALAR >
1276  const NodeProperty< std::vector< std::vector< std::vector< GUM_SCALAR > > > >&
1278  return credalNet_src_cpt__;
1279  }
1280 
1281  template < typename GUM_SCALAR >
1282  typename CredalNet< GUM_SCALAR >::NodeType
1284  if (current_nodeType__ != nullptr) return (*(current_nodeType__))[id];
1285 
1286  return original_nodeType__[id];
1287  }
1288 
1289  template < typename GUM_SCALAR >
1290  typename CredalNet< GUM_SCALAR >::NodeType
1291  CredalNet< GUM_SCALAR >::nodeType(const NodeId& id) const {
1292  return original_nodeType__[id];
1293  }
1294 
1295  template < typename GUM_SCALAR >
1296  const bool CredalNet< GUM_SCALAR >::isSeparatelySpecified() const {
1297  return separatelySpecified__;
1298  }
1299 
1300  template < typename GUM_SCALAR >
1303  }
1304 
1305  // only if CN is binary !!
1306  template < typename GUM_SCALAR >
1310 
1311  for (auto node: current_bn().nodes()) {
1312  auto pConf = credalNet_currentCpt()[node].size();
1313  std::vector< GUM_SCALAR > min(pConf);
1314  std::vector< GUM_SCALAR > max(pConf);
1315 
1316  for (Size pconf = 0; pconf < pConf; pconf++) {
1317  GUM_SCALAR v1, v2;
1318  v1 = credalNet_currentCpt()[node][pconf][0][1];
1319 
1320  if (credalNet_currentCpt()[node][pconf].size() > 1)
1321  v2 = credalNet_currentCpt()[node][pconf][1][1];
1322  else
1323  v2 = v1;
1324 
1325  GUM_SCALAR delta = v1 - v2;
1326  min[pconf] = (delta >= 0) ? v2 : v1;
1327  max[pconf] = (delta >= 0) ? v1 : v2;
1328  }
1329 
1330  binCptMin__[node] = min;
1331  binCptMax__[node] = max;
1332  }
1333 
1335  }
1336 
1337  template < typename GUM_SCALAR >
1338  const std::vector< std::vector< GUM_SCALAR > >&
1340  return binCptMin__;
1341  }
1342 
1343  template < typename GUM_SCALAR >
1344  const std::vector< std::vector< GUM_SCALAR > >&
1346  return binCptMax__;
1347  }
1348 
1349  template < typename GUM_SCALAR >
1351  return epsilonMin__;
1352  }
1353 
1354  template < typename GUM_SCALAR >
1356  return epsilonMax__;
1357  }
1358 
1359  template < typename GUM_SCALAR >
1361  return epsilonMoy__;
1362  }
1363 
1364  template < typename GUM_SCALAR >
1367  const BayesNet< GUM_SCALAR >* current_bn__;
1368  const NodeProperty<
1369  std::vector< std::vector< std::vector< GUM_SCALAR > > > >*
1371 
1372  if (this->current_bn__ == nullptr)
1373  current_bn__ = &this->src_bn__;
1374  else
1375  current_bn__ = this->current_bn__;
1376 
1377  if (this->credalNet_current_cpt__ == nullptr)
1379  else
1381 
1382  for (auto node: current_bn__->nodes()) {
1384  auto pconfs
1386 
1387  output << "\n" << current_bn__->variable(node) << "\n";
1388 
1390  ins.forgetMaster();
1392  ins.setFirst();
1393 
1394  for (Size pconf = 0; pconf < pconfs; pconf++) {
1395  output << ins << " : ";
1396  output << (*credalNet_current_cpt__)[node][pconf] << "\n";
1397 
1398  if (pconf < pconfs - 1) ++ins;
1399  }
1400  }
1401 
1402  output << "\n";
1403 
1404  return output.str();
1405  }
1406 
1407  template < typename GUM_SCALAR >
1409  if (current_bn__ != nullptr) return *current_bn__;
1410 
1411  return src_bn__;
1412  }
1413 
1414  template < typename GUM_SCALAR >
1416  return src_bn__;
1417  }
1418 
1419  /////////// protected stuff //////////
1420 
1421  /////////// private stuff ////////////
1422 
1423  template < typename GUM_SCALAR >
1425  epsilonMin__ = 0;
1426  epsilonMax__ = 0;
1427  epsilonMoy__ = 0;
1428 
1429  epsRedund__ = GUM_SCALAR(1e-6);
1430 
1431  // farey algorithm
1432  epsF__ = GUM_SCALAR(1e-6);
1433  denMax__ = GUM_SCALAR(1e6); // beware LRSWrapper
1434 
1435  // continued fractions, beware LRSWrapper
1436  // decimal paces (epsC__ * precisionC__ == 1)
1437  precisionC__ = GUM_SCALAR(1e6);
1438  deltaC__ = 5;
1439 
1440  // old custom algorithm
1441  precision__ = GUM_SCALAR(1e6); // beware LRSWrapper
1442 
1443  current_bn__ = nullptr;
1444  credalNet_current_cpt__ = nullptr;
1445  current_nodeType__ = nullptr;
1446 
1448  }
1449 
1450  template < typename GUM_SCALAR >
1452  const std::string& src_max_den) {
1454  std::string other;
1455 
1456  if (src_max_den.compare("") != 0)
1457  other = src_max_den;
1458  else
1459  other = src_min_num;
1460 
1463 
1464  reader.proceed();
1465  reader_min.proceed();
1466  reader_max.proceed();
1467  }
1468 
1469  template < typename GUM_SCALAR >
1471  const BayesNet< GUM_SCALAR >& src_min_num,
1472  const BayesNet< GUM_SCALAR >& src_max_den) {
1475 
1476  if (src_max_den.size() > 0)
1478  else
1480  }
1481 
1482  template < typename GUM_SCALAR >
1484  const std::vector< std::vector< std::vector< GUM_SCALAR > > >& var_cpt)
1485  const {
1486  Size vertices_size = 0;
1487 
1488  for (auto entry = var_cpt.cbegin(), theEnd = var_cpt.cend(); entry != theEnd;
1489  ++entry) {
1491  }
1492 
1493  return int(vertices_size);
1494  }
1495 
1496  template < typename GUM_SCALAR >
1498  const BayesNet< GUM_SCALAR >* current_bn__;
1499 
1500  if (this->current_bn__ == nullptr)
1501  current_bn__ = &this->src_bn__;
1502  else
1503  current_bn__ = this->current_bn__;
1504 
1505  for (auto node: current_bn__->nodes())
1507 
1509 
1510  for (auto node: current_bn__->nodes()) {
1512  if (current_bn__->nodeId(*parent_idIt) != node)
1514  } // end of : for each parent in order of appearence
1515  } // end of : for each variable
1516 
1518  }
1519 
1520  /*
1521  // cdd can use real values, not just rationals / integers
1522  template< typename GUM_SCALAR >
1523  void CredalNet< GUM_SCALAR >::H2Vcdd__ ( const std::vector< std::vector<
1524  GUM_SCALAR > > & h_rep, std::vector< std::vector< GUM_SCALAR > > & v_rep )
1525  const {
1526  dd_set_global_constants();
1527 
1528  dd_MatrixPtr M, G;
1529  dd_PolyhedraPtr poly;
1530  dd_ErrorType err;
1531 
1532  unsigned int rows = h_rep.size();
1533  unsigned int cols = 0;
1534  if( h_rep.size() > 0 )
1535  cols = h_rep[0].size();
1536 
1537  M = dd_CreateMatrix( rows, cols);
1538 
1539  for ( unsigned int row = 0; row < rows; row++ )
1540  for ( unsigned int col = 0; col < cols; col++ )
1541  dd_set_d( M->matrix[row][col], h_rep[row][col] );
1542 
1543  M->representation = dd_Inequality;
1544 
1545  poly = dd_DDMatrix2Poly(M, &err);
1546  G = dd_CopyGenerators(poly);
1547 
1548  rows = G->rowsize;
1549  cols = G->colsize;
1550 
1551  v_rep.clear();
1552  for ( unsigned int row = 0; row < rows; row++ ) {
1553  std::vector< GUM_SCALAR > aRow(cols - 1);
1554 
1555  if ( *G->matrix[row][0] != 1 )
1556  GUM_ERROR(OperationNotAllowed, "__H2Vcdd : not reading a vertex");
1557 
1558  for ( unsigned int col = 0; col < cols - 1; col++ )
1559  aRow[col] = *G->matrix[row][ col + 1 ];
1560 
1561  v_rep.push_back(aRow);
1562  }
1563 
1564  dd_FreeMatrix(M);
1565  dd_FreeMatrix(G);
1566  dd_FreePolyhedra(poly);
1567 
1568  dd_free_global_constants();
1569  }
1570  */
1571 
1572  template < typename GUM_SCALAR >
1574  const std::vector< std::vector< GUM_SCALAR > >& h_rep,
1575  std::vector< std::vector< GUM_SCALAR > >& v_rep) const {
1576  // write H rep file
1577  int64_t num, den;
1578 
1580  = getUniqueFileName(); // generate unique file name, we
1581  // need to add .ine or .ext for lrs
1582  // to know which input it is (Hrep
1583  // to Vrep or Vrep to Hrep)
1584  sinefile += ".ine";
1585 
1587 
1588  if (!h_file.good())
1590  "__H2Vlrs : could not open lrs input file : " << sinefile);
1591 
1592  h_file << "H - representation\n";
1593  h_file << "begin\n";
1594  h_file << h_rep.size() << ' ' << h_rep[0].size() << " rational\n";
1595 
1596  for (auto it = h_rep.cbegin(), theEnd = h_rep.cend(); it != theEnd; ++it) {
1597  for (auto it2 = it->cbegin(), theEnd2 = it->cend(); it2 != theEnd2;
1598  ++it2) {
1599  // get integer fraction from decimal value
1600  // smallest numerator & denominator is farley, also
1601  // best precision
1603  den,
1604  ((*it2 > 0) ? *it2 : -*it2),
1605  int64_t(denMax__),
1606  epsF__);
1607 
1608  h_file << ((*it2 > 0) ? num : -num) << '/' << den << ' ';
1609  }
1610 
1611  h_file << '\n';
1612  }
1613 
1614  h_file << "end\n";
1615  h_file.close();
1616 
1617  // call lrs
1618  // lrs arguments
1619  char* args[3];
1620 
1621  std::string soft_name = "lrs";
1623  extfile += ".ext";
1624 
1625  args[0] = new char[soft_name.size()];
1626  args[1] = new char[sinefile.size()];
1627  args[2] = new char[extfile.size()];
1628 
1629  strcpy(args[0], soft_name.c_str());
1630  strcpy(args[1], sinefile.c_str());
1631  strcpy(args[2], extfile.c_str());
1632 
1633  // standard cout to null (avoid lrs flooding)
1634  int old_cout, new_cout;
1635  fflush(stdout);
1636  old_cout = dup(1);
1637 
1638  new_cout = open("/dev/null", O_WRONLY);
1639  dup2(new_cout, 1);
1640  close(new_cout);
1641 
1642  lrs_main(3, args);
1643 
1644  // restore standard cout
1645  fflush(stdout);
1646  dup2(old_cout, 1);
1647  close(old_cout);
1648 
1649  delete[] args[2];
1650  delete[] args[1];
1651  delete[] args[0];
1652 
1653  // read V rep file
1654  std::ifstream v_file(extfile.c_str() /*extfilename.c_str()*/, std::ios::in);
1655 
1656  if (!v_file.good())
1657  GUM_ERROR(IOError, "__H2Vlrs : could not open lrs ouput file : ");
1658 
1659  std::string line, tmp;
1660  char * cstr, *p;
1662 
1663  std::string::size_type pos;
1664  bool keep_going = true;
1665  // int vertices;
1666 
1668 
1669  v_file.ignore(256, 'l');
1670 
1671  while (v_file.good() && keep_going) {
1672  getline(v_file, line);
1673 
1674  if (line.size() == 0)
1675  continue;
1676  else if (line.compare("end") == 0) {
1677  keep_going = false;
1678  // this is to get vertices number :
1679  /*getline ( v_file, line );
1680  std::string::size_type pos, end_pos;
1681  pos = line.find ( "vertices = " );
1682  end_pos = line.find ( "rays", pos + 9 );
1683  vertices = atoi ( line.substr ( pos + 9, end_pos - pos - 9 ).c_str()
1684  );*/
1685  break;
1686  } else if (line[1] != '1') {
1688  "__H2Vlrs : reading something other than a vertex from "
1689  "lrs output file : ");
1690  }
1691 
1692  line = line.substr(2);
1693  cstr = new char[line.size() + 1];
1694  strcpy(cstr, line.c_str());
1695 
1696  p = strtok(cstr, " ");
1697 
1698  while (p != nullptr) {
1699  tmp = p;
1700 
1701  if (tmp.compare("1") == 0 || tmp.compare("0") == 0)
1703  else {
1704  pos = tmp.find("/");
1705  probability
1706  = GUM_SCALAR(atof(tmp.substr(0, pos).c_str())
1707  / atof(tmp.substr(pos + 1, tmp.size()).c_str()));
1708  }
1709 
1711  p = strtok(nullptr, " ");
1712  } // end of : for all tokens
1713 
1714  delete[] p;
1715  delete[] cstr;
1716 
1717  bool is_redund = false;
1718 
1719 #pragma omp parallel
1720  {
1721  int this_thread = getThreadNumber();
1723 
1724  auto begin_pos = (this_thread + 0) * v_rep.size() / num_threads;
1725  auto end_pos = (this_thread + 1) * v_rep.size() / num_threads;
1726 
1727  for (auto p = begin_pos; p < end_pos; p++) {
1728 #pragma omp flush(is_redund)
1729 
1730  if (is_redund) break;
1731 
1732  bool thread_redund = true;
1733 
1734  auto vsize = vertex.size();
1735 
1736  for (Size modality = 0; modality < vsize; modality++) {
1737  if (std::fabs(vertex[modality] - v_rep[p][modality]) > epsRedund__) {
1738  thread_redund = false;
1739  break;
1740  }
1741  }
1742 
1743  if (thread_redund) {
1744  is_redund = true;
1745 #pragma omp flush(is_redund)
1746  }
1747  } // end of : each thread for
1748  } // end of : parallel
1749 
1751 
1752  vertex.clear();
1753 
1754  } // end of : file
1755 
1756  v_file.close();
1757 
1758  if (std::remove(sinefile.c_str()) != 0)
1759  GUM_ERROR(IOError, "error removing : " + sinefile);
1760 
1761  if (std::remove(extfile.c_str()) != 0)
1762  GUM_ERROR(IOError, "error removing : " + extfile);
1763  }
1764 
1765  template < typename GUM_SCALAR >
1768  const NodeProperty<
1769  std::vector< std::vector< std::vector< GUM_SCALAR > > > >*
1771 
1772  const BayesNet< GUM_SCALAR >* current_bn__;
1773 
1774  if (this->current_bn__ == nullptr)
1776  else
1777  current_bn__ = this->current_bn__;
1778 
1779  if (this->credalNet_current_cpt__ == nullptr)
1781  else
1783 
1784  if (this->current_nodeType__ == nullptr)
1786  else
1788 
1789  /*if ( ! current_nodeType__->empty() )
1790  current_nodeType__->clear();*/
1791 
1792  for (auto node: current_bn__->nodes()) {
1793  // indicatrices are already present
1794  if (current_nodeType__->exists(node)) continue;
1795 
1796  bool precise = true, vacuous = true;
1797 
1798  for (auto entry = (*credalNet_current_cpt__)[node].cbegin(),
1800  entry != theEnd2;
1801  ++entry) {
1802  auto vertices = entry->size();
1803  auto var_dSize = (*entry)[0].size();
1804 
1805  if (precise && vertices > 1) precise = false;
1806 
1807  if (vacuous && vertices == var_dSize) {
1808  std::vector< bool > elem(var_dSize, false);
1809 
1810  for (auto vertex = entry->cbegin(), vEnd = entry->cend();
1811  vertex != vEnd;
1812  ++vertex) {
1813  for (auto probability = vertex->cbegin(), pEnd = vertex->cend();
1814  probability != pEnd;
1815  ++probability) {
1816  if (*probability == 1) {
1817  elem[probability - vertex->begin()] = true;
1818  break;
1819  }
1820  } // end of : for each modality
1821 
1822  break; // not vacuous
1823  } // end of : for each vertex
1824 
1825  for (auto /*std::vector< bool >::const_iterator*/ probability
1826  = elem.cbegin();
1827  probability != elem.cend();
1828  ++probability)
1829  if (*probability == false) vacuous = false;
1830 
1831  } // end of : if vertices == dSize
1832  else
1833  vacuous = false;
1834 
1835  if (vacuous == false && precise == false) {
1837  break;
1838  }
1839 
1840  } // end of : for each parents entry
1841 
1842  if (vacuous)
1844  else if (precise)
1846 
1847  } // end of : for each variable
1848  }
1849 
1850  } // namespace credal
1851 } // namespace gum
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:669
namespace for all credal networks entities
Definition: LpInterface.cpp:37