diff --git a/gtsam/discrete/DecisionTreeFactor.cpp b/gtsam/discrete/DecisionTreeFactor.cpp
index 2607a80ef..e9c393c7d 100644
--- a/gtsam/discrete/DecisionTreeFactor.cpp
+++ b/gtsam/discrete/DecisionTreeFactor.cpp
@@ -187,12 +187,13 @@ namespace gtsam {
return ADT::dot(keyFormatter, valueFormatter, showZero);
}
+ // Print out header.
/* ************************************************************************* */
string DecisionTreeFactor::markdown(const KeyFormatter& keyFormatter,
const Names& names) const {
stringstream ss;
- // Print out header and construct argument for `cartesianProduct`.
+ // Print out header.
ss << "|";
for (auto& key : keys()) {
ss << keyFormatter(key) << "|";
@@ -218,11 +219,63 @@ namespace gtsam {
return ss.str();
}
+ /* ************************************************************************ */
+ string DecisionTreeFactor::html(const KeyFormatter& keyFormatter,
+ const Names& names) const {
+ const string style =
+ "\n";
+
+ stringstream ss;
+
+ // Print out preamble.
+ ss << "
\n"
+ << style
+ << "
\n"
+ " \n";
+
+ // Print out header row.
+ ss << " ";
+ for (auto& key : keys()) {
+ ss << "" << keyFormatter(key) << " | ";
+ }
+ ss << "value |
\n";
+
+ // Finish header and start body.
+ ss << " \n \n";
+
+ // Print out all rows.
+ auto rows = enumerate();
+ for (const auto& kv : rows) {
+ ss << " ";
+ auto assignment = kv.first;
+ for (auto& key : keys()) {
+ size_t index = assignment.at(key);
+ ss << "" << Translate(names, key, index) << " | ";
+ }
+ ss << "" << kv.second << " | "; // value
+ ss << "
\n";
+ }
+ ss << " \n
\n
";
+ return ss.str();
+ }
+
+ /* ************************************************************************* */
DecisionTreeFactor::DecisionTreeFactor(const DiscreteKeys &keys, const vector &table) :
DiscreteFactor(keys.indices()), AlgebraicDecisionTree(keys, table),
cardinalities_(keys.cardinalities()) {
}
+ /* ************************************************************************* */
DecisionTreeFactor::DecisionTreeFactor(const DiscreteKeys &keys, const string &table) :
DiscreteFactor(keys.indices()), AlgebraicDecisionTree(keys, table),
cardinalities_(keys.cardinalities()) {
diff --git a/gtsam/discrete/DecisionTreeFactor.h b/gtsam/discrete/DecisionTreeFactor.h
index f7c50d5b5..b5f6c0c4a 100644
--- a/gtsam/discrete/DecisionTreeFactor.h
+++ b/gtsam/discrete/DecisionTreeFactor.h
@@ -211,6 +211,16 @@ namespace gtsam {
std::string markdown(const KeyFormatter& keyFormatter = DefaultKeyFormatter,
const Names& names = {}) const override;
+ /**
+ * @brief Render as html table
+ *
+ * @param keyFormatter GTSAM-style Key formatter.
+ * @param names optional, category names corresponding to choices.
+ * @return std::string a html string.
+ */
+ std::string html(const KeyFormatter& keyFormatter = DefaultKeyFormatter,
+ const Names& names = {}) const override;
+
/// @}
};
diff --git a/gtsam/discrete/DiscreteFactor.h b/gtsam/discrete/DiscreteFactor.h
index e30c0a6fe..43486c5ae 100644
--- a/gtsam/discrete/DiscreteFactor.h
+++ b/gtsam/discrete/DiscreteFactor.h
@@ -106,6 +106,17 @@ public:
const KeyFormatter& keyFormatter = DefaultKeyFormatter,
const Names& names = {}) const = 0;
+ /**
+ * @brief Render as html table
+ *
+ * @param keyFormatter GTSAM-style Key formatter.
+ * @param names optional, category names corresponding to choices.
+ * @return std::string a html string.
+ */
+ virtual std::string html(
+ const KeyFormatter& keyFormatter = DefaultKeyFormatter,
+ const Names& names = {}) const = 0;
+
/// @}
};
// DiscreteFactor
diff --git a/gtsam/discrete/discrete.i b/gtsam/discrete/discrete.i
index d17401e44..3e8013ce8 100644
--- a/gtsam/discrete/discrete.i
+++ b/gtsam/discrete/discrete.i
@@ -54,6 +54,10 @@ virtual class DecisionTreeFactor : gtsam::DiscreteFactor {
gtsam::DefaultKeyFormatter) const;
string markdown(const gtsam::KeyFormatter& keyFormatter,
std::map> names) const;
+ string html(const gtsam::KeyFormatter& keyFormatter =
+ gtsam::DefaultKeyFormatter) const;
+ string html(const gtsam::KeyFormatter& keyFormatter,
+ std::map> names) const;
};
#include
@@ -93,6 +97,10 @@ virtual class DiscreteConditional : gtsam::DecisionTreeFactor {
gtsam::DefaultKeyFormatter) const;
string markdown(const gtsam::KeyFormatter& keyFormatter,
std::map> names) const;
+ string html(const gtsam::KeyFormatter& keyFormatter =
+ gtsam::DefaultKeyFormatter) const;
+ string html(const gtsam::KeyFormatter& keyFormatter,
+ std::map> names) const;
};
#include
diff --git a/gtsam/discrete/tests/testDecisionTreeFactor.cpp b/gtsam/discrete/tests/testDecisionTreeFactor.cpp
index 716a77127..c9f692497 100644
--- a/gtsam/discrete/tests/testDecisionTreeFactor.cpp
+++ b/gtsam/discrete/tests/testDecisionTreeFactor.cpp
@@ -154,6 +154,51 @@ TEST(DecisionTreeFactor, markdownWithValueFormatter) {
EXPECT(actual == expected);
}
+/* ************************************************************************* */
+// Check html representation with a value formatter.
+TEST(DecisionTreeFactor, htmlWithValueFormatter) {
+ DiscreteKey A(12, 3), B(5, 2);
+ DecisionTreeFactor f(A & B, "1 2 3 4 5 6");
+ string expected =
+ "\n"
+ "\n"
+ "
\n"
+ " \n"
+ " A | B | value |
\n"
+ " \n"
+ " \n"
+ " Zero | - | 1 |
\n"
+ " Zero | + | 2 |
\n"
+ " One | - | 3 |
\n"
+ " One | + | 4 |
\n"
+ " Two | - | 5 |
\n"
+ " Two | + | 6 |
\n"
+ " \n"
+ "
\n"
+ "
";
+ auto keyFormatter = [](Key key) { return key == 12 ? "A" : "B"; };
+ DecisionTreeFactor::Names names{{12, {"Zero", "One", "Two"}},
+ {5, {"-", "+"}}};
+ string actual = f.html(keyFormatter, names);
+ cout << expected << endl;
+ cout << actual << endl;
+ ofstream ef("expected=html.txt"), af("actual-html.txt");
+ ef << expected << endl;
+ af << actual << endl;
+ EXPECT(actual == expected);
+}
+
/* ************************************************************************* */
int main() {
TestResult tr;
diff --git a/gtsam_unstable/discrete/Constraint.h b/gtsam_unstable/discrete/Constraint.h
index 85748f054..4ee7b85eb 100644
--- a/gtsam_unstable/discrete/Constraint.h
+++ b/gtsam_unstable/discrete/Constraint.h
@@ -91,6 +91,12 @@ class GTSAM_EXPORT Constraint : public DiscreteFactor {
return (boost::format("`Constraint` on %1% variables\n") % (size())).str();
}
+ /// Render as html table.
+ std::string html(const KeyFormatter& keyFormatter = DefaultKeyFormatter,
+ const Names& names = {}) const override {
+ return (boost::format("Constraint on %1% variables
") % (size())).str();
+ }
+
/// @}
};
// DiscreteFactor