54 template < GUM_Numeric GUM_SCALAR >
65 template < GUM_Numeric GUM_SCALAR >
73 if (a != b || a != c )
75 "addVariable : not the same id over all networks : " << a <<
", " << b <<
", "
81 template < GUM_Numeric GUM_SCALAR >
88 template < GUM_Numeric GUM_SCALAR >
91 const std::vector< std::vector< std::vector< GUM_SCALAR > > >& cpt) {
92 const Tensor< GUM_SCALAR >*
const tensor(&
_src_bn_.cpt(
id));
94 auto var_dSize =
_src_bn_.variable(
id).domainSize();
96 if (
auto entry_size = tensor->domainSize() / var_dSize; cpt.size() != entry_size)
98 "setCPTs : entry sizes of cpts does not match for node id : "
99 <<
id <<
" : " << cpt.size() <<
" != " << entry_size);
101 for (
const auto& cset: cpt) {
102 if (cset.size() == 0)
104 "setCPTs : vertices in credal set does not match for node id : "
105 <<
id <<
" with 0 vertices");
107 for (
const auto& vertex: cset) {
108 if (vertex.size() != var_dSize)
110 "setCPTs : variable modalities in cpts does "
111 "not match for node id : "
112 <<
id <<
" with vertex " << vertex <<
" : " << vertex.size()
113 <<
" != " << var_dSize);
117 for (
const auto& prob: vertex) {
123 "setCPTs : a vertex coordinates does not "
124 "sum to one for node id : "
125 <<
id <<
" with vertex " << vertex);
132 template < GUM_Numeric GUM_SCALAR >
135 const std::vector< std::vector< GUM_SCALAR > >& cpt) {
136 const Tensor< GUM_SCALAR >*
const tensor(&
_src_bn_.cpt(
id));
138 auto var_dSize =
_src_bn_.variable(
id).domainSize();
139 auto entry_size = tensor->domainSize() / var_dSize;
141 if (entry >= entry_size)
143 "setCPT : entry is greater or equal than entry size "
144 "(entries start at 0 up to entry_size - 1) : "
145 << entry <<
" >= " << entry_size);
147 if (cpt.size() == 0)
GUM_ERROR(
SizeError,
"setCPT : empty credal set for entry : " << entry)
149 for (
const auto& vertex: cpt) {
150 if (vertex.size() != var_dSize)
152 "setCPT : variable modalities in cpts does not "
153 "match for node id : "
154 <<
id <<
" with vertex " << vertex <<
" at entry " << entry <<
" : "
155 << vertex.size() <<
" != " << var_dSize);
159 for (
const auto& prob: vertex) {
165 "setCPT : a vertex coordinates does not sum to one for node id : "
166 <<
id <<
" at entry " << entry <<
" with vertex " << vertex);
172 std::vector< std::vector< std::vector< GUM_SCALAR > > >(entry_size));
174 if (node_cpt[entry].size() != 0)
176 "setCPT : vertices of entry id " << entry
177 <<
" already set to : " << node_cpt[entry]
178 <<
", cannot insert : " << cpt);
180 node_cpt[entry] = cpt;
185 template < GUM_Numeric GUM_SCALAR >
188 const std::vector< std::vector< GUM_SCALAR > >& cpt) {
189 const Tensor< GUM_SCALAR >*
const tensor(&
_src_bn_.cpt(
id));
191 auto var_dSize =
_src_bn_.variable(
id).domainSize();
192 auto entry_size = tensor->domainSize() / var_dSize;
213 "setCPT : instantiation : "
214 << ins <<
" is not valid for node id " <<
id
215 <<
" which accepts instantiations such as (order is not "
220 Idx entry = 0, jump = 1;
222 for (
Idx i = 0, end = ins.
nbrDim(); i < end; i++) {
225 entry += ins.
val(i) * jump;
230 if (entry >= entry_size)
232 "setCPT : entry is greater or equal than entry size "
233 "(entries start at 0 up to entry_size - 1) : "
234 << entry <<
" >= " << entry_size);
236 if (cpt.size() == 0)
GUM_ERROR(
SizeError,
"setCPT : empty credal set for entry : " << entry)
238 for (
const auto& vertex: cpt) {
239 if (vertex.size() != var_dSize)
241 "setCPT : variable modalities in cpts does not "
242 "match for node id : "
243 <<
id <<
" with vertex " << vertex <<
" at entry " << entry <<
" : "
244 << vertex.size() <<
" != " << var_dSize);
248 for (
const auto& prob: vertex) {
254 "setCPT : a vertex coordinates does not sum to one for node id : "
255 <<
id <<
" at entry " << entry <<
" with vertex " << vertex);
260 std::vector< std::vector< std::vector< GUM_SCALAR > > >(entry_size));
262 if (node_cpt[entry].size() != 0)
264 "setCPT : vertices of entry : " << ins <<
" id " << entry
265 <<
" already set to : " << node_cpt[entry]
266 <<
", cannot insert : " << cpt);
268 node_cpt[entry] = cpt;
273 template < GUM_Numeric GUM_SCALAR >
275 const std::vector< GUM_SCALAR >& lower,
276 const std::vector< GUM_SCALAR >& upper) {
282 "fillConstraints : sizes does not match in fillWith for node id : " <<
id);
286 template < GUM_Numeric GUM_SCALAR >
289 const std::vector< GUM_SCALAR >& lower,
290 const std::vector< GUM_SCALAR >& upper) {
291 Tensor< GUM_SCALAR >*
const tensor_min(
292 const_cast< Tensor< GUM_SCALAR >*
const >(&
_src_bn_min_.cpt(
id)));
293 Tensor< GUM_SCALAR >*
const tensor_max(
294 const_cast< Tensor< GUM_SCALAR >*
const >(&
_src_bn_max_.cpt(
id)));
296 auto var_dSize =
_src_bn_.variable(
id).domainSize();
298 if (lower.size() != var_dSize || upper.size() != var_dSize)
300 "setCPT : variable modalities in cpts does not match for node id : "
301 <<
id <<
" with sizes of constraints : ( " << lower.size() <<
" || "
302 << upper.size() <<
" ) != " << var_dSize);
304 auto entry_size = tensor_min->domainSize() / var_dSize;
306 if (entry >= entry_size)
308 "setCPT : entry is greater or equal than entry size "
309 "(entries start at 0 up to entry_size - 1) : "
310 << entry <<
" >= " << entry_size);
319 while (pos != entry) {
325 for (
Size i = 0; i < var_dSize; i++) {
326 tensor_min->set(min, lower[i]);
327 tensor_max->set(max, upper[i]);
333 template < GUM_Numeric GUM_SCALAR >
336 const std::vector< GUM_SCALAR >& lower,
337 const std::vector< GUM_SCALAR >& upper) {
338 const Tensor< GUM_SCALAR >*
const tensor(&
_src_bn_.cpt(
id));
362 "setCPT : instantiation : "
363 << ins <<
" is not valid for node id " <<
id
364 <<
" which accepts instantiations such as (order is not "
369 Idx entry = 0, jump = 1;
371 for (
Idx i = 0, end = ins.
nbrDim(); i < end; i++) {
374 entry += ins.
val(i) * jump;
400 template < GUM_Numeric GUM_SCALAR >
405 template < GUM_Numeric GUM_SCALAR >
407 return _src_bn_.variable(
id).domainSize();
412 template < GUM_Numeric GUM_SCALAR >
420 template < GUM_Numeric GUM_SCALAR >
422 const BayesNet< GUM_SCALAR >& src_max_den) {
429 template < GUM_Numeric GUM_SCALAR >
441 template < GUM_Numeric GUM_SCALAR >
446 template < GUM_Numeric GUM_SCALAR >
448 GUM_SCALAR epsi_min = 1.;
449 GUM_SCALAR epsi_max = 0.;
450 GUM_SCALAR epsi_moy = 0.;
451 GUM_SCALAR epsi_den = 0.;
453 for (
auto node:
src_bn().nodes()) {
454 const Tensor< GUM_SCALAR >*
const tensor(&
_src_bn_.cpt(node));
456 Tensor< GUM_SCALAR >*
const tensor_min(
457 const_cast< Tensor< GUM_SCALAR >*
const >(&
_src_bn_min_.cpt(node)));
458 Tensor< GUM_SCALAR >*
const tensor_max(
459 const_cast< Tensor< GUM_SCALAR >*
const >(&
_src_bn_max_.cpt(node)));
462 Size entry_size = tensor->domainSize() / var_dSize;
472 std::vector< GUM_SCALAR > vertex(var_dSize);
474 for (
Size entry = 0; entry < entry_size; entry++) {
478 else den = tensor_max->get(ins_max);
482 for (
Size modality = 0; modality < var_dSize; modality++) {
483 vertex[modality] = tensor->get(ins);
486 den += vertex[modality];
488 if (vertex[modality] < 1 && vertex[modality] > 0)
490 "bnToCredal : the BayesNet contains "
491 "probabilities and not event counts "
492 "although user precised oneNet = "
496 if (vertex[modality] > 0) nbm++;
505 for (
auto modality = vertex.cbegin(), theEnd = vertex.cend(); modality != theEnd;
513 <<
"(" <<
_epsRedund_ <<
") does not sum to one for" <<
" " << entry
515 << vertex << std::endl
516 << ins << std::endl);
524 if (beta == 0) epsilon = 0;
525 else if (den == 0 || beta == 1) epsilon = GUM_SCALAR(1.0);
526 else epsilon = GUM_SCALAR(std::pow(beta, std::log1p(den)));
531 if (epsilon > epsi_max) epsi_max = epsilon;
533 if (epsilon < epsi_min) epsi_min = epsilon;
537 for (
Size modality = 0; modality < var_dSize; modality++) {
538 if ((vertex[modality] > 0 && nbm > 1) || !keepZeroes) {
539 min = GUM_SCALAR((1. - epsilon) * vertex[modality]);
541 if (oneNet) min = GUM_SCALAR(min * 1.0 / den);
543 max = GUM_SCALAR(min + epsilon);
548 min = vertex[modality];
550 if (oneNet) min = GUM_SCALAR(min * 1.0 / den);
555 tensor_min->set(ins_min, min);
556 tensor_max->set(ins_max, max);
566 _epsilonMoy_ = (GUM_SCALAR)epsi_moy / (GUM_SCALAR)epsi_den;
571 template < GUM_Numeric GUM_SCALAR >
574 const Tensor< GUM_SCALAR >*
const tensor(&
_src_bn_.cpt(node));
576 auto var_dSize =
_src_bn_.variable(node).domainSize();
577 auto entry_size = tensor->domainSize() / var_dSize;
583 std::vector< GUM_SCALAR > vertex(var_dSize);
585 for (
Size entry = 0; entry < entry_size; entry++) {
589 for (
Size modality = 0; modality < var_dSize; modality++) {
590 vertex[modality] = tensor->get(ins);
592 if (vertex[modality] < 1 && vertex[modality] > 0)
594 "lagrangeNormalization : the BayesNet "
595 "contains probabilities and not event "
598 if (!zeroes && vertex[modality] == 0) { zeroes =
true; }
606 for (
Size modality = 0; modality < var_dSize; modality++) {
607 tensor->set(ins, tensor->get(ins) + 1);
615 template < GUM_Numeric GUM_SCALAR >
618 const Tensor< GUM_SCALAR >*
const tensor(&
_src_bn_.cpt(node));
620 Tensor< GUM_SCALAR >*
const tensor_min(
621 const_cast< Tensor< GUM_SCALAR >*
const >(&
_src_bn_min_.cpt(node)));
622 Tensor< GUM_SCALAR >*
const tensor_max(
623 const_cast< Tensor< GUM_SCALAR >*
const >(&
_src_bn_max_.cpt(node)));
626 Size entry_size = tensor->domainSize() / var_dSize;
636 std::vector< GUM_SCALAR > vertex(var_dSize);
638 for (
Size entry = 0; entry < entry_size; entry++) {
642 for (
Size modality = 0; modality < var_dSize; modality++) {
643 vertex[modality] = tensor->get(ins);
645 if (vertex[modality] < 1 && vertex[modality] > 0)
647 "idmLearning : the BayesNet contains "
648 "probabilities and not event counts.");
650 den += vertex[modality];
652 if (vertex[modality] > 0) nbm++;
657 if (nbm > 1 || !keepZeroes) den += s;
661 for (
Size modality = 0; modality < var_dSize; modality++) {
662 min = vertex[modality];
665 if ((vertex[modality] > 0 && nbm > 1) || !keepZeroes) { max += s; }
667 min = GUM_SCALAR(min * 1.0 / den);
668 max = GUM_SCALAR(max * 1.0 / den);
670 tensor_min->set(ins_min, min);
671 tensor_max->set(ins_max, max);
686 template < GUM_Numeric GUM_SCALAR >
693 const Tensor< GUM_SCALAR >*
const tensor_min(&
_src_bn_min_.cpt(node));
694 const Tensor< GUM_SCALAR >*
const tensor_max(&
_src_bn_max_.cpt(node));
697 Size entry_size = tensor_min->domainSize() / var_dSize;
699 std::vector< std::vector< std::vector< GUM_SCALAR > > > var_cpt(entry_size);
707 std::vector< GUM_SCALAR > lower(var_dSize);
708 std::vector< GUM_SCALAR > upper(var_dSize);
710 for (
Size entry = 0; entry < entry_size; entry++) {
711 for (
Size modality = 0; modality < var_dSize; modality++, ++ins_min, ++ins_max) {
712 lower[modality] = tensor_min->get(ins_min);
713 upper[modality] = tensor_max->get(ins_max);
716 bool all_equals =
true;
717 std::vector< std::vector< GUM_SCALAR > > vertices;
719 for (
Size modality = 0; modality < var_dSize; modality++) {
720 if (std::fabs(upper[modality] - lower[modality]) < 1e-6)
continue;
723 std::vector< GUM_SCALAR > vertex(var_dSize);
724 vertex[modality] = upper[modality];
726 for (
Size mod = 0; mod < var_dSize; mod++) {
727 if (modality != mod) vertex[mod] = lower[mod];
730 GUM_SCALAR total = 0;
732 auto vsize = vertex.size();
734 for (
Size i = 0; i < vsize; i++)
737 if (std::fabs(total - 1.) > 1e-6)
740 <<
" does not sum to one for " << entry << std::endl
741 << vertex << std::endl);
743 vertices.push_back(vertex);
747 std::vector< GUM_SCALAR > vertex(var_dSize);
749 for (
Size modality = 0; modality < var_dSize; modality++)
750 vertex[modality] = lower[modality];
752 GUM_SCALAR total = 0.;
754 auto vsize = vertex.size();
756 for (
Size i = 0; i < vsize; i++)
759 if (std::fabs(total - 1.) > 1e-6)
762 <<
" does not sum to one for " << entry << std::endl
763 << vertex << std::endl);
765 vertices.push_back(vertex);
768 var_cpt[entry] = vertices;
780 template < GUM_Numeric GUM_SCALAR >
789 const Tensor< GUM_SCALAR >*
const tensor_min(&
_src_bn_min_.cpt(node));
790 const Tensor< GUM_SCALAR >*
const tensor_max(&
_src_bn_max_.cpt(node));
793 Size entry_size = tensor_min->domainSize() / var_dSize;
795 std::vector< std::vector< std::vector< GUM_SCALAR > > > var_cpt(entry_size);
803 lrsWrapper.
setUpH(var_dSize);
805 for (
Size entry = 0; entry < entry_size; entry++) {
806 for (
Size modality = 0; modality < var_dSize; modality++) {
807 if (tensor_min->get(ins_min) > tensor_max->get(ins_max)) {
810 <<
_src_bn_.variable(node).name() <<
" (at " << ins_min
811 <<
"), the min is greater than the max : " << tensor_min->get(ins_min)
812 <<
">" << tensor_max->get(ins_max) <<
".");
814 lrsWrapper.
fillH(tensor_min->get(ins_min), tensor_max->get(ins_max), modality);
833 template < GUM_Numeric GUM_SCALAR >
840 const Tensor< GUM_SCALAR >*
const tensor_min(&
_src_bn_min_.cpt(node));
841 const Tensor< GUM_SCALAR >*
const tensor_max(&
_src_bn_max_.cpt(node));
843 auto var_dSize =
_src_bn_.variable(node).domainSize();
844 auto entry_size = tensor_min->domainSize() / var_dSize;
846 std::vector< std::vector< std::vector< GUM_SCALAR > > > var_cpt(entry_size);
855 for (
Size entry = 0; entry < entry_size; entry++) {
856 std::vector< std::vector< GUM_SCALAR > > vertices;
857 std::vector< GUM_SCALAR > vertex(var_dSize);
859 std::vector< std::vector< GUM_SCALAR > > inequalities(
861 std::vector< GUM_SCALAR >(var_dSize + 1, 0));
863 std::vector< GUM_SCALAR > sum_ineq1(var_dSize + 1, -1);
864 std::vector< GUM_SCALAR > sum_ineq2(var_dSize + 1, 1);
868 bool isInterval =
false;
870 for (
Size modality = 0; modality < var_dSize; modality++) {
871 inequalities[modality * 2][0] = -tensor_min->get(ins_min);
872 inequalities[modality * 2 + 1][0] = tensor_max->get(ins_max);
873 inequalities[modality * 2][modality + 1] = 1;
874 inequalities[modality * 2 + 1][modality + 1] = -1;
876 vertex[modality] = inequalities[modality * 2 + 1][0];
879 && (-inequalities[modality * 2][0] != inequalities[modality * 2 + 1][0]))
886 inequalities.push_back(sum_ineq1);
887 inequalities.push_back(sum_ineq2);
890 vertices.push_back(vertex);
895 }
catch (
const std::exception& err) {
896 std::cout << err.what() << std::endl;
901 if (entry == 0 && vertices.size() >= 2) {
902 auto tmp = vertices[0];
903 vertices[0] = vertices[1];
907 var_cpt[entry] = vertices;
924 template < GUM_Numeric GUM_SCALAR >
926 std::string_view max_path) {
929 std::string minfilename(min_path);
930 std::string maxfilename(max_path);
931 std::ofstream min_file(minfilename.c_str(), std::ios::out | std::ios::trunc);
932 std::ofstream max_file(maxfilename.c_str(), std::ios::out | std::ios::trunc);
934 if (!min_file.good())
935 GUM_ERROR(
IOError,
"bnToCredal() : could not open stream : min_file : " << minfilename);
937 if (!max_file.good()) {
939 GUM_ERROR(
IOError,
"bnToCredal() : could not open stream : min_file : " << maxfilename);
956 template < GUM_Numeric GUM_SCALAR >
959 auto bin_bn =
new BayesNet< GUM_SCALAR >();
963 auto credalNet_bin_cpt
971 credalNet_current_cpt;
982 bin_bn->beginTopologyTransformation();
985 auto var_dSize =
current_bn->variable(node).domainSize();
987 if (var_dSize != 2) {
990 superiorPow(
static_cast< unsigned long >(var_dSize), b, c);
993 std::string bit_name;
994 std::vector< NodeId > bits(nb_bits);
996 for (
Size bit = 0; bit < nb_bits; bit++) {
997 bit_name =
current_bn->variable(node).name() +
"-b";
998 bit_name += std::to_string(bit);
1001 NodeId iD = bin_bn->add(var_bit);
1009 const std::string bit_name =
current_bn->variable(node).name();
1011 const NodeId iD = bin_bn->add(var_bit);
1013 _var_bits_.insert(node, std::vector< NodeId >(1, iD));
1021 parent_bit < spbits;
1031 const auto bitsize =
_var_bits_[node].size();
1033 for (
Size bit_c = 1; bit_c < bitsize; bit_c++)
1034 for (
Size bit_p = 0; bit_p < bit_c; bit_p++)
1038 bin_bn->endTopologyTransformation();
1044 for (
Size var = 0; var < varsize; var++) {
1047 for (
Size i = 0; i < bitsize; i++) {
1048 Tensor< GUM_SCALAR >
const* tensor(&bin_bn->cpt(
_var_bits_[var][i]));
1052 auto entry_size = tensor->domainSize() / 2;
1053 std::vector< std::vector< std::vector< GUM_SCALAR > > > var_cpt(entry_size);
1057 for (
Size conf = 0; conf < entry_size; conf++) {
1058 std::vector< std::vector< GUM_SCALAR > > pvar_cpt;
1059 auto verticessize = (*credalNet_current_cpt)[var][old_conf].size();
1061 for (
Size old_distri = 0; old_distri < verticessize; old_distri++) {
1062 const std::vector< GUM_SCALAR >& vertex
1063 = (*credalNet_current_cpt)[var][old_conf][old_distri];
1064 auto vertexsize = vertex.size();
1066 std::vector< Idx > incc(vertexsize, 0);
1068 for (
Size preced = 0; preced < i; preced++) {
1069 auto bit_pos = ins.
pos(bin_bn->variable(
_var_bits_[var][preced]));
1070 auto val = ins.
val(bit_pos);
1075 if (val == 0) elem = 0;
1078 while (elem < vertexsize) {
1082 if (elem % pas == 0) elem += pas;
1088 std::vector< GUM_SCALAR > distri(2, 0);
1091 for (
Size elem = 0; elem < vertexsize; elem++) {
1092 if (elem % pas == 0) pos = -pos;
1094 if (incc[elem] == i)
1095 (pos < 0) ? (distri[0] += vertex[elem]) : (distri[1] += vertex[elem]);
1099 GUM_SCALAR den = distri[0] + distri[1];
1110 pvar_cpt.push_back(distri);
1114 std::vector< std::vector< GUM_SCALAR > > vertices(2, std::vector< GUM_SCALAR >(2, 1));
1117 const auto new_verticessize = pvar_cpt.size();
1119 for (
Size v = 0; v < new_verticessize; v++) {
1120 if (pvar_cpt[v][1] < vertices[0][1]) vertices[0][1] = pvar_cpt[v][1];
1122 if (pvar_cpt[v][1] > vertices[1][1]) vertices[1][1] = pvar_cpt[v][1];
1125 vertices[0][0] = 1 - vertices[0][1];
1126 vertices[1][0] = 1 - vertices[1][1];
1128 pvar_cpt = vertices;
1130 var_cpt[conf] = pvar_cpt;
1137 if (old_conf == (*credalNet_current_cpt)[var].size()) old_conf = 0;
1140 credalNet_bin_cpt->insert(
_var_bits_[var][i], var_cpt);
1144 bin_bn->beginTopologyTransformation();
1149 for (
Size i = 0; i < old_varsize; i++) {
1153 if (bitsize == 1)
continue;
1155 auto old_card =
_src_bn_.variable(i).domainSize();
1157 for (
Size mod = 0; mod < old_card; mod++) {
1158 auto ss_str = std::format(
"{}-v{}",
_src_bn_.variable(i).name(), mod);
1161 const NodeId indic = bin_bn->add(var);
1164 for (
Size bit = 0; bit < bitsize; bit++)
1170 std::vector< std::vector< std::vector< GUM_SCALAR > > > icpt(num);
1172 for (
Size entry = 0; entry < num; entry++) {
1173 std::vector< std::vector< GUM_SCALAR > > vertices(1, std::vector< GUM_SCALAR >(2, 0));
1175 if (mod == entry) vertices[0][1] = 1;
1176 else vertices[0][0] = 1;
1178 icpt[entry] = vertices;
1181 credalNet_bin_cpt->insert(indic, icpt);
1187 bin_bn->endTopologyTransformation();
1207 template < GUM_Numeric GUM_SCALAR >
1215 template < GUM_Numeric GUM_SCALAR >
1221 template < GUM_Numeric GUM_SCALAR >
1229 template < GUM_Numeric GUM_SCALAR >
1235 template < GUM_Numeric GUM_SCALAR >
1240 template < GUM_Numeric GUM_SCALAR >
1246 template < GUM_Numeric GUM_SCALAR >
1255 std::vector< GUM_SCALAR > min(pConf);
1256 std::vector< GUM_SCALAR > max(pConf);
1258 for (
Size pconf = 0; pconf < pConf; pconf++) {
1266 GUM_SCALAR delta = v1 - v2;
1267 min[pconf] = (delta >= 0) ? v2 : v1;
1268 max[pconf] = (delta >= 0) ? v1 : v2;
1278 template < GUM_Numeric GUM_SCALAR >
1279 const std::vector< std::vector< GUM_SCALAR > >&
1284 template < GUM_Numeric GUM_SCALAR >
1285 const std::vector< std::vector< GUM_SCALAR > >&
1290 template < GUM_Numeric GUM_SCALAR >
1295 template < GUM_Numeric GUM_SCALAR >
1300 template < GUM_Numeric GUM_SCALAR >
1305 template < GUM_Numeric GUM_SCALAR >
1307 std::stringstream output;
1312 for (
auto node: bn_ptr->nodes()) {
1313 const Tensor< GUM_SCALAR >* tensor(&bn_ptr->cpt(node));
1314 auto pconfs = tensor->domainSize() / bn_ptr->variable(node).domainSize();
1316 output <<
"\n" << bn_ptr->variable(node) <<
"\n";
1320 ins.
erase(bn_ptr->variable(node));
1323 for (
Size pconf = 0; pconf < pconfs; pconf++) {
1324 output << ins <<
" : ";
1325 output << (*cpt_ptr)[node][pconf] <<
"\n";
1327 if (pconf < pconfs - 1) ++ins;
1333 return output.str();
1336 template < GUM_Numeric GUM_SCALAR >
1343 template < GUM_Numeric GUM_SCALAR >
1352 template < GUM_Numeric GUM_SCALAR >
1361 _epsF_ = GUM_SCALAR(1e-6);
1379 template < GUM_Numeric GUM_SCALAR >
1381 std::string_view src_max_den) {
1385 if (src_max_den.compare(
"") != 0) other = src_max_den;
1386 else other = src_min_num;
1396 template < GUM_Numeric GUM_SCALAR >
1398 const BayesNet< GUM_SCALAR >& src_max_den) {
1402 if (src_max_den.size() > 0)
_src_bn_max_ = src_max_den;
1406 template < GUM_Numeric GUM_SCALAR >
1408 const std::vector< std::vector< std::vector< GUM_SCALAR > > >& var_cpt)
const {
1409 Size vertices_size = 0;
1411 for (
auto entry = var_cpt.cbegin(), theEnd = var_cpt.cend(); entry != theEnd; ++entry) {
1412 if (entry->size() > vertices_size) vertices_size =
Size(entry->size());
1415 return int(vertices_size);
1418 template < GUM_Numeric GUM_SCALAR >
1422 for (
auto node: bn_ptr->nodes())
1423 dest.add(bn_ptr->variable(node));
1425 dest.beginTopologyTransformation();
1427 for (
auto node: bn_ptr->nodes()) {
1428 for (
auto parent_idIt: bn_ptr->cpt(node).variablesSequence()) {
1429 if (bn_ptr->nodeId(*parent_idIt) != node) dest.addArc(bn_ptr->nodeId(*parent_idIt), node);
1433 dest.endTopologyTransformation();
1488 template < GUM_Numeric GUM_SCALAR >
1490 std::vector< std::vector< GUM_SCALAR > >& v_rep)
const {
1500 std::ofstream h_file(sinefile.c_str(), std::ios::out | std::ios::trunc);
1503 GUM_ERROR(
IOError,
" __H2Vlrs : could not open lrs input file : " << sinefile)
1505 h_file <<
"H - representation\n";
1506 h_file <<
"begin\n";
1507 h_file << h_rep.size() <<
' ' << h_rep[0].size() <<
" rational\n";
1509 for (
auto it = h_rep.cbegin(), theEnd = h_rep.cend(); it != theEnd; ++it) {
1510 for (
auto it2 = it->cbegin(), theEnd2 = it->cend(); it2 != theEnd2; ++it2) {
1516 ((*it2 > 0) ? *it2 : -*it2),
1520 h_file << ((*it2 > 0) ? num : -num) <<
'/' << den <<
' ';
1530 std::string extfile(sinefile);
1533 std::string lrs_arg0 =
"lrs";
1534 std::string lrs_arg1 = sinefile;
1535 std::string lrs_arg2 = extfile;
1536 char* lrs_argv[3] = {lrs_arg0.data(), lrs_arg1.data(), lrs_arg2.data()};
1539 lrs_main(3, lrs_argv);
1542 std::ifstream v_file(extfile.c_str() , std::ios::in);
1544 if (!v_file.good())
GUM_ERROR(
IOError,
" __H2Vlrs : could not open lrs output file : ")
1546 std::string line, tmp;
1548 GUM_SCALAR probability;
1550 std::string::size_type pos;
1551 bool keep_going =
true;
1554 std::vector< GUM_SCALAR > vertex;
1556 v_file.ignore(256,
'l');
1558 while (v_file.good() && keep_going) {
1559 getline(v_file, line);
1561 if (line.size() == 0)
continue;
1562 else if (line.compare(
"end") == 0) {
1572 }
else if (line[1] !=
'1') {
1574 " __H2Vlrs : reading something other than a vertex from "
1575 "lrs output file : ");
1578 line = line.substr(2);
1579 cstr =
new char[line.size() + 1];
1580 strcpy(cstr, line.c_str());
1582 p = strtok(cstr,
" ");
1584 while (p !=
nullptr) {
1587 if (tmp.compare(
"1") == 0 || tmp.compare(
"0") == 0)
1588 probability = GUM_SCALAR(atof(tmp.c_str()));
1590 pos = tmp.find(
"/");
1591 probability = GUM_SCALAR(atof(tmp.substr(0, pos).c_str())
1592 / atof(tmp.substr(pos + 1, tmp.size()).c_str()));
1595 vertex.push_back(probability);
1596 p = strtok(
nullptr,
" ");
1607 const auto nsize = v_rep.size();
1608 const auto real_nb_threads = std::min(nb_threads, nsize);
1612 std::vector< Size > t_redund(real_nb_threads);
1615 auto threadedExec = [
this, ranges, &t_redund, vertex, v_rep](
const std::size_t this_thread,
1616 const std::size_t nb_threads) {
1617 const auto vsize = vertex.size();
1618 auto& thread_redund = t_redund[this_thread];
1620 for (
Idx i = ranges[this_thread].first, end = ranges[this_thread].second; i < end; i++) {
1622 for (
Idx modality = 0; modality < vsize; ++modality) {
1623 if (std::fabs(vertex[modality] - v_rep[i][modality]) >
_epsRedund_) {
1629 if (thread_redund)
return;
1637 bool is_redund =
false;
1638 for (
const auto thread_redund: t_redund) {
1639 if (thread_redund) {
1681 if (!is_redund) v_rep.push_back(vertex);
1688 if (std::remove(sinefile.c_str()) != 0)
GUM_ERROR(
IOError,
"error removing : " + sinefile)
1690 if (std::remove(extfile.c_str()) != 0)
GUM_ERROR(
IOError,
"error removing : " + extfile)
1693 template < GUM_Numeric GUM_SCALAR >
1701 for (
auto node: bn_ptr->nodes()) {
1703 if (nodeType_ptr->
exists(node))
continue;
1705 bool precise =
true, vacuous =
true;
1707 for (
auto entry = (*cpt_ptr)[node].cbegin(), theEnd2 = (*cpt_ptr)[node].cend();
1710 auto vertices = entry->size();
1711 auto var_dSize = (*entry)[0].size();
1713 if (precise && vertices > 1) precise =
false;
1715 if (vacuous && vertices == var_dSize) {
1716 std::vector< bool > elem(var_dSize,
false);
1718 for (
auto vertex = entry->cbegin(), vEnd = entry->cend(); vertex != vEnd; ++vertex) {
1719 for (
auto probability = vertex->cbegin(), pEnd = vertex->cend(); probability != pEnd;
1721 if (*probability == 1) {
1722 elem[probability - vertex->begin()] =
true;
1728 for (
auto probability = elem.cbegin(); probability != elem.cend(); ++probability)
1729 if (*probability ==
false) vacuous =
false;
1734 if (vacuous ==
false && precise ==
false) {
Definition of templatized reader of BIF files for Bayesian networks.
Size proceed() override
parse.
Writes a IBayesNet in the BIF format.
void write(std::ostream &output, IBayesNet< GUM_SCALAR > &bn)
Writes a Bayesian network in the output stream.
Exception base for CPT error.
virtual Size domainSize() const =0
Exception : a similar element already exists.
Base class for all aGrUM's exceptions.
value_type & insert(const Key &key, const Val &val)
Adds a new element (actually a copy of this element) into the hash table.
bool exists(const Key &key) const
Checks whether there exists an element with a given key in the hashtable.
Exception : input/output problem.
Class for assigning/browsing values to tuples of discrete variables.
const Sequence< const DiscreteVariable * > & variablesSequence() const final
Returns the sequence of DiscreteVariable of this instantiation.
Idx pos(const DiscreteVariable &v) const final
Returns the position of the variable v.
void erase(const DiscreteVariable &v) final
Removes a variable from the Instantiation.
void reorder(const Sequence< const DiscreteVariable * > &v)
Reorder vars of this instantiation giving the order in v.
Idx val(Idx i) const
Returns the current value of the variable at position i.
void setFirst()
Assign the first values to the tuple of the Instantiation.
const DiscreteVariable & variable(Idx i) const final
Returns the variable at position i in the tuple.
Idx nbrDim() const final
Returns the number of variables in the Instantiation.
bool forgetMaster()
Deassociate the master MultiDimAdressable, if any.
Exception : operation not allowed.
static void farey(int64_t &numerator, int64_t &denominator, const GUM_SCALAR &number, const int64_t &den_max=1000000L, const GUM_SCALAR &zero=1e-6)
Find the rational close enough to a given ( decimal ) number in [-1,1] and whose denominator is not h...
Exception : problem with size.
void _H2Vlrs_(const std::vector< std::vector< GUM_SCALAR > > &h_rep, std::vector< std::vector< GUM_SCALAR > > &v_rep) const
void _initParams_()
Initialize private constant variables after the Constructor has been called.
GUM_SCALAR _epsilonMoy_
The average perturbation of the BayesNet provided as input for this CredalNet.
void setCPTs(const NodeId &id, const std::vector< std::vector< std::vector< GUM_SCALAR > > > &cpt)
Set the vertices of the credal sets ( all of the conditionals ) of a given node
GUM_SCALAR _deltaC_
5 by default, used by fracC as number of decimals.
Size domainSize(const NodeId &id)
Get the cardinality of a node
BayesNet< GUM_SCALAR > _src_bn_max_
BayesNet used to store upper probabilities.
void intervalToCredalWithFiles()
void _initCNNets_(std::string_view src_min_num, std::string_view src_max_den)
Initialize private BayesNet variables after the Constructor has been called.
BayesNet< GUM_SCALAR > * _current_bn_
Up-to-date BayesNet (used as a DAG).
void _intervalToCredal_()
Computes the vertices of each credal set according to their interval definition (does not use lrs).
std::string toString() const
bool _hasComputedBinaryCPTMinMax_
Used by L2U, to know if lower and upper probabilities over the second modality has been stored in ord...
NodeProperty< std::vector< std::vector< std::vector< GUM_SCALAR > > > > _credalNet_src_cpt_
This CredalNet original CPTs.
const GUM_SCALAR & epsilonMax() const
void _bnCopy_(BayesNet< GUM_SCALAR > &bn_dest)
bool hasComputedBinaryCPTMinMax() const
GUM_SCALAR _precision_
Precision used by frac.
const NodeProperty< std::vector< std::vector< std::vector< GUM_SCALAR > > > > & credalNet_currentCpt() const
void bnToCredal(GUM_SCALAR beta, bool oneNet, bool keepZeroes)
Perturbates the BayesNet provided as input for this CredalNet by generating intervals instead of poin...
void intervalToCredal()
Computes the vertices of each credal set according to their interval definition (uses lrs).
const GUM_SCALAR & epsilonMean() const
std::vector< std::vector< GUM_SCALAR > > _binCptMin_
Used with binary networks to speed-up L2U inference.
void saveBNsMinMax(std::string_view min_path, std::string_view max_path)
If this CredalNet was built over a perturbed BayesNet, one can save the intervals as two BayesNet.
void approximatedBinarization()
Approximate binarization.
const BayesNet< GUM_SCALAR > & src_bn() const
int _find_dNode_card_(const std::vector< std::vector< std::vector< GUM_SCALAR > > > &var_cpt) const
BayesNet< GUM_SCALAR > _src_bn_
Original BayesNet (used as a DAG).
void computeBinaryCPTMinMax()
Used with binary networks to speed-up L2U inference.
const NodeProperty< std::vector< std::vector< std::vector< GUM_SCALAR > > > > & credalNet_srcCpt() const
NodeType currentNodeType(const NodeId &id) const
NodeProperty< NodeType > _original_nodeType_
The NodeType of each node from the ORIGINAL network.
void lagrangeNormalization()
Normalize counts of a BayesNet storing counts of each events such that no probability is 0.
NodeProperty< std::vector< std::vector< std::vector< GUM_SCALAR > > > > * _credalNet_current_cpt_
This CredalNet up-to-date CPTs.
bool isSeparatelySpecified() const
void _sort_varType_()
Set the NodeType of each node
void idmLearning(const Idx s=0, const bool keepZeroes=false)
Learns parameters from a BayesNet storing counts of events.
GUM_SCALAR _epsilonMax_
The highest perturbation of the BayesNet provided as input for this CredalNet.
std::vector< std::vector< GUM_SCALAR > > _binCptMax_
Used with binary networks to speed-up L2U inference.
NodeType nodeType(const NodeId &id) const
Instantiation instantiation(const NodeId &id)
Get an Instantiation from a node id, useful to fill the constraints of the network
bool _separatelySpecified_
TRUE if this CredalNet is separately and interval specified, FALSE otherwise.
void setCPT(const NodeId &id, const Size &entry, const std::vector< std::vector< GUM_SCALAR > > &cpt)
Set the vertices of one credal set of a given node ( any instantiation index )
NodeProperty< std::vector< NodeId > > _var_bits_
Corresponding bits of each variable.
const std::vector< std::vector< GUM_SCALAR > > & get_binaryCPT_max() const
Used with binary networks to speed-up L2U inference.
BayesNet< GUM_SCALAR > _src_bn_min_
BayesNet used to store lower probabilities.
NodeId addVariable(std::string_view name, const Size &card)
Adds a discrete node into the network.
const BayesNet< GUM_SCALAR > & current_bn() const
void addArc(const NodeId &tail, const NodeId &head)
Adds an arc between two nodes.
const std::vector< std::vector< GUM_SCALAR > > & get_binaryCPT_min() const
Used with binary networks to speed-up L2U inference.
void fillConstraints(const NodeId &id, const std::vector< GUM_SCALAR > &lower, const std::vector< GUM_SCALAR > &upper)
Set the interval constraints of the credal sets of a given node (all instantiations )
GUM_SCALAR _epsilonMin_
The lowest perturbation of the BayesNet provided as input for this CredalNet.
const GUM_SCALAR & epsilonMin() const
NodeProperty< NodeType > * _current_nodeType_
The NodeType of each node from the up-to-date network.
GUM_SCALAR _denMax_
Highest possible denominator allowed when using farey.
void fillConstraint(const NodeId &id, const Idx &entry, const std::vector< GUM_SCALAR > &lower, const std::vector< GUM_SCALAR > &upper)
Set the interval constraints of a credal set of a given node ( from an instantiation index )
GUM_SCALAR _epsRedund_
Value under which a decimal number is considered to be zero when computing redundant vertices.
GUM_SCALAR _precisionC_
1e6 by default, used by fracC as precision.
NodeType
NodeType to speed-up computations in some algorithms.
CredalNet()
Constructor used to create a CredalNet step by step, i.e.
GUM_SCALAR _epsF_
Value under which a decimal number is considered to be zero when using farey.
Class template acting as a wrapper for Lexicographic Reverse Search by David Avis.
const matrix & getOutput() const
Get the output matrix solution of the problem.
void H2V()
H-representation to V-representation.
void fillH(const GUM_SCALAR &min, const GUM_SCALAR &max, const Size &modal)
Creates the H-representation of min <= p(X=modal | .) <= max and add it to the problem input _input_.
void setUpH(const Size &card)
Sets up an H-representation.
void nextHInput()
Reset the wrapper for next computation for a H-representation with the same variable cardinality and ...
Class representing Credal Networks.
#define GUM_ERROR(type, msg)
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Size Idx
Type for indexes.
Size NodeId
Type for node ids.
HashTable< NodeId, VAL > NodeProperty
Property on graph elements.
Set< NodeId > NodeSet
Some typdefs and define for shortcuts ...
uint64_t int2Pow(uint64_t exponent)
Specialized base 2 pow function with integer.
void superiorPow(unsigned long card, unsigned long &num_bits, unsigned long &new_card)
Compute the superior and closest power of two of an integer.
std::string getUniqueFileName()
Returns a path to a unique file name.
namespace for all credal networks entities
gum is the global namespace for all aGrUM entities
std::vector< std::pair< Idx, Idx > > dispatchRangeToThreads(const Idx beg, const Idx end, const unsigned int nb_threads)
returns a vector equally splitting elements of a range among threads
unsigned int getNumberOfThreads()
returns the max number of threads used by default when entering the next parallel region
bool isCloseToOne(T x, T tol=T(1e-9))
static void execute(std::size_t nb_threads, FUNCTION exec_func, ARGS &&... func_args)
executes a function using several threads
static int nbRunningThreadsExecutors()
indicates how many threadExecutors are currently running
Utilities for manipulating strings.