Working html for conditionals
parent
e8127792f2
commit
a7b7a8b0fa
|
@ -348,18 +348,14 @@ std::string DiscreteConditional::markdown(const KeyFormatter& keyFormatter,
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print out header and construct argument for `cartesianProduct`.
|
// Print out header.
|
||||||
ss << "|";
|
ss << "|";
|
||||||
for (Key parent : parents()) {
|
for (Key parent : parents()) {
|
||||||
ss << "*" << keyFormatter(parent) << "*|";
|
ss << "*" << keyFormatter(parent) << "*|";
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t n = 1;
|
auto frontalAssignments = this->frontalAssignments();
|
||||||
for (Key key : frontals()) {
|
for (const auto& a : frontalAssignments) {
|
||||||
size_t k = cardinalities_.at(key);
|
|
||||||
n *= k;
|
|
||||||
}
|
|
||||||
for (const auto& a : frontalAssignments()) {
|
|
||||||
for (auto&& it = beginFrontals(); it != endFrontals(); ++it) {
|
for (auto&& it = beginFrontals(); it != endFrontals(); ++it) {
|
||||||
size_t index = a.at(*it);
|
size_t index = a.at(*it);
|
||||||
ss << Translate(names, *it, index);
|
ss << Translate(names, *it, index);
|
||||||
|
@ -370,6 +366,7 @@ std::string DiscreteConditional::markdown(const KeyFormatter& keyFormatter,
|
||||||
|
|
||||||
// Print out separator with alignment hints.
|
// Print out separator with alignment hints.
|
||||||
ss << "|";
|
ss << "|";
|
||||||
|
size_t n = frontalAssignments.size();
|
||||||
for (size_t j = 0; j < nrParents() + n; j++) ss << ":-:|";
|
for (size_t j = 0; j < nrParents() + n; j++) ss << ":-:|";
|
||||||
ss << "\n";
|
ss << "\n";
|
||||||
|
|
||||||
|
@ -408,28 +405,37 @@ string DiscreteConditional::html(const KeyFormatter& keyFormatter,
|
||||||
|
|
||||||
// Print out header row.
|
// Print out header row.
|
||||||
ss << " <tr>";
|
ss << " <tr>";
|
||||||
for (auto& key : keys()) {
|
for (Key parent : parents()) {
|
||||||
ss << "<th>" << keyFormatter(key) << "</th>";
|
ss << "<th><i>" << keyFormatter(parent) << "</i></th>";
|
||||||
}
|
}
|
||||||
ss << "<th>value</th></tr>\n";
|
auto frontalAssignments = this->frontalAssignments();
|
||||||
|
for (const auto& a : frontalAssignments) {
|
||||||
|
for (auto&& it = beginFrontals(); it != endFrontals(); ++it) {
|
||||||
|
size_t index = a.at(*it);
|
||||||
|
ss << "<th>" << Translate(names, *it, index) << "</th>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ss << "</tr>\n";
|
||||||
|
|
||||||
// Finish header and start body.
|
// Finish header and start body.
|
||||||
ss << " </thead>\n <tbody>\n";
|
ss << " </thead>\n <tbody>\n";
|
||||||
|
|
||||||
// Print out all rows.
|
size_t count = 0, n = frontalAssignments.size();
|
||||||
auto rows = enumerate();
|
for (const auto& a : allAssignments()) {
|
||||||
for (const auto& kv : rows) {
|
if (count == 0) {
|
||||||
ss << " <tr>";
|
ss << " <tr>";
|
||||||
auto assignment = kv.first;
|
for (auto&& it = beginParents(); it != endParents(); ++it) {
|
||||||
for (auto& key : keys()) {
|
size_t index = a.at(*it);
|
||||||
size_t index = assignment.at(key);
|
ss << "<th>" << Translate(names, *it, index) << "</th>";
|
||||||
ss << "<th>" << Translate(names, key, index) << "</th>";
|
}
|
||||||
}
|
}
|
||||||
ss << "<td>" << kv.second << "</td>"; // value
|
ss << "<td>" << operator()(a) << "</td>"; // value
|
||||||
ss << "</tr>\n";
|
count = (count + 1) % n;
|
||||||
|
if (count == 0) ss << "</tr>\n";
|
||||||
}
|
}
|
||||||
ss << " </tbody>\n</table>\n</div>";
|
|
||||||
|
|
||||||
|
// Finish up
|
||||||
|
ss << " </tbody>\n</table>\n</div>";
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -182,13 +182,13 @@ TEST(DiscreteBayesNet, markdown) {
|
||||||
string expected =
|
string expected =
|
||||||
"`DiscreteBayesNet` of size 2\n"
|
"`DiscreteBayesNet` of size 2\n"
|
||||||
"\n"
|
"\n"
|
||||||
" *P(Asia)*:\n\n"
|
" *P(Asia):*\n\n"
|
||||||
"|Asia|value|\n"
|
"|Asia|value|\n"
|
||||||
"|:-:|:-:|\n"
|
"|:-:|:-:|\n"
|
||||||
"|0|0.99|\n"
|
"|0|0.99|\n"
|
||||||
"|1|0.01|\n"
|
"|1|0.01|\n"
|
||||||
"\n"
|
"\n"
|
||||||
" *P(Smoking|Asia)*:\n\n"
|
" *P(Smoking|Asia):*\n\n"
|
||||||
"|*Asia*|0|1|\n"
|
"|*Asia*|0|1|\n"
|
||||||
"|:-:|:-:|:-:|\n"
|
"|:-:|:-:|:-:|\n"
|
||||||
"|0|0.8|0.2|\n"
|
"|0|0.8|0.2|\n"
|
||||||
|
|
|
@ -125,7 +125,7 @@ TEST(DiscreteConditional, markdown_prior) {
|
||||||
DiscreteKey A(Symbol('x', 1), 3);
|
DiscreteKey A(Symbol('x', 1), 3);
|
||||||
DiscreteConditional conditional(A % "1/2/2");
|
DiscreteConditional conditional(A % "1/2/2");
|
||||||
string expected =
|
string expected =
|
||||||
" *P(x1)*:\n\n"
|
" *P(x1):*\n\n"
|
||||||
"|x1|value|\n"
|
"|x1|value|\n"
|
||||||
"|:-:|:-:|\n"
|
"|:-:|:-:|\n"
|
||||||
"|0|0.2|\n"
|
"|0|0.2|\n"
|
||||||
|
@ -142,7 +142,7 @@ TEST(DiscreteConditional, markdown_prior_names) {
|
||||||
DiscreteKey A(x1, 3);
|
DiscreteKey A(x1, 3);
|
||||||
DiscreteConditional conditional(A % "1/2/2");
|
DiscreteConditional conditional(A % "1/2/2");
|
||||||
string expected =
|
string expected =
|
||||||
" *P(x1)*:\n\n"
|
" *P(x1):*\n\n"
|
||||||
"|x1|value|\n"
|
"|x1|value|\n"
|
||||||
"|:-:|:-:|\n"
|
"|:-:|:-:|\n"
|
||||||
"|A0|0.2|\n"
|
"|A0|0.2|\n"
|
||||||
|
@ -160,7 +160,7 @@ TEST(DiscreteConditional, markdown_multivalued) {
|
||||||
DiscreteConditional conditional(
|
DiscreteConditional conditional(
|
||||||
A | B = "2/88/10 2/20/78 33/33/34 33/33/34 95/2/3");
|
A | B = "2/88/10 2/20/78 33/33/34 33/33/34 95/2/3");
|
||||||
string expected =
|
string expected =
|
||||||
" *P(a1|b1)*:\n\n"
|
" *P(a1|b1):*\n\n"
|
||||||
"|*b1*|0|1|2|\n"
|
"|*b1*|0|1|2|\n"
|
||||||
"|:-:|:-:|:-:|:-:|\n"
|
"|:-:|:-:|:-:|:-:|\n"
|
||||||
"|0|0.02|0.88|0.1|\n"
|
"|0|0.02|0.88|0.1|\n"
|
||||||
|
@ -178,7 +178,7 @@ 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");
|
||||||
string expected =
|
string expected =
|
||||||
" *P(A|B,C)*:\n\n"
|
" *P(A|B,C):*\n\n"
|
||||||
"|*B*|*C*|T|F|\n"
|
"|*B*|*C*|T|F|\n"
|
||||||
"|:-:|:-:|:-:|:-:|\n"
|
"|:-:|:-:|:-:|:-:|\n"
|
||||||
"|-|Zero|0|1|\n"
|
"|-|Zero|0|1|\n"
|
||||||
|
@ -195,6 +195,36 @@ TEST(DiscreteConditional, markdown) {
|
||||||
EXPECT(actual == expected);
|
EXPECT(actual == expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ************************************************************************* */
|
||||||
|
// Check html representation looks as expected, two parents + names.
|
||||||
|
TEST(DiscreteConditional, html) {
|
||||||
|
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");
|
||||||
|
string expected =
|
||||||
|
"<div>\n"
|
||||||
|
"<p> <i>P(A|B,C):</i></p>\n"
|
||||||
|
"<table class='DiscreteConditional'>\n"
|
||||||
|
" <thead>\n"
|
||||||
|
" <tr><th><i>B</i></th><th><i>C</i></th><th>T</th><th>F</th></tr>\n"
|
||||||
|
" </thead>\n"
|
||||||
|
" <tbody>\n"
|
||||||
|
" <tr><th>-</th><th>Zero</th><td>0</td><td>1</td></tr>\n"
|
||||||
|
" <tr><th>-</th><th>One</th><td>0.25</td><td>0.75</td></tr>\n"
|
||||||
|
" <tr><th>-</th><th>Two</th><td>0.5</td><td>0.5</td></tr>\n"
|
||||||
|
" <tr><th>+</th><th>Zero</th><td>0.75</td><td>0.25</td></tr>\n"
|
||||||
|
" <tr><th>+</th><th>One</th><td>0</td><td>1</td></tr>\n"
|
||||||
|
" <tr><th>+</th><th>Two</th><td>1</td><td>0</td></tr>\n"
|
||||||
|
" </tbody>\n"
|
||||||
|
"</table>\n"
|
||||||
|
"</div>";
|
||||||
|
vector<string> keyNames{"C", "B", "A"};
|
||||||
|
auto formatter = [keyNames](Key key) { return keyNames[key]; };
|
||||||
|
DecisionTreeFactor::Names names{
|
||||||
|
{0, {"Zero", "One", "Two"}}, {1, {"-", "+"}}, {2, {"T", "F"}}};
|
||||||
|
string actual = conditional.html(formatter, names);
|
||||||
|
EXPECT(actual == expected);
|
||||||
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
int main() {
|
int main() {
|
||||||
TestResult tr;
|
TestResult tr;
|
||||||
|
|
|
@ -49,7 +49,7 @@ class TestDiscreteConditional(GtsamTestCase):
|
||||||
conditional = DiscreteConditional(A, parents,
|
conditional = DiscreteConditional(A, parents,
|
||||||
"0/1 1/3 1/1 3/1 0/1 1/0")
|
"0/1 1/3 1/1 3/1 0/1 1/0")
|
||||||
expected = \
|
expected = \
|
||||||
" *P(A|B,C)*:\n\n" \
|
" *P(A|B,C):*\n\n" \
|
||||||
"|*B*|*C*|0|1|\n" \
|
"|*B*|*C*|0|1|\n" \
|
||||||
"|:-:|:-:|:-:|:-:|\n" \
|
"|:-:|:-:|:-:|:-:|\n" \
|
||||||
"|0|0|0|1|\n" \
|
"|0|0|0|1|\n" \
|
||||||
|
|
|
@ -51,7 +51,7 @@ class TestDiscretePrior(GtsamTestCase):
|
||||||
"""Test the _repr_markdown_ method."""
|
"""Test the _repr_markdown_ method."""
|
||||||
|
|
||||||
prior = DiscretePrior(X, "2/3")
|
prior = DiscretePrior(X, "2/3")
|
||||||
expected = " *P(0)*:\n\n" \
|
expected = " *P(0):*\n\n" \
|
||||||
"|0|value|\n" \
|
"|0|value|\n" \
|
||||||
"|:-:|:-:|\n" \
|
"|:-:|:-:|\n" \
|
||||||
"|0|0.4|\n" \
|
"|0|0.4|\n" \
|
||||||
|
|
Loading…
Reference in New Issue