diff --git a/gtsam/linear/VectorValues.cpp b/gtsam/linear/VectorValues.cpp index 6a2514b35..bf1579eac 100644 --- a/gtsam/linear/VectorValues.cpp +++ b/gtsam/linear/VectorValues.cpp @@ -33,7 +33,7 @@ namespace gtsam { using boost::adaptors::map_values; using boost::accumulate; - /* ************************************************************************* */ + /* ************************************************************************ */ VectorValues::VectorValues(const VectorValues& first, const VectorValues& second) { // Merge using predicate for comparing first of pair @@ -44,7 +44,7 @@ namespace gtsam { throw invalid_argument("Requested to merge two VectorValues that have one or more variables in common."); } - /* ************************************************************************* */ + /* ************************************************************************ */ VectorValues::VectorValues(const Vector& x, const Dims& dims) { using Pair = pair; size_t j = 0; @@ -61,7 +61,7 @@ namespace gtsam { } } - /* ************************************************************************* */ + /* ************************************************************************ */ VectorValues::VectorValues(const Vector& x, const Scatter& scatter) { size_t j = 0; for (const SlotEntry& v : scatter) { @@ -74,7 +74,7 @@ namespace gtsam { } } - /* ************************************************************************* */ + /* ************************************************************************ */ VectorValues VectorValues::Zero(const VectorValues& other) { VectorValues result; @@ -87,7 +87,7 @@ namespace gtsam { return result; } - /* ************************************************************************* */ + /* ************************************************************************ */ VectorValues::iterator VectorValues::insert(const std::pair& key_value) { std::pair result = values_.insert(key_value); if(!result.second) @@ -97,7 +97,7 @@ namespace gtsam { return result.first; } - /* ************************************************************************* */ + /* ************************************************************************ */ void VectorValues::update(const VectorValues& values) { iterator hint = begin(); @@ -115,7 +115,7 @@ namespace gtsam { } } - /* ************************************************************************* */ + /* ************************************************************************ */ void VectorValues::insert(const VectorValues& values) { size_t originalSize = size(); @@ -124,14 +124,14 @@ namespace gtsam { throw invalid_argument("Requested to insert a VectorValues into another VectorValues that already contains one or more of its keys."); } - /* ************************************************************************* */ + /* ************************************************************************ */ void VectorValues::setZero() { for(Vector& v: values_ | map_values) v.setZero(); } - /* ************************************************************************* */ + /* ************************************************************************ */ GTSAM_EXPORT ostream& operator<<(ostream& os, const VectorValues& v) { // Change print depending on whether we are using TBB #ifdef GTSAM_USE_TBB @@ -150,7 +150,7 @@ namespace gtsam { return os; } - /* ************************************************************************* */ + /* ************************************************************************ */ void VectorValues::print(const string& str, const KeyFormatter& formatter) const { cout << str << ": " << size() << " elements\n"; @@ -158,7 +158,7 @@ namespace gtsam { cout.flush(); } - /* ************************************************************************* */ + /* ************************************************************************ */ bool VectorValues::equals(const VectorValues& x, double tol) const { if(this->size() != x.size()) return false; @@ -170,7 +170,7 @@ namespace gtsam { return true; } - /* ************************************************************************* */ + /* ************************************************************************ */ Vector VectorValues::vector() const { // Count dimensions DenseIndex totalDim = 0; @@ -187,7 +187,7 @@ namespace gtsam { return result; } - /* ************************************************************************* */ + /* ************************************************************************ */ Vector VectorValues::vector(const Dims& keys) const { // Count dimensions @@ -203,12 +203,12 @@ namespace gtsam { return result; } - /* ************************************************************************* */ + /* ************************************************************************ */ void VectorValues::swap(VectorValues& other) { this->values_.swap(other.values_); } - /* ************************************************************************* */ + /* ************************************************************************ */ namespace internal { bool structureCompareOp(const boost::tuple()); } - /* ************************************************************************* */ + /* ************************************************************************ */ double VectorValues::dot(const VectorValues& v) const { if(this->size() != v.size()) @@ -244,12 +244,12 @@ namespace gtsam { return result; } - /* ************************************************************************* */ + /* ************************************************************************ */ double VectorValues::norm() const { return std::sqrt(this->squaredNorm()); } - /* ************************************************************************* */ + /* ************************************************************************ */ double VectorValues::squaredNorm() const { double sumSquares = 0.0; using boost::adaptors::map_values; @@ -258,7 +258,7 @@ namespace gtsam { return sumSquares; } - /* ************************************************************************* */ + /* ************************************************************************ */ VectorValues VectorValues::operator+(const VectorValues& c) const { if(this->size() != c.size()) @@ -278,13 +278,13 @@ namespace gtsam { return result; } - /* ************************************************************************* */ + /* ************************************************************************ */ VectorValues VectorValues::add(const VectorValues& c) const { return *this + c; } - /* ************************************************************************* */ + /* ************************************************************************ */ VectorValues& VectorValues::operator+=(const VectorValues& c) { if(this->size() != c.size()) @@ -301,13 +301,13 @@ namespace gtsam { return *this; } - /* ************************************************************************* */ + /* ************************************************************************ */ VectorValues& VectorValues::addInPlace(const VectorValues& c) { return *this += c; } - /* ************************************************************************* */ + /* ************************************************************************ */ VectorValues& VectorValues::addInPlace_(const VectorValues& c) { for(const_iterator j2 = c.begin(); j2 != c.end(); ++j2) { @@ -320,7 +320,7 @@ namespace gtsam { return *this; } - /* ************************************************************************* */ + /* ************************************************************************ */ VectorValues VectorValues::operator-(const VectorValues& c) const { if(this->size() != c.size()) @@ -340,13 +340,13 @@ namespace gtsam { return result; } - /* ************************************************************************* */ + /* ************************************************************************ */ VectorValues VectorValues::subtract(const VectorValues& c) const { return *this - c; } - /* ************************************************************************* */ + /* ************************************************************************ */ VectorValues operator*(const double a, const VectorValues &v) { VectorValues result; @@ -359,13 +359,13 @@ namespace gtsam { return result; } - /* ************************************************************************* */ + /* ************************************************************************ */ VectorValues VectorValues::scale(const double a) const { return a * *this; } - /* ************************************************************************* */ + /* ************************************************************************ */ VectorValues& VectorValues::operator*=(double alpha) { for(Vector& v: *this | map_values) @@ -373,12 +373,36 @@ namespace gtsam { return *this; } - /* ************************************************************************* */ + /* ************************************************************************ */ VectorValues& VectorValues::scaleInPlace(double alpha) { return *this *= alpha; } - /* ************************************************************************* */ + /* ************************************************************************ */ + string VectorValues::html(const KeyFormatter& keyFormatter) const { + stringstream ss; + + // Print out preamble. + ss << "
\n\n \n"; + + // Print out header row. + ss << " \n"; + + // Finish header and start body. + ss << " \n \n"; + + // Print out all rows. + for (const auto& kv : *this) { + ss << " "; + ss << ""; + ss << "\n"; + } + ss << " \n
Variablevalue
" << keyFormatter(kv.first) << "" + << kv.second.transpose() << "
\n
"; + return ss.str(); + } + + /* ************************************************************************ */ } // \namespace gtsam diff --git a/gtsam/linear/VectorValues.h b/gtsam/linear/VectorValues.h index 9e60ff2aa..1ff8c5c16 100644 --- a/gtsam/linear/VectorValues.h +++ b/gtsam/linear/VectorValues.h @@ -34,7 +34,7 @@ namespace gtsam { /** - * This class represents a collection of vector-valued variables associated + * VectorValues represents a collection of vector-valued variables associated * each with a unique integer index. It is typically used to store the variables * of a GaussianFactorGraph. Optimizing a GaussianFactorGraph or GaussianBayesNet * returns this class. @@ -69,7 +69,7 @@ namespace gtsam { * which is a view on the underlying data structure. * * This class is additionally used in gradient descent and dog leg to store the gradient. - * \nosubgrouping + * @addtogroup linear */ class GTSAM_EXPORT VectorValues { protected: @@ -344,11 +344,16 @@ namespace gtsam { /// @} - /// @} - /// @name Matlab syntactic sugar for linear algebra operations + /// @name Wrapper support /// @{ - //inline VectorValues scale(const double a, const VectorValues& c) const { return a * (*this); } + /** + * @brief Output as a html table. + * + * @param keyFormatter function that formats keys. + */ + std::string html( + const KeyFormatter& keyFormatter = DefaultKeyFormatter) const; /// @} diff --git a/gtsam/linear/linear.i b/gtsam/linear/linear.i index 113ebb8ec..3f3f79b14 100644 --- a/gtsam/linear/linear.i +++ b/gtsam/linear/linear.i @@ -255,6 +255,7 @@ class VectorValues { // enabling serialization functionality void serialize() const; + void html() const; }; #include diff --git a/gtsam/linear/tests/testVectorValues.cpp b/gtsam/linear/tests/testVectorValues.cpp index f97f96aaf..521cc2289 100644 --- a/gtsam/linear/tests/testVectorValues.cpp +++ b/gtsam/linear/tests/testVectorValues.cpp @@ -17,7 +17,7 @@ #include #include -#include +#include #include @@ -248,6 +248,33 @@ TEST(VectorValues, print) EXPECT(expected == actual.str()); } +/* ************************************************************************* */ +// Check html representation. +TEST(VectorValues, html) { + VectorValues vv; + using symbol_shorthand::X; + vv.insert(X(1), Vector2(2, 3.1)); + vv.insert(X(2), Vector2(4, 5.2)); + vv.insert(X(5), Vector2(6, 7.3)); + vv.insert(X(7), Vector2(8, 9.4)); + string expected = + "
\n" + "\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "
Variablevalue
x1 2 3.1
x2 4 5.2
x5 6 7.3
x7 8 9.4
\n" + "
"; + string actual = vv.html(); + EXPECT(actual == expected); +} + /* ************************************************************************* */ int main() { TestResult tr; return TestRegistry::runAllTests(tr); } /* ************************************************************************* */