32 TableFactor::TableFactor() {}
50 double denom =
table.size();
53 denominators_.insert(std::pair<Key, double>(dkey.first, denom));
79 size_t cardinalityProduct = 1;
80 for (
auto&& [
_,
c] :
dt.cardinalities()) {
81 cardinalityProduct *=
c;
85 dt.visit([&nrValues](
double x) {
86 if (
x > 0) nrValues += 1;
90 KeySet allKeys(
dt.keys().begin(),
dt.keys().end());
93 std::map<Key, size_t> denominators;
94 double denom = sparseTable.size();
97 denominators.
insert(std::pair<Key, double>(dkey.first, denom));
114 for (
auto&& [k,
_] : assignment) {
115 assignmentKeys.insert(k);
120 std::set_difference(allKeys.begin(), allKeys.end(),
121 assignmentKeys.begin(), assignmentKeys.end(),
122 std::back_inserter(diff));
126 for (
auto&&
key : diff) {
127 extras.push_back({
key,
dt.cardinality(
key)});
131 for (
auto&& extra : extraAssignments) {
134 updatedAssignment.
insert(extra);
139 for (
auto&& it = updatedAssignment.rbegin();
140 it != updatedAssignment.rend(); it++) {
141 idx += it->second * denominators.at(it->first);
175 if (
table.size() != max_size) {
176 throw std::runtime_error(
177 "The cardinalities of the keys don't match the number of values in the "
189 sparse_table.pruned();
196 const std::string&
table) {
198 std::vector<double> ys;
199 std::istringstream iss(
table);
200 std::copy(std::istream_iterator<double>(iss), std::istream_iterator<double>(),
201 std::back_inserter(ys));
222 idx += card *
values.at(it->first);
233 for (
auto it =
keys_.rbegin(); it !=
keys_.rend(); ++it) {
235 idx += card *
values.at(*it);
261 if (
auto tf = std::dynamic_pointer_cast<TableFactor>(
f)) {
263 result = std::make_shared<TableFactor>(this->
operator*(*tf));
265 }
else if (
auto dtf = std::dynamic_pointer_cast<DecisionTreeFactor>(
f)) {
277 result = std::make_shared<DecisionTreeFactor>(
278 f->operator*(
this->toDecisionTreeFactor()));
286 if (
auto tf = std::dynamic_pointer_cast<TableFactor>(
f)) {
287 return std::make_shared<TableFactor>(this->
operator/(*tf));
288 }
else if (
auto dtf = std::dynamic_pointer_cast<DecisionTreeFactor>(
f)) {
289 return std::make_shared<TableFactor>(
290 this->
operator/(
TableFactor(f->discreteKeys(), *dtf)));
293 return std::make_shared<TableFactor>(this->
operator/(divisor));
302 if (dkeys.size() == 0) {
313 table[it.index()] = it.value();
324 if (parent_keys.empty())
return *
this;
329 for (
auto it =
keys_.rbegin(); it !=
keys_.rend(); ++it) {
330 if (parent_assign.find(*it) != parent_assign.end()) {
331 unique += parent_assign.at(*it) * card;
338 std::sort(parent_keys.begin(), parent_keys.end());
340 parent_keys.begin(), parent_keys.end(),
341 std::back_inserter(child_dkeys));
346 child_card *= child_dkey.second;
348 child_sparse_table_.
reserve(child_card);
355 if (parent_unique == unique) {
357 child_sparse_table_.
insert(idx) = it.value();
361 child_sparse_table_.pruned();
363 return TableFactor(child_dkeys, child_sparse_table_);
371 return (
a == 0 ||
b == 0) ? 0 : (
a /
b);
380 cout <<
" ]" << endl;
383 for (
auto&& kv : assignment) {
384 cout <<
"(" <<
formatter(kv.first) <<
", " << kv.second <<
")";
386 cout <<
" | " << std::setw(10) <<
std::left << it.value() <<
" | "
387 << it.index() << endl;
402 sparse_table.
coeffRef(it.index()) = op(it.value());
406 sparse_table.pruned();
422 sparse_table.
coeffRef(it.index()) = op(assignment, it.value());
426 sparse_table.pruned();
435 else if (
f.keys_.empty() &&
f.sparse_table_.nonZeros() == 0)
442 unordered_map<uint64_t, AssignValList> map_f =
443 f.createMap(contract_dkeys, f_free_dkeys);
446 for (
auto u_dkey : union_dkeys) card *= u_dkey.second;
448 mult_sparse_table.
reserve(card);
452 if (map_f.find(contract_unique) == map_f.end())
continue;
453 for (
auto assignVal : map_f[contract_unique]) {
455 mult_sparse_table.
insert(union_idx) = op(it.value(), assignVal.second);
459 mult_sparse_table.pruned();
462 return TableFactor(union_dkeys, mult_sparse_table);
470 f.sorted_dkeys_.begin(),
f.sorted_dkeys_.end(),
471 back_inserter(contract));
480 f.sorted_dkeys_.begin(),
f.sorted_dkeys_.end(),
481 back_inserter(free));
490 f.sorted_dkeys_.end(), back_inserter(union_dkeys));
499 for (
auto it = union_keys.rbegin(); it != union_keys.rend(); it++) {
500 if (f_free.find(it->first) == f_free.end()) {
503 union_idx += f_free.at(it->first) * card;
514 unordered_map<uint64_t, AssignValList> map_f;
521 for (
auto&
key : free)
524 if (map_f.find(unique_rep) == map_f.end()) {
525 map_f[unique_rep] = {make_pair(free_assignments, it.value())};
527 map_f[unique_rep].push_back(make_pair(free_assignments, it.value()));
536 if (dkeys.empty())
return 0;
538 for (
auto it = dkeys.rbegin(); it != dkeys.rend(); it++) {
547 if (assignments.empty())
return 0;
549 for (
auto it = assignments.rbegin(); it != assignments.rend(); it++) {
550 unique_rep += it->second * card;
568 if (nrFrontals >
size()) {
569 throw invalid_argument(
570 "TableFactor::combine: invalid number of frontal "
572 to_string(nrFrontals) +
", nr.keys=" + std::to_string(
size()));
577 for (
auto i = nrFrontals;
i <
keys_.size();
i++) {
587 double new_val = op(combined_table.
coeff(idx), it.value());
588 combined_table.
coeffRef(idx) = new_val;
591 combined_table.pruned();
593 return std::make_shared<TableFactor>(remain_dkeys, combined_table);
599 if (frontalKeys.size() >
size()) {
600 throw invalid_argument(
601 "TableFactor::combine: invalid number of frontal "
603 std::to_string(frontalKeys.size()) +
604 ", nr.keys=" + std::to_string(
size()));
610 if (std::find(frontalKeys.begin(), frontalKeys.end(),
key) ==
622 double new_val = op(combined_table.
coeff(idx), it.value());
623 combined_table.
coeffRef(idx) = new_val;
626 combined_table.pruned();
628 return std::make_shared<TableFactor>(remain_dkeys, combined_table);
640 std::vector<std::pair<Key, size_t>> pairs =
discreteKeys();
642 std::vector<std::pair<Key, size_t>> rpairs(pairs.rbegin(), pairs.rend());
645 std::vector<std::pair<DiscreteValues, double>>
result;
646 for (
const auto& assignment : assignments) {
647 result.emplace_back(assignment,
operator()(assignment));
661 ss << keyFormatter(
key) <<
"|";
667 for (
size_t j = 0;
j <
size();
j++)
ss <<
":-:|";
675 size_t index = assignment.at(
key);
678 ss << it.value() <<
"|\n";
689 ss <<
"<div>\n<table class='TableFactor'>\n <thead>\n";
694 ss <<
"<th>" << keyFormatter(
key) <<
"</th>";
696 ss <<
"<th>value</th></tr>\n";
699 ss <<
" </thead>\n <tbody>\n";
706 size_t index = assignment.at(
key);
709 ss <<
"<td>" << it.value() <<
"</td>";
712 ss <<
" </tbody>\n</table>\n</div>";
718 const size_t N = maxNrAssignments;
721 vector<pair<Eigen::Index, double>> probabilities;
725 probabilities.emplace_back(it.index(), it.value());
729 if (probabilities.size() <=
N)
return *
this;
732 sort(probabilities.begin(), probabilities.end(),
733 [](
const std::pair<Eigen::Index, double>&
a,
734 const std::pair<Eigen::Index, double>&
b) {
735 return a.second > b.second;
739 if (probabilities.size() >
N) probabilities.resize(
N);
743 pruned_vec.
reserve(probabilities.size());
746 for (
const auto& prob : probabilities) {
747 pruned_vec.
insert(prob.first) = prob.second;