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);
262 if (dkeys.size() == 0) {
273 table[it.index()] = it.value();
284 if (parent_keys.empty())
return *
this;
289 for (
auto it =
keys_.rbegin(); it !=
keys_.rend(); ++it) {
290 if (parent_assign.find(*it) != parent_assign.end()) {
291 unique += parent_assign.at(*it) * card;
298 std::sort(parent_keys.begin(), parent_keys.end());
300 parent_keys.begin(), parent_keys.end(),
301 std::back_inserter(child_dkeys));
306 child_card *= child_dkey.second;
308 child_sparse_table_.
reserve(child_card);
315 if (parent_unique == unique) {
317 child_sparse_table_.
insert(idx) = it.value();
321 child_sparse_table_.pruned();
323 return TableFactor(child_dkeys, child_sparse_table_);
331 return (
a == 0 ||
b == 0) ? 0 : (
a /
b);
340 cout <<
" ]" << endl;
343 for (
auto&& kv : assignment) {
344 cout <<
"(" <<
formatter(kv.first) <<
", " << kv.second <<
")";
346 cout <<
" | " << std::setw(10) <<
std::left << it.value() <<
" | "
347 << it.index() << endl;
362 sparse_table.
coeffRef(it.index()) = op(it.value());
366 sparse_table.pruned();
382 sparse_table.
coeffRef(it.index()) = op(assignment, it.value());
386 sparse_table.pruned();
395 else if (
f.keys_.empty() &&
f.sparse_table_.nonZeros() == 0)
402 unordered_map<uint64_t, AssignValList> map_f =
403 f.createMap(contract_dkeys, f_free_dkeys);
406 for (
auto u_dkey : union_dkeys) card *= u_dkey.second;
408 mult_sparse_table.
reserve(card);
412 if (map_f.find(contract_unique) == map_f.end())
continue;
413 for (
auto assignVal : map_f[contract_unique]) {
415 mult_sparse_table.
insert(union_idx) = op(it.value(), assignVal.second);
419 mult_sparse_table.pruned();
422 return TableFactor(union_dkeys, mult_sparse_table);
430 f.sorted_dkeys_.begin(),
f.sorted_dkeys_.end(),
431 back_inserter(contract));
440 f.sorted_dkeys_.begin(),
f.sorted_dkeys_.end(),
441 back_inserter(free));
450 f.sorted_dkeys_.end(), back_inserter(union_dkeys));
459 for (
auto it = union_keys.rbegin(); it != union_keys.rend(); it++) {
460 if (f_free.find(it->first) == f_free.end()) {
463 union_idx += f_free.at(it->first) * card;
474 unordered_map<uint64_t, AssignValList> map_f;
481 for (
auto&
key : free)
484 if (map_f.find(unique_rep) == map_f.end()) {
485 map_f[unique_rep] = {make_pair(free_assignments, it.value())};
487 map_f[unique_rep].push_back(make_pair(free_assignments, it.value()));
496 if (dkeys.empty())
return 0;
498 for (
auto it = dkeys.rbegin(); it != dkeys.rend(); it++) {
507 if (assignments.empty())
return 0;
509 for (
auto it = assignments.rbegin(); it != assignments.rend(); it++) {
510 unique_rep += it->second * card;
528 if (nrFrontals >
size()) {
529 throw invalid_argument(
530 "TableFactor::combine: invalid number of frontal "
532 to_string(nrFrontals) +
", nr.keys=" + std::to_string(
size()));
537 for (
auto i = nrFrontals;
i <
keys_.size();
i++) {
547 double new_val = op(combined_table.
coeff(idx), it.value());
548 combined_table.
coeffRef(idx) = new_val;
551 combined_table.pruned();
553 return std::make_shared<TableFactor>(remain_dkeys, combined_table);
559 if (frontalKeys.size() >
size()) {
560 throw invalid_argument(
561 "TableFactor::combine: invalid number of frontal "
563 std::to_string(frontalKeys.size()) +
564 ", nr.keys=" + std::to_string(
size()));
570 if (std::find(frontalKeys.begin(), frontalKeys.end(),
key) ==
582 double new_val = op(combined_table.
coeff(idx), it.value());
583 combined_table.
coeffRef(idx) = new_val;
586 combined_table.pruned();
588 return std::make_shared<TableFactor>(remain_dkeys, combined_table);
600 std::vector<std::pair<Key, size_t>> pairs =
discreteKeys();
602 std::vector<std::pair<Key, size_t>> rpairs(pairs.rbegin(), pairs.rend());
605 std::vector<std::pair<DiscreteValues, double>>
result;
606 for (
const auto& assignment : assignments) {
607 result.emplace_back(assignment,
operator()(assignment));
621 ss << keyFormatter(
key) <<
"|";
627 for (
size_t j = 0;
j <
size();
j++)
ss <<
":-:|";
635 size_t index = assignment.at(
key);
638 ss << it.value() <<
"|\n";
649 ss <<
"<div>\n<table class='TableFactor'>\n <thead>\n";
654 ss <<
"<th>" << keyFormatter(
key) <<
"</th>";
656 ss <<
"<th>value</th></tr>\n";
659 ss <<
" </thead>\n <tbody>\n";
666 size_t index = assignment.at(
key);
669 ss <<
"<td>" << it.value() <<
"</td>";
672 ss <<
" </tbody>\n</table>\n</div>";
678 const size_t N = maxNrAssignments;
681 vector<pair<Eigen::Index, double>> probabilities;
685 probabilities.emplace_back(it.index(), it.value());
689 if (probabilities.size() <=
N)
return *
this;
692 sort(probabilities.begin(), probabilities.end(),
693 [](
const std::pair<Eigen::Index, double>&
a,
694 const std::pair<Eigen::Index, double>&
b) {
695 return a.second > b.second;
699 if (probabilities.size() >
N) probabilities.resize(
N);
703 pruned_vec.
reserve(probabilities.size());
706 for (
const auto& prob : probabilities) {
707 pruned_vec.
insert(prob.first) = prob.second;