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;
404 double max_value = std::numeric_limits<double>::lowest();
406 max_value =
std::max(max_value, it.value());
431 sparse_table.
coeffRef(it.index()) = op(it.value());
435 sparse_table.pruned();
451 sparse_table.
coeffRef(it.index()) = op(assignment, it.value());
455 sparse_table.pruned();
464 else if (
f.keys_.empty() &&
f.sparse_table_.nonZeros() == 0)
471 unordered_map<uint64_t, AssignValList> map_f =
472 f.createMap(contract_dkeys, f_free_dkeys);
475 for (
auto u_dkey : union_dkeys) card *= u_dkey.second;
477 mult_sparse_table.
reserve(card);
481 if (map_f.find(contract_unique) == map_f.end())
continue;
482 for (
auto assignVal : map_f[contract_unique]) {
484 mult_sparse_table.
insert(union_idx) = op(it.value(), assignVal.second);
488 mult_sparse_table.pruned();
491 return TableFactor(union_dkeys, mult_sparse_table);
499 f.sorted_dkeys_.begin(),
f.sorted_dkeys_.end(),
500 back_inserter(contract));
509 f.sorted_dkeys_.begin(),
f.sorted_dkeys_.end(),
510 back_inserter(free));
519 f.sorted_dkeys_.end(), back_inserter(union_dkeys));
528 for (
auto it = union_keys.rbegin(); it != union_keys.rend(); it++) {
529 if (f_free.find(it->first) == f_free.end()) {
532 union_idx += f_free.at(it->first) * card;
543 unordered_map<uint64_t, AssignValList> map_f;
550 for (
auto&
key : free)
553 if (map_f.find(unique_rep) == map_f.end()) {
554 map_f[unique_rep] = {make_pair(free_assignments, it.value())};
556 map_f[unique_rep].push_back(make_pair(free_assignments, it.value()));
565 if (dkeys.empty())
return 0;
567 for (
auto it = dkeys.rbegin(); it != dkeys.rend(); it++) {
576 if (assignments.empty())
return 0;
578 for (
auto it = assignments.rbegin(); it != assignments.rend(); it++) {
579 unique_rep += it->second * card;
597 if (nrFrontals >
size()) {
598 throw invalid_argument(
599 "TableFactor::combine: invalid number of frontal "
601 to_string(nrFrontals) +
", nr.keys=" + std::to_string(
size()));
606 for (
auto i = nrFrontals;
i <
keys_.size();
i++) {
616 double new_val = op(combined_table.
coeff(idx), it.value());
617 combined_table.
coeffRef(idx) = new_val;
620 combined_table.pruned();
622 return std::make_shared<TableFactor>(remain_dkeys, combined_table);
628 if (frontalKeys.size() >
size()) {
629 throw invalid_argument(
630 "TableFactor::combine: invalid number of frontal "
632 std::to_string(frontalKeys.size()) +
633 ", nr.keys=" + std::to_string(
size()));
639 if (std::find(frontalKeys.begin(), frontalKeys.end(),
key) ==
651 double new_val = op(combined_table.
coeff(idx), it.value());
652 combined_table.
coeffRef(idx) = new_val;
655 combined_table.pruned();
657 return std::make_shared<TableFactor>(remain_dkeys, combined_table);
669 std::vector<std::pair<Key, size_t>> pairs =
discreteKeys();
671 std::vector<std::pair<Key, size_t>> rpairs(pairs.rbegin(), pairs.rend());
674 std::vector<std::pair<DiscreteValues, double>>
result;
675 for (
const auto& assignment : assignments) {
676 result.emplace_back(assignment,
operator()(assignment));
690 ss << keyFormatter(
key) <<
"|";
696 for (
size_t j = 0;
j <
size();
j++)
ss <<
":-:|";
704 size_t index = assignment.at(
key);
707 ss << it.value() <<
"|\n";
718 ss <<
"<div>\n<table class='TableFactor'>\n <thead>\n";
723 ss <<
"<th>" << keyFormatter(
key) <<
"</th>";
725 ss <<
"<th>value</th></tr>\n";
728 ss <<
" </thead>\n <tbody>\n";
735 size_t index = assignment.at(
key);
738 ss <<
"<td>" << it.value() <<
"</td>";
741 ss <<
" </tbody>\n</table>\n</div>";
747 const size_t N = maxNrAssignments;
750 vector<pair<Eigen::Index, double>> probabilities;
754 probabilities.emplace_back(it.index(), it.value());
758 if (probabilities.size() <=
N)
return *
this;
761 sort(probabilities.begin(), probabilities.end(),
762 [](
const std::pair<Eigen::Index, double>&
a,
763 const std::pair<Eigen::Index, double>&
b) {
764 return a.second > b.second;
768 if (probabilities.size() >
N) probabilities.resize(
N);
772 pruned_vec.
reserve(probabilities.size());
775 for (
const auto& prob : probabilities) {
776 pruned_vec.
insert(prob.first) = prob.second;
786 throw std::runtime_error(
"TableFactor::restrict not implemented");