More sophisticated markdown
parent
791e04e9f3
commit
839679eb7d
|
|
@ -227,41 +227,66 @@ std::string DiscreteConditional::_repr_markdown_(
|
||||||
const KeyFormatter& keyFormatter) const {
|
const KeyFormatter& keyFormatter) const {
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
|
|
||||||
|
// Print out signature.
|
||||||
|
ss << " $P(";
|
||||||
|
for(Key key: frontals())
|
||||||
|
ss << keyFormatter(key);
|
||||||
|
if (nrParents() > 0)
|
||||||
|
ss << "|";
|
||||||
|
bool first = true;
|
||||||
|
for (Key parent : parents()) {
|
||||||
|
if (!first) ss << ",";
|
||||||
|
ss << keyFormatter(parent);
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
ss << ")$:" << std::endl;
|
||||||
|
|
||||||
// Print out header and construct argument for `cartesianProduct`.
|
// Print out header and construct argument for `cartesianProduct`.
|
||||||
// TODO(dellaert): examine why we can't use "for (auto key: frontals())"
|
|
||||||
std::vector<std::pair<Key, size_t>> pairs;
|
std::vector<std::pair<Key, size_t>> pairs;
|
||||||
ss << "|";
|
ss << "|";
|
||||||
const_iterator it;
|
const_iterator it;
|
||||||
for (it = beginParents(); it != endParents(); ++it) {
|
for(Key parent: parents()) {
|
||||||
auto key = *it;
|
ss << keyFormatter(parent) << "|";
|
||||||
ss << keyFormatter(key) << "|";
|
pairs.emplace_back(parent, cardinalities_.at(parent));
|
||||||
pairs.emplace_back(key, cardinalities_.at(key));
|
|
||||||
}
|
}
|
||||||
for (it = beginFrontals(); it != endFrontals(); ++it) {
|
|
||||||
auto key = *it;
|
size_t n = 1;
|
||||||
ss << keyFormatter(key) << "|";
|
for(Key key: frontals()) {
|
||||||
pairs.emplace_back(key, cardinalities_.at(key));
|
size_t k = cardinalities_.at(key);
|
||||||
|
pairs.emplace_back(key, k);
|
||||||
|
n *= k;
|
||||||
}
|
}
|
||||||
ss << "value|\n";
|
size_t nrParents = size() - nrFrontals_;
|
||||||
|
std::vector<std::pair<Key, size_t>> slatnorf(pairs.rbegin(),
|
||||||
|
pairs.rend() - nrParents);
|
||||||
|
const auto frontal_assignments = cartesianProduct(slatnorf);
|
||||||
|
for (const auto& a : frontal_assignments) {
|
||||||
|
for (it = beginFrontals(); it != endFrontals(); ++it) ss << a.at(*it);
|
||||||
|
ss << "|";
|
||||||
|
}
|
||||||
|
ss << "\n";
|
||||||
|
|
||||||
// Print out separator with alignment hints.
|
// Print out separator with alignment hints.
|
||||||
ss << "|";
|
ss << "|";
|
||||||
for (size_t j = 0; j < size(); j++) ss << ":-:|";
|
for (size_t j = 0; j < nrParents + n; j++) ss << ":-:|";
|
||||||
ss << ":-:|\n";
|
ss << "\n";
|
||||||
|
|
||||||
// Print out all rows.
|
// Print out all rows.
|
||||||
std::vector<std::pair<Key, size_t>> rpairs(pairs.rbegin(), pairs.rend());
|
std::vector<std::pair<Key, size_t>> rpairs(pairs.rbegin(), pairs.rend());
|
||||||
const auto assignments = cartesianProduct(rpairs);
|
const auto assignments = cartesianProduct(rpairs);
|
||||||
|
size_t count = 0;
|
||||||
for (const auto& a : assignments) {
|
for (const auto& a : assignments) {
|
||||||
ss << "|";
|
if (count == 0) {
|
||||||
for (it = beginParents(); it != endParents(); ++it) ss << a.at(*it) << "|";
|
ss << "|";
|
||||||
for (it = beginFrontals(); it != endFrontals(); ++it)
|
for (it = beginParents(); it != endParents(); ++it)
|
||||||
ss << "*" << a.at(*it) << "*|";
|
ss << a.at(*it) << "|";
|
||||||
ss << operator()(a) << "|\n";
|
}
|
||||||
|
ss << operator()(a) << "|";
|
||||||
|
count = (count + 1) % n;
|
||||||
|
if (count == 0) ss << "\n";
|
||||||
}
|
}
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
/* ********************************************************************************
|
/* ************************************************************************* */
|
||||||
*/
|
|
||||||
|
|
||||||
}// namespace
|
} // namespace gtsam
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ using namespace boost::assign;
|
||||||
#include <CppUnitLite/TestHarness.h>
|
#include <CppUnitLite/TestHarness.h>
|
||||||
#include <gtsam/discrete/DecisionTreeFactor.h>
|
#include <gtsam/discrete/DecisionTreeFactor.h>
|
||||||
#include <gtsam/discrete/DiscreteConditional.h>
|
#include <gtsam/discrete/DiscreteConditional.h>
|
||||||
|
#include <gtsam/inference/Symbol.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace gtsam;
|
using namespace gtsam;
|
||||||
|
|
@ -107,40 +108,53 @@ TEST(DiscreteConditional, Combine) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
// TEST(DiscreteConditional, Combine2) {
|
// Check markdown representation looks as expected, no parents.
|
||||||
// DiscreteKey A(0, 3), B(1, 2), C(2, 2);
|
TEST(DiscreteConditional, markdown_prior) {
|
||||||
// vector<DiscreteConditional::shared_ptr> c;
|
DiscreteKey A(Symbol('x', 1), 2);
|
||||||
// auto P = {B, C};
|
DiscreteConditional conditional(A % "1/3");
|
||||||
// c.push_back(boost::make_shared<DiscreteConditional>(A, P, "1/2 2/1 1/2 2/1"));
|
string expected =
|
||||||
// c.push_back(boost::make_shared<DiscreteConditional>(B | C = "1/2"));
|
" $P(x1)$:\n"
|
||||||
// auto actual = DiscreteConditional::Combine(c.begin(), c.end());
|
"|0|1|\n"
|
||||||
// GTSAM_PRINT(*actual);
|
"|:-:|:-:|\n"
|
||||||
// }
|
"|0.25|0.75|\n";
|
||||||
|
string actual = conditional._repr_markdown_();
|
||||||
|
EXPECT(actual == expected);
|
||||||
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
// Check markdown representation looks as expected.
|
// Check markdown representation looks as expected, multivalued.
|
||||||
|
TEST(DiscreteConditional, markdown_multivalued) {
|
||||||
|
DiscreteKey A(Symbol('a', 1), 3), B(Symbol('b', 1), 5);
|
||||||
|
DiscreteConditional conditional(
|
||||||
|
A | B = "2/88/10 2/20/78 33/33/34 33/33/34 95/2/3");
|
||||||
|
string expected =
|
||||||
|
" $P(a1|b1)$:\n"
|
||||||
|
"|b1|0|1|2|\n"
|
||||||
|
"|:-:|:-:|:-:|:-:|\n"
|
||||||
|
"|0|0.02|0.88|0.1|\n"
|
||||||
|
"|1|0.02|0.2|0.78|\n"
|
||||||
|
"|2|0.33|0.33|0.34|\n"
|
||||||
|
"|3|0.33|0.33|0.34|\n"
|
||||||
|
"|4|0.95|0.02|0.03|\n";
|
||||||
|
string actual = conditional._repr_markdown_();
|
||||||
|
EXPECT(actual == expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ************************************************************************* */
|
||||||
|
// Check markdown representation looks as expected, two parents.
|
||||||
TEST(DiscreteConditional, markdown) {
|
TEST(DiscreteConditional, markdown) {
|
||||||
DiscreteKey A(2, 2), B(1, 2), C(0, 3);
|
DiscreteKey A(2, 2), B(1, 2), C(0, 3);
|
||||||
DiscreteConditional conditional(A, {B, C}, "0/1 1/3 1/1 3/1 0/1 1/0");
|
DiscreteConditional conditional(A, {B, C}, "0/1 1/3 1/1 3/1 0/1 1/0");
|
||||||
EXPECT_LONGS_EQUAL(A.first, *(conditional.beginFrontals()));
|
|
||||||
EXPECT_LONGS_EQUAL(B.first, *(conditional.beginParents()));
|
|
||||||
EXPECT(conditional.endParents() == conditional.end());
|
|
||||||
EXPECT(conditional.endFrontals() == conditional.beginParents());
|
|
||||||
string expected =
|
string expected =
|
||||||
"|B|C|A|value|\n"
|
" $P(A|B,C)$:\n"
|
||||||
|
"|B|C|0|1|\n"
|
||||||
"|:-:|:-:|:-:|:-:|\n"
|
"|:-:|:-:|:-:|:-:|\n"
|
||||||
"|0|0|*0*|0|\n"
|
"|0|0|0|1|\n"
|
||||||
"|0|0|*1*|1|\n"
|
"|0|1|0.25|0.75|\n"
|
||||||
"|0|1|*0*|0.25|\n"
|
"|0|2|0.5|0.5|\n"
|
||||||
"|0|1|*1*|0.75|\n"
|
"|1|0|0.75|0.25|\n"
|
||||||
"|0|2|*0*|0.5|\n"
|
"|1|1|0|1|\n"
|
||||||
"|0|2|*1*|0.5|\n"
|
"|1|2|1|0|\n";
|
||||||
"|1|0|*0*|0.75|\n"
|
|
||||||
"|1|0|*1*|0.25|\n"
|
|
||||||
"|1|1|*0*|0|\n"
|
|
||||||
"|1|1|*1*|1|\n"
|
|
||||||
"|1|2|*0*|1|\n"
|
|
||||||
"|1|2|*1*|0|\n";
|
|
||||||
vector<string> names{"C", "B", "A"};
|
vector<string> names{"C", "B", "A"};
|
||||||
auto formatter = [names](Key key) { return names[key]; };
|
auto formatter = [names](Key key) { return names[key]; };
|
||||||
string actual = conditional._repr_markdown_(formatter);
|
string actual = conditional._repr_markdown_(formatter);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue