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 std::set<Key> allKeys(
dt.keys().begin(),
dt.keys().end());
105 std::set<Key> assignmentKeys;
106 for (
auto&& [k,
_] : assignment) {
107 assignmentKeys.insert(k);
111 std::vector<Key> diff;
112 std::set_difference(allKeys.begin(), allKeys.end(),
113 assignmentKeys.begin(), assignmentKeys.end(),
114 std::back_inserter(diff));
118 for (
auto&&
key : diff) {
119 extras.push_back({
key,
dt.cardinality(
key)});
123 for (
auto&& extra : extraAssignments) {
126 updatedAssignment.
insert(extra);
130 size_t previousCardinality = 1;
132 for (
auto&& it = updatedAssignment.rbegin();
133 it != updatedAssignment.rend(); it++) {
134 idx += previousCardinality * it->second;
135 previousCardinality *=
dt.cardinality(it->first);
170 if (
table.size() != max_size) {
171 throw std::runtime_error(
172 "The cardinalities of the keys don't match the number of values in the "
184 sparse_table.pruned();
191 const std::string&
table) {
193 std::vector<double> ys;
194 std::istringstream iss(
table);
195 std::copy(std::istream_iterator<double>(iss), std::istream_iterator<double>(),
196 std::back_inserter(ys));
217 idx += card *
values.at(it->first);
228 for (
auto it =
keys_.rbegin(); it !=
keys_.rend(); ++it) {
230 idx += card *
values.at(*it);
255 std::vector<double>
table;
267 if (parent_keys.empty())
return *
this;
272 for (
auto it =
keys_.rbegin(); it !=
keys_.rend(); ++it) {
273 if (parent_assign.find(*it) != parent_assign.end()) {
274 unique += parent_assign.at(*it) * card;
281 std::sort(parent_keys.begin(), parent_keys.end());
283 parent_keys.begin(), parent_keys.end(),
284 std::back_inserter(child_dkeys));
289 child_card *= child_dkey.second;
291 child_sparse_table_.
reserve(child_card);
298 if (parent_unique == unique) {
300 child_sparse_table_.
insert(idx) = it.value();
304 child_sparse_table_.pruned();
306 return TableFactor(child_dkeys, child_sparse_table_);
314 return (
a == 0 ||
b == 0) ? 0 : (
a /
b);
323 cout <<
" ]" << endl;
326 for (
auto&& kv : assignment) {
327 cout <<
"(" <<
formatter(kv.first) <<
", " << kv.second <<
")";
329 cout <<
" | " << std::setw(10) <<
std::left << it.value() <<
" | "
330 << it.index() << endl;
345 sparse_table.
coeffRef(it.index()) = op(it.value());
349 sparse_table.pruned();
365 sparse_table.
coeffRef(it.index()) = op(assignment, it.value());
369 sparse_table.pruned();
378 else if (
f.keys_.empty() &&
f.sparse_table_.nonZeros() == 0)
385 unordered_map<uint64_t, AssignValList> map_f =
386 f.createMap(contract_dkeys, f_free_dkeys);
389 for (
auto u_dkey : union_dkeys) card *= u_dkey.second;
391 mult_sparse_table.
reserve(card);
395 if (map_f.find(contract_unique) == map_f.end())
continue;
396 for (
auto assignVal : map_f[contract_unique]) {
398 mult_sparse_table.
insert(union_idx) = op(it.value(), assignVal.second);
402 mult_sparse_table.pruned();
405 return TableFactor(union_dkeys, mult_sparse_table);
413 f.sorted_dkeys_.begin(),
f.sorted_dkeys_.end(),
414 back_inserter(contract));
423 f.sorted_dkeys_.begin(),
f.sorted_dkeys_.end(),
424 back_inserter(free));
433 f.sorted_dkeys_.end(), back_inserter(union_dkeys));
442 for (
auto it = union_keys.rbegin(); it != union_keys.rend(); it++) {
443 if (f_free.find(it->first) == f_free.end()) {
446 union_idx += f_free.at(it->first) * card;
457 unordered_map<uint64_t, AssignValList> map_f;
464 for (
auto&
key : free)
467 if (map_f.find(unique_rep) == map_f.end()) {
468 map_f[unique_rep] = {make_pair(free_assignments, it.value())};
470 map_f[unique_rep].push_back(make_pair(free_assignments, it.value()));
479 if (dkeys.empty())
return 0;
481 for (
auto it = dkeys.rbegin(); it != dkeys.rend(); it++) {
490 if (assignments.empty())
return 0;
492 for (
auto it = assignments.rbegin(); it != assignments.rend(); it++) {
493 unique_rep += it->second * card;
511 if (nrFrontals >
size()) {
512 throw invalid_argument(
513 "TableFactor::combine: invalid number of frontal "
515 to_string(nrFrontals) +
", nr.keys=" + std::to_string(
size()));
520 for (
auto i = nrFrontals;
i <
keys_.size();
i++) {
530 double new_val = op(combined_table.
coeff(idx), it.value());
531 combined_table.
coeffRef(idx) = new_val;
534 combined_table.pruned();
536 return std::make_shared<TableFactor>(remain_dkeys, combined_table);
542 if (frontalKeys.size() >
size()) {
543 throw invalid_argument(
544 "TableFactor::combine: invalid number of frontal "
546 std::to_string(frontalKeys.size()) +
547 ", nr.keys=" + std::to_string(
size()));
553 if (std::find(frontalKeys.begin(), frontalKeys.end(),
key) ==
565 double new_val = op(combined_table.
coeff(idx), it.value());
566 combined_table.
coeffRef(idx) = new_val;
569 combined_table.pruned();
571 return std::make_shared<TableFactor>(remain_dkeys, combined_table);
583 std::vector<std::pair<Key, size_t>> pairs =
discreteKeys();
585 std::vector<std::pair<Key, size_t>> rpairs(pairs.rbegin(), pairs.rend());
588 std::vector<std::pair<DiscreteValues, double>>
result;
589 for (
const auto& assignment : assignments) {
590 result.emplace_back(assignment,
operator()(assignment));
604 ss << keyFormatter(
key) <<
"|";
610 for (
size_t j = 0;
j <
size();
j++)
ss <<
":-:|";
618 size_t index = assignment.at(
key);
621 ss << it.value() <<
"|\n";
632 ss <<
"<div>\n<table class='TableFactor'>\n <thead>\n";
637 ss <<
"<th>" << keyFormatter(
key) <<
"</th>";
639 ss <<
"<th>value</th></tr>\n";
642 ss <<
" </thead>\n <tbody>\n";
649 size_t index = assignment.at(
key);
652 ss <<
"<td>" << it.value() <<
"</td>";
655 ss <<
" </tbody>\n</table>\n</div>";
661 const size_t N = maxNrAssignments;
664 vector<pair<Eigen::Index, double>> probabilities;
668 probabilities.emplace_back(it.index(), it.value());
672 if (probabilities.size() <=
N)
return *
this;
675 sort(probabilities.begin(), probabilities.end(),
676 [](
const std::pair<Eigen::Index, double>&
a,
677 const std::pair<Eigen::Index, double>&
b) {
678 return a.second > b.second;
682 if (probabilities.size() >
N) probabilities.resize(
N);
686 pruned_vec.
reserve(probabilities.size());
689 for (
const auto& prob : probabilities) {
690 pruned_vec.
insert(prob.first) = prob.second;