diff --git a/examples/LocalizationExample.cpp b/examples/LocalizationExample.cpp index dfe3d1e99..035139a5d 100644 --- a/examples/LocalizationExample.cpp +++ b/examples/LocalizationExample.cpp @@ -27,7 +27,7 @@ #include // We will use simple integer Keys to refer to the robot poses. -#include +#include // As in OdometryExample.cpp, we use a BetweenFactor to model odometry measurements. #include diff --git a/examples/Pose2SLAMExample.cpp b/examples/Pose2SLAMExample.cpp index cbe97ae12..1220481f5 100644 --- a/examples/Pose2SLAMExample.cpp +++ b/examples/Pose2SLAMExample.cpp @@ -29,7 +29,7 @@ #include // We will use simple integer Keys to refer to the robot poses. -#include +#include // In GTSAM, measurement functions are represented as 'factors'. Several common factors // have been provided with the library for solving robotics/SLAM/Bundle Adjustment problems. diff --git a/examples/Pose2SLAMwSPCG.cpp b/examples/Pose2SLAMwSPCG.cpp index 36f2552a1..09af6351d 100644 --- a/examples/Pose2SLAMwSPCG.cpp +++ b/examples/Pose2SLAMwSPCG.cpp @@ -33,7 +33,7 @@ // Each variable in the system (poses) must be identified with a unique key. // We can either use simple integer keys (1, 2, 3, ...) or symbols (X1, X2, L1). // Here we will use simple integer keys -#include +#include // In GTSAM, measurement functions are represented as 'factors'. Several common factors // have been provided with the library for solving robotics/SLAM/Bundle Adjustment problems. diff --git a/gtsam/inference/ConditionalUnordered.h b/gtsam/inference/ConditionalUnordered.h index 1a7e28012..0e1ea274b 100644 --- a/gtsam/inference/ConditionalUnordered.h +++ b/gtsam/inference/ConditionalUnordered.h @@ -19,6 +19,7 @@ #pragma once #include +#include #include #include @@ -35,7 +36,7 @@ namespace gtsam { * IndexConditional and GaussianConditional for examples. * \nosubgrouping */ - template + template class ConditionalUnordered { protected: @@ -51,7 +52,7 @@ namespace gtsam { public: - typedef ConditionalUnordered This; + typedef ConditionalUnordered This; /** View of the frontal keys (call frontals()) */ typedef boost::iterator_range Frontals; @@ -86,12 +87,12 @@ namespace gtsam { size_t nrFrontals() const { return nrFrontals_; } /** return the number of parents */ - size_t nrParents() const { return asDerived.size() - nrFrontals_; } + size_t nrParents() const { return asFactor().size() - nrFrontals_; } /** Convenience function to get the first frontal key */ Key firstFrontalKey() const { if(nrFrontals_ > 0) - return asDerived().front(); + return asFactor().front(); else throw std::invalid_argument("Requested Conditional::firstFrontalKey from a conditional with zero frontal keys"); } @@ -103,16 +104,16 @@ namespace gtsam { Parents parents() const { return boost::make_iterator_range(beginParents(), endParents()); } /** Iterator pointing to first frontal key. */ - const_iterator beginFrontals() const { return asDerived().begin(); } + const_iterator beginFrontals() const { return asFactor().begin(); } /** Iterator pointing past the last frontal key. */ - const_iterator endFrontals() const { return asDerived().begin() + nrFrontals_; } + const_iterator endFrontals() const { return asFactor().begin() + nrFrontals_; } /** Iterator pointing to the first parent key. */ const_iterator beginParents() const { return endFrontals(); } /** Iterator pointing past the last parent key. */ - const_iterator endParents() const { return asDerived().end(); } + const_iterator endParents() const { return asFactor().end(); } /// @} /// @name Advanced Interface @@ -120,24 +121,24 @@ namespace gtsam { /** Mutable iterators and accessors */ iterator beginFrontals() { - return FactorType::begin(); + return asFactor().begin(); } ///(*this); } + // Cast to factor type (non-const) (casts down to derived conditional type, then up to factor type) + FACTOR& asFactor() { return static_cast(static_cast(*this)); } - // Cast to derived type (const) - const FACTOR& asDerived() const { return static_cast(*this); } + // Cast to derived type (const) (casts down to derived conditional type, then up to factor type) + const FACTOR& asFactor() const { return static_cast(static_cast(*this)); } /** Serialization function */ friend class boost::serialization::access; @@ -152,8 +153,8 @@ namespace gtsam { }; /* ************************************************************************* */ - template - void ConditionalUnordered::print(const std::string& s, const KeyFormatter& formatter) const { + template + void ConditionalUnordered::print(const std::string& s, const KeyFormatter& formatter) const { std::cout << s << " P("; BOOST_FOREACH(Key key, frontals()) std::cout << " " << formatter(key); diff --git a/gtsam/inference/EliminationTreeUnordered-inl.h b/gtsam/inference/EliminationTreeUnordered-inl.h index 6051ec220..aa2dc3140 100644 --- a/gtsam/inference/EliminationTreeUnordered-inl.h +++ b/gtsam/inference/EliminationTreeUnordered-inl.h @@ -17,10 +17,12 @@ */ #pragma once +#include +#include + #include #include - -#include +#include namespace gtsam { @@ -39,7 +41,7 @@ namespace gtsam { static const size_t none = std::numeric_limits::max(); // Allocate result parent vector and vector of last factor columns - std::vector nodes(n); + std::vector nodes(n); std::vector parents(n, none); std::vector prevCol(m, none); std::vector factorUsed(m, false); @@ -50,7 +52,8 @@ namespace gtsam { { // Retrieve the factors involving this variable and create the current node const VariableIndex::Factors& factors = structure[order[j]]; - nodes[j] = boost::make_shared >(order[j]); + nodes[j] = boost::make_shared(); + nodes[j]->key = order[j]; // for row i \in Struct[A*j] do BOOST_FOREACH(const size_t i, factors) { @@ -71,12 +74,12 @@ namespace gtsam { if (r != j) { // Now that we found the root, hook up parent and child pointers in the nodes. parents[r] = j; - nodes[j]->subTrees_.push_back(nodes[r]); + nodes[j]->subTrees.push_back(nodes[r]); } } else { // Add the current factor to the current node since we are at the first variable in this // factor. - nodes[j]->factors_.push_back(graph[i]); + nodes[j]->factors.push_back(graph[i]); factorUsed[i] = true; } prevCol[i] = j; @@ -115,17 +118,51 @@ namespace gtsam { remainingFactors_.swap(temp.remainingFactors_); } + /* ************************************************************************* */ + template + EliminationTreeUnordered& + EliminationTreeUnordered::operator=(const EliminationTreeUnordered& other) + { + // Start by duplicating the roots. + roots_.clear(); + std::stack > stack; + BOOST_FOREACH(const sharedNode& root, other.roots_) { + roots_.push_back(boost::make_shared(*root)); + stack.push(roots_.back()); + } + + // Traverse the tree, duplicating each node's children and fixing the pointers as we go. We do + // not clone any factors, only copy their pointers (this is a standard in GTSAM). + while(!stack.empty()) { + sharedNode node = stack.top(); + stack.pop(); + BOOST_FOREACH(sharedNode& child, node->subTrees) { + // Important: since we are working with a *reference* to a shared pointer in this + // BOOST_FOREACH loop, the next statement modifies the pointer in the current node's child + // list - it replaces it with a pointer to a copy of the child. + child = boost::make_shared(*child); + stack.push(child); + } + } + + // Assign the remaining factors - these are pointers to factors in the original factor graph and + // we do not clone them. + remainingFactors_ = other.remainingFactors_; + + return *this; + } + /* ************************************************************************* */ namespace { - template + template struct EliminationNode { bool expanded; - Key key; - std::vector > factors; - EliminationNode* parent; - template EliminationNode( - Key _key, size_t nFactorsToReserve, ITERATOR firstFactor, ITERATOR lastFactor, EliminationNode* _parent) : - expanded(false), key(_key), parent(_parent) { + const typename ELIMINATIONTREE::Node* const treeNode; + std::vector factors; + EliminationNode* const parent; + template EliminationNode(const typename ELIMINATIONTREE::Node* _treeNode, size_t nFactorsToReserve, + ITERATOR firstFactor, ITERATOR lastFactor, EliminationNode* _parent) : + expanded(false), treeNode(_treeNode), parent(_parent) { factors.reserve(nFactorsToReserve); factors.insert(factors.end(), firstFactor, lastFactor); } @@ -135,7 +172,7 @@ namespace gtsam { /* ************************************************************************* */ template std::pair, boost::shared_ptr > - EliminationTreeUnordered::eliminate(Eliminate function) + EliminationTreeUnordered::eliminate(Eliminate function) const { // Stack for eliminating nodes. We use this stack instead of recursive function calls to // avoid call stack overflow due to very long trees that arise from chain-like graphs. We use @@ -143,7 +180,7 @@ namespace gtsam { // about the vector growing to be very large once and not being deallocated until this // function exits, because in the worst case we only store one pointer in this stack for each // variable in the system. - typedef EliminationNode EliminationNode; + typedef EliminationNode EliminationNode; std::stack > eliminationStack; // Create empty Bayes net and factor graph to hold result @@ -152,25 +189,25 @@ namespace gtsam { // EliminationTree - these are the factors that were not included in the partial elimination // at all. boost::shared_ptr remainingFactors = - boost::make_shared(remainingFactors_); + boost::make_shared(remainingFactors_.begin(), remainingFactors_.end()); // Add roots to the stack BOOST_FOREACH(const sharedNode& root, roots_) { eliminationStack.push( - EliminationNode(root->key, root->factors.size() + root->subTrees.size(), + EliminationNode(root.get(), root->factors.size() + root->subTrees.size(), root->factors.begin(), root->factors.end(), 0)); } // Until the stack is empty while(!eliminationStack.empty()) { // Process the next node. If it has children, add its children to the stack and mark it // expanded - we'll come back and eliminate it later after the children have been processed. - EliminationNode& node = nodeStack.top(); + EliminationNode& node = eliminationStack.top(); if(node.expanded) { // Remove from stack - nodeStack.pop(); + eliminationStack.pop(); // Do a dense elimination step - std::vector keyAsVector(1); keyAsVector[0] = node.key; + std::vector keyAsVector(1); keyAsVector[0] = node.treeNode->key; std::pair, boost::shared_ptr > eliminationResult = function(node.factors, keyAsVector); @@ -185,10 +222,10 @@ namespace gtsam { } else { // Expand children and mark as expanded node.expanded = true; - BOOST_FOREACH(const sharedNode& child, node.subTrees) { - nodeStack.push( - EliminationNode(child->key, child->factors.size() + child->subTrees.size(), - child->factors.begin(), child->factors.end(), 0)); } + BOOST_FOREACH(const sharedNode& child, node.treeNode->subTrees) { + eliminationStack.push( + EliminationNode(child.get(), child->factors.size() + child->subTrees.size(), + child->factors.begin(), child->factors.end(), &node)); } } } @@ -198,28 +235,98 @@ namespace gtsam { /* ************************************************************************* */ template - void EliminationTreeUnordered::print(const std::string& name, - const IndexFormatter& formatter) const { - std::cout << name << " (" << formatter(key_) << ")" << std::endl; - BOOST_FOREACH(const sharedFactor& factor, factors_) { - factor->print(name + " ", formatter); } - BOOST_FOREACH(const shared_ptr& child, subTrees_) { - child->print(name + " ", formatter); } + void EliminationTreeUnordered::print(const std::string& name, const KeyFormatter& formatter) const + { + // Depth-first-traversal stack + std::stack > stack; + + // Add roots + BOOST_FOREACH(const sharedNode& node, roots_) { stack.push(std::make_pair(node, " ")); } + + // Traverse + while(!stack.empty()) { + std::pair node_string = stack.top(); + stack.pop(); + std::cout << node_string.second << " (" << formatter(node_string.first->key) << ")\n"; + BOOST_FOREACH(const sharedFactor& factor, node_string.first->factors) { + if(factor) + factor->print(node_string.second + " "); + else + std::cout << node_string.second << " null factor\n"; + } + BOOST_FOREACH(const sharedNode& child, node_string.first->subTrees) { + stack.push(std::make_pair(child, node_string.second + " ")); + } + } } /* ************************************************************************* */ template - bool EliminationTreeUnordered::equals(const This& expected, double tol) const { - if(this->key_ == expected.key_ && this->factors_ == expected.factors_ - && this->subTrees_.size() == expected.subTrees_.size()) { - typename SubTrees::const_iterator this_subtree = this->subTrees_.begin(); - typename SubTrees::const_iterator expected_subtree = expected.subTrees_.begin(); - while(this_subtree != this->subTrees_.end()) - if( ! (*(this_subtree++))->equals(**(expected_subtree++), tol)) + bool EliminationTreeUnordered::equals(const This& expected, double tol) const + { + // Depth-first-traversal stacks + std::stack > stack1, stack2; + + // Add roots in sorted order + { + FastMap keys; + BOOST_FOREACH(const sharedNode& root, this->roots_) { keys.insert(make_pair(root->key, root)); } + typedef FastMap::value_type Key_Node; + BOOST_FOREACH(const Key_Node& key_node, keys) { stack1.push(key_node.second); } + } + { + FastMap keys; + BOOST_FOREACH(const sharedNode& root, expected.roots_) { keys.insert(make_pair(root->key, root)); } + typedef FastMap::value_type Key_Node; + BOOST_FOREACH(const Key_Node& key_node, keys) { stack2.push(key_node.second); } + } + + // Traverse, adding children in sorted order + while(!stack1.empty() && !stack2.empty()) { + // Pop nodes + sharedNode node1 = stack1.top(); + stack1.pop(); + sharedNode node2 = stack2.top(); + stack2.pop(); + + // Compare nodes + if(node1->key != node2->key) + return false; + if(node1->factors.size() != node2->factors.size()) { + return false; + } else { + for(Node::Factors::const_iterator it1 = node1->factors.begin(), it2 = node2->factors.begin(); + it1 != node1->factors.end(); ++it1, ++it2) // Only check it1 == end because we already returned false for different counts + { + if(*it1 && *it2) { + if(!(*it1)->equals(**it2, tol)) + return false; + } else if(*it1 && !*it2 || *it2 && !*it1) { return false; - return true; - } else + } + } + } + + // Add children in sorted order + { + FastMap keys; + BOOST_FOREACH(const sharedNode& node, node1->subTrees) { keys.insert(make_pair(node->key, node)); } + typedef FastMap::value_type Key_Node; + BOOST_FOREACH(const Key_Node& key_node, keys) { stack1.push(key_node.second); } + } + { + FastMap keys; + BOOST_FOREACH(const sharedNode& node, node2->subTrees) { keys.insert(make_pair(node->key, node)); } + typedef FastMap::value_type Key_Node; + BOOST_FOREACH(const Key_Node& key_node, keys) { stack2.push(key_node.second); } + } + } + + // If either stack is not empty, the number of nodes differed + if(!stack1.empty() || !stack2.empty()) return false; + + return true; } } diff --git a/gtsam/inference/EliminationTreeUnordered.h b/gtsam/inference/EliminationTreeUnordered.h index 1b24b36c7..2c33266b6 100644 --- a/gtsam/inference/EliminationTreeUnordered.h +++ b/gtsam/inference/EliminationTreeUnordered.h @@ -19,12 +19,14 @@ #include #include +#include #include #include #include class EliminationTreeUnorderedTester; // for unit tests, see testEliminationTree +namespace { template struct EliminationNode; } namespace gtsam { @@ -59,28 +61,29 @@ namespace gtsam { typedef typename boost::shared_ptr sharedFactor; ///< Shared pointer to a factor typedef BAYESNET BayesNetType; ///< The BayesNet corresponding to FACTOR typedef typename BayesNetType::ConditionalType ConditionalType; ///< The type of conditionals - typedef typename GRAPH::Eliminate Eliminate; ///< Typedef for an eliminate subroutine + typedef typename boost::shared_ptr sharedConditional; ///< Shared pointer to a conditional + typedef boost::function(std::vector, std::vector)> + Eliminate; ///< Typedef for an eliminate subroutine private: class Node { public: - typedef boost::shared_ptr shared_ptr; typedef FastList Factors; - typedef FastList SubTrees; + typedef FastList > SubTrees; Key key; ///< key associated with root Factors factors; ///< factors associated with root SubTrees subTrees; ///< sub-trees }; - typedef Node::shared_ptr sharedNode; ///< Shared pointer to Node + typedef boost::shared_ptr sharedNode; ///< Shared pointer to Node /** concept check */ GTSAM_CONCEPT_TESTABLE_TYPE(FactorType); FastList roots_; - FactorGraphType remainingFactors_; + std::vector remainingFactors_; public: @@ -107,11 +110,11 @@ namespace gtsam { /** TODO: Copy constructor - makes a deep copy of the tree structure, but only pointers to factors are * copied, factors are not cloned. */ - EliminationTreeUnordered(const This& other) { throw std::runtime_error("Not implemented"); } + EliminationTreeUnordered(const This& other) { *this = other; } /** TODO: Assignment operator - makes a deep copy of the tree structure, but only pointers to factors are * copied, factors are not cloned. */ - This& operator=(const This& other) { throw std::runtime_error("Not implemented"); } + This& operator=(const This& other); /// @} /// @name Standard Interface @@ -138,13 +141,18 @@ namespace gtsam { /// @} - private: + protected: + /// Protected default constructor + EliminationTreeUnordered() {} + private: /// Allow access to constructor and add methods for testing purposes friend class ::EliminationTreeUnorderedTester; + + friend struct EliminationNode; }; } -#include +#include diff --git a/gtsam/inference/FactorGraphUnordered-inl.h b/gtsam/inference/FactorGraphUnordered-inl.h index 4d45ecde8..272995409 100644 --- a/gtsam/inference/FactorGraphUnordered-inl.h +++ b/gtsam/inference/FactorGraphUnordered-inl.h @@ -38,14 +38,14 @@ namespace gtsam { /* ************************************************************************* */ template - void FactorGraphUnordered::print(const std::string& s, - const KeyFormatter& formatter) const { + void FactorGraphUnordered::print(const std::string& s, const KeyFormatter& formatter) const { std::cout << s << std::endl; std::cout << "size: " << size() << std::endl; for (size_t i = 0; i < factors_.size(); i++) { std::stringstream ss; ss << "factor " << i << ": "; - if (factors_[i] != NULL) factors_[i]->print(ss.str(), formatter); + if (factors_[i]) + factors_[i]->print(ss.str(), formatter); } } diff --git a/gtsam/inference/FactorGraphUnordered.h b/gtsam/inference/FactorGraphUnordered.h index 1bccc04b3..9cb8db921 100644 --- a/gtsam/inference/FactorGraphUnordered.h +++ b/gtsam/inference/FactorGraphUnordered.h @@ -22,7 +22,6 @@ #pragma once #include -#include #include #include @@ -48,12 +47,6 @@ namespace gtsam { typedef typename std::vector::iterator iterator; typedef typename std::vector::const_iterator const_iterator; - /** typedef for elimination result */ - typedef std::pair EliminationResult; - - /** typedef for an eliminate subroutine */ - typedef boost::function Eliminate; - protected: /** concept check, makes sure FACTOR defines print and equals */ @@ -70,6 +63,10 @@ namespace gtsam { /** Default constructor */ FactorGraphUnordered() {} + /** Constructor from iterator over factors */ + template + FactorGraphUnordered(ITERATOR firstFactor, ITERATOR lastFactor) { push_back(firstFactor, lastFactor); } + /// @} /// @name Advanced Constructors /// @{ diff --git a/gtsam/inference/FactorUnordered.cpp b/gtsam/inference/FactorUnordered.cpp index d6b92bf51..28b6594d1 100644 --- a/gtsam/inference/FactorUnordered.cpp +++ b/gtsam/inference/FactorUnordered.cpp @@ -19,12 +19,15 @@ // \callgraph +#include +#include + #include namespace gtsam { /* ************************************************************************* */ - void FactorUnordered::print(const std::string& s = "Factor", const KeyFormatter& formatter = DefaultKeyFormatter) const + void FactorUnordered::print(const std::string& s, const KeyFormatter& formatter) const { return this->printKeys(s, formatter); } @@ -32,8 +35,13 @@ namespace gtsam { /* ************************************************************************* */ void FactorUnordered::printKeys(const std::string& s, const KeyFormatter& formatter) const { std::cout << s << " "; - BOOST_FOREACH(KEY key, keys_) std::cout << " " << formatter(key); + BOOST_FOREACH(Key key, keys_) std::cout << " " << formatter(key); std::cout << std::endl; } + /* ************************************************************************* */ + bool FactorUnordered::equals(const This& other, double tol) const { + return keys_ == other.keys_; + } + } \ No newline at end of file diff --git a/gtsam/inference/FactorUnordered.h b/gtsam/inference/FactorUnordered.h index 90f26dbef..d1b49b139 100644 --- a/gtsam/inference/FactorUnordered.h +++ b/gtsam/inference/FactorUnordered.h @@ -48,7 +48,7 @@ namespace gtsam { * during symbolic elimination. GaussianFactor and NonlinearFactor are virtual. * \nosubgrouping */ -class FactorUnordered { +class GTSAM_EXPORT FactorUnordered { public: @@ -108,7 +108,9 @@ public: /** Construct n-way factor from iterator over keys. */ template static FactorUnordered FromIterator(ITERATOR first, ITERATOR last) { - FactorUnordered result; result.keys_.assign(first, last); } + FactorUnordered result; + result.keys_.assign(first, last); + return result; } /** Construct n-way factor from container of keys. */ template diff --git a/gtsam/inference/Key.cpp b/gtsam/inference/Key.cpp index fe9f8c480..521ca5261 100644 --- a/gtsam/inference/Key.cpp +++ b/gtsam/inference/Key.cpp @@ -22,7 +22,7 @@ #include #include -#include +#include #include namespace gtsam { diff --git a/gtsam/inference/OrderingUnordered.cpp b/gtsam/inference/OrderingUnordered.cpp deleted file mode 100644 index 4ab3a2b75..000000000 --- a/gtsam/inference/OrderingUnordered.cpp +++ /dev/null @@ -1,130 +0,0 @@ -/* ---------------------------------------------------------------------------- - - * GTSAM Copyright 2010, Georgia Tech Research Corporation, - * Atlanta, Georgia 30332-0415 - * All Rights Reserved - * Authors: Frank Dellaert, et al. (see THANKS for the full author list) - - * See LICENSE for the license information - - * -------------------------------------------------------------------------- */ - -/** - * @file Ordering.cpp - * @author Richard Roberts - * @date Sep 2, 2010 - */ - -#include "Ordering.h" - -#include -#include -#include - -using namespace std; - -namespace gtsam { - -/* ************************************************************************* */ -Ordering::Ordering(const std::list & L) { - int i = 0; - BOOST_FOREACH( Key s, L ) - insert(s, i++) ; -} - -/* ************************************************************************* */ -Ordering::Ordering(const Ordering& other) : order_(other.order_), orderingIndex_(other.size()) { - for(iterator item = order_.begin(); item != order_.end(); ++item) - orderingIndex_[item->second] = item; -} - -/* ************************************************************************* */ -Ordering& Ordering::operator=(const Ordering& rhs) { - order_ = rhs.order_; - orderingIndex_.resize(rhs.size()); - for(iterator item = order_.begin(); item != order_.end(); ++item) - orderingIndex_[item->second] = item; - return *this; -} - -/* ************************************************************************* */ -void Ordering::permuteInPlace(const Permutation& permutation) { - gttic(Ordering_permuteInPlace); - // Allocate new index and permute in map iterators - OrderingIndex newIndex(permutation.size()); - for(size_t j = 0; j < newIndex.size(); ++j) { - newIndex[j] = orderingIndex_[permutation[j]]; // Assign the iterator - newIndex[j]->second = j; // Change the stored index to its permuted value - } - // Swap the new index into this Ordering class - orderingIndex_.swap(newIndex); -} - -/* ************************************************************************* */ -void Ordering::permuteInPlace(const Permutation& selector, const Permutation& permutation) { - if(selector.size() != permutation.size()) - throw invalid_argument("Ordering::permuteInPlace (partial permutation version) called with selector and permutation of different sizes."); - // Create new index the size of the permuted entries - OrderingIndex newIndex(selector.size()); - // Permute the affected entries into the new index - for(size_t dstSlot = 0; dstSlot < selector.size(); ++dstSlot) - newIndex[dstSlot] = orderingIndex_[selector[permutation[dstSlot]]]; - // Put the affected entries back in the new order and fix the indices - for(size_t slot = 0; slot < selector.size(); ++slot) { - orderingIndex_[selector[slot]] = newIndex[slot]; - orderingIndex_[selector[slot]]->second = selector[slot]; - } -} - -/* ************************************************************************* */ -void Ordering::print(const string& str, const KeyFormatter& keyFormatter) const { - cout << str; - // Print ordering in index order - // Print the ordering with varsPerLine ordering entries printed on each line, - // for compactness. - static const size_t varsPerLine = 10; - bool endedOnNewline = false; - BOOST_FOREACH(const Map::iterator& index_key, orderingIndex_) { - if(index_key->second % varsPerLine != 0) - cout << ", "; - cout << index_key->second<< ":" << keyFormatter(index_key->first); - if(index_key->second % varsPerLine == varsPerLine - 1) { - cout << "\n"; - endedOnNewline = true; - } else { - endedOnNewline = false; - } - } - if(!endedOnNewline) - cout << "\n"; - cout.flush(); -} - -/* ************************************************************************* */ -bool Ordering::equals(const Ordering& rhs, double tol) const { - return order_ == rhs.order_; -} - -/* ************************************************************************* */ -Ordering::value_type Ordering::pop_back() { - iterator lastItem = orderingIndex_.back(); // Get the map iterator to the highest-index entry - value_type removed = *lastItem; // Save the key-index pair to return - order_.erase(lastItem); // Erase the entry from the map - orderingIndex_.pop_back(); // Erase the entry from the index - return removed; // Return the removed item -} - -/* ************************************************************************* */ -void Unordered::print(const string& s) const { - cout << s << " (" << size() << "):"; - BOOST_FOREACH(Index key, *this) - cout << " " << key; - cout << endl; -} - -/* ************************************************************************* */ -bool Unordered::equals(const Unordered &other, double tol) const { - return *this == other; -} - -} diff --git a/gtsam/inference/OrderingUnordered.h b/gtsam/inference/OrderingUnordered.h deleted file mode 100644 index ad32443d6..000000000 --- a/gtsam/inference/OrderingUnordered.h +++ /dev/null @@ -1,271 +0,0 @@ -/* ---------------------------------------------------------------------------- - - * GTSAM Copyright 2010, Georgia Tech Research Corporation, - * Atlanta, Georgia 30332-0415 - * All Rights Reserved - * Authors: Frank Dellaert, et al. (see THANKS for the full author list) - - * See LICENSE for the license information - - * -------------------------------------------------------------------------- */ - -/** - * @file Ordering.h - * @author Richard Roberts - * @date Sep 2, 2010 - */ - -#pragma once - -#include -#include -#include - -#include -#include -#include -#include - -namespace gtsam { - -/** - * An ordering is a map from symbols (non-typed keys) to integer indices - * \nosubgrouping - */ -class GTSAM_EXPORT Ordering { -protected: - typedef FastMap Map; - typedef std::vector OrderingIndex; - Map order_; - OrderingIndex orderingIndex_; - -public: - - typedef boost::shared_ptr shared_ptr; - - typedef std::pair value_type; - typedef Map::iterator iterator; - typedef Map::const_iterator const_iterator; - - /// @name Standard Constructors - /// @{ - - /// Default constructor for empty ordering - Ordering() {} - - /// Copy constructor - Ordering(const Ordering& other); - - /// Construct from list, assigns order indices sequentially to list items. - Ordering(const std::list & L); - - /// Assignment operator - Ordering& operator=(const Ordering& rhs); - - /// @} - /// @name Standard Interface - /// @{ - - /** The actual number of variables in this ordering, i.e. not including missing indices in the count. See also nVars(). */ - Index size() const { return orderingIndex_.size(); } - - const_iterator begin() const { return order_.begin(); } /**< Iterator in order of sorted symbols, not in elimination/index order! */ - const_iterator end() const { return order_.end(); } /**< Iterator in order of sorted symbols, not in elimination/index order! */ - - Index at(Key key) const { return operator[](key); } ///< Synonym for operator[](Key) const - Key key(Index index) const { - if(index >= orderingIndex_.size()) - throw std::out_of_range("Attempting to access out-of-range index in Ordering"); - else - return orderingIndex_[index]->first; } - - /** Assigns the ordering index of the requested \c key into \c index if the symbol - * is present in the ordering, otherwise does not modify \c index. The - * return value indicates whether the symbol is in fact present in the - * ordering. - * @param key The key whose index you request - * @param [out] index Reference into which to write the index of the requested key, if the key is present. - * @return true if the key is present and \c index was modified, false otherwise. - */ - bool tryAt(Key key, Index& index) const { - const_iterator i = order_.find(key); - if(i != order_.end()) { - index = i->second; - return true; - } else - return false; } - - /// Access the index for the requested key, throws std::out_of_range if the - /// key is not present in the ordering (note that this differs from the - /// behavior of std::map) - Index& operator[](Key key) { - iterator i=order_.find(key); - if(i == order_.end()) throw std::out_of_range( - std::string("Attempting to access a key from an ordering that does not contain that key:") + DefaultKeyFormatter(key)); - else return i->second; } - - /// Access the index for the requested key, throws std::out_of_range if the - /// key is not present in the ordering (note that this differs from the - /// behavior of std::map) - Index operator[](Key key) const { - const_iterator i=order_.find(key); - if(i == order_.end()) throw std::out_of_range( - std::string("Attempting to access a key from an ordering that does not contain that key:") + DefaultKeyFormatter(key)); - else return i->second; } - - /** Returns an iterator pointing to the symbol/index pair with the requested, - * or the end iterator if it does not exist. - * - * @return An iterator pointing to the symbol/index pair with the requested, - * or the end iterator if it does not exist. - */ - iterator find(Key key) { return order_.find(key); } - - /** Returns an iterator pointing to the symbol/index pair with the requested, - * or the end iterator if it does not exist. - * - * @return An iterator pointing to the symbol/index pair with the requested, - * or the end iterator if it does not exist. - */ - const_iterator find(Key key) const { return order_.find(key); } - - /** Insert a key-index pair, but will fail if the key is already present */ - iterator insert(const value_type& key_order) { - std::pair it_ok(order_.insert(key_order)); - if(it_ok.second) { - if(key_order.second >= orderingIndex_.size()) - orderingIndex_.resize(key_order.second + 1); - orderingIndex_[key_order.second] = it_ok.first; - return it_ok.first; - } else - throw std::invalid_argument(std::string("Attempting to insert a key into an ordering that already contains that key")); } - - /// Test if the key exists in the ordering. - bool exists(Key key) const { return order_.count(key) > 0; } - - /** Insert a key-index pair, but will fail if the key is already present */ - iterator insert(Key key, Index order) { return insert(std::make_pair(key,order)); } - - /// Adds a new key to the ordering with an index of one greater than the current highest index. - Index push_back(Key key) { return insert(std::make_pair(key, orderingIndex_.size()))->second; } - - /// @} - /// @name Advanced Interface - /// @{ - - /** - * Iterator in order of sorted symbols, not in elimination/index order! - */ - iterator begin() { return order_.begin(); } - - /** - * Iterator in order of sorted symbols, not in elimination/index order! - */ - iterator end() { return order_.end(); } - - /** Remove the last (last-ordered, not highest-sorting key) symbol/index pair - * from the ordering (this version is \f$ O(n) \f$, use it when you do not - * know the last-ordered key). - * - * If you already know the last-ordered symbol, call popback(Key) - * that accepts this symbol as an argument. - * - * @return The symbol and index that were removed. - */ - value_type pop_back(); - - /** - * += operator allows statements like 'ordering += x0,x1,x2,x3;', which are - * very useful for unit tests. This functionality is courtesy of - * boost::assign. - */ - inline boost::assign::list_inserter, Key> - operator+=(Key key) { - return boost::assign::make_list_inserter(boost::assign_detail::call_push_back(*this))(key); } - - /** - * Reorder the variables with a permutation. This is typically used - * internally, permuting an initial key-sorted ordering into a fill-reducing - * ordering. - */ - void permuteInPlace(const Permutation& permutation); - - void permuteInPlace(const Permutation& selector, const Permutation& permutation); - - /// Synonym for operator[](Key) - Index& at(Key key) { return operator[](key); } - - /// @} - /// @name Testable - /// @{ - - /** print (from Testable) for testing and debugging */ - void print(const std::string& str = "Ordering:\n", const KeyFormatter& keyFormatter = DefaultKeyFormatter) const; - - /** equals (from Testable) for testing and debugging */ - bool equals(const Ordering& rhs, double tol = 0.0) const; - - /// @} - -private: - - /** Serialization function */ - friend class boost::serialization::access; - template - void save(ARCHIVE & ar, const unsigned int version) const - { - ar & BOOST_SERIALIZATION_NVP(order_); - size_t size_ = orderingIndex_.size(); // Save only the size but not the iterators - ar & BOOST_SERIALIZATION_NVP(size_); - } - template - void load(ARCHIVE & ar, const unsigned int version) - { - ar & BOOST_SERIALIZATION_NVP(order_); - size_t size_; - ar & BOOST_SERIALIZATION_NVP(size_); - orderingIndex_.resize(size_); - for(iterator item = order_.begin(); item != order_.end(); ++item) - orderingIndex_[item->second] = item; // Assign the iterators - } - BOOST_SERIALIZATION_SPLIT_MEMBER() -}; // \class Ordering - -/** - * @class Unordered - * @brief a set of unordered indices - */ -class Unordered: public std::set { -public: - /** Default constructor creates empty ordering */ - Unordered() { } - - /** Create from a single symbol */ - Unordered(Index key) { insert(key); } - - /** Copy constructor */ - Unordered(const std::set& keys_in) : std::set(keys_in) {} - - /** whether a key exists */ - bool exists(const Index& key) { return find(key) != end(); } - - // Testable - GTSAM_EXPORT void print(const std::string& s = "Unordered") const; - GTSAM_EXPORT bool equals(const Unordered &t, double tol=0) const; -}; - -// Create an index formatter that looks up the Key in an inverse ordering, then -// formats the key using the provided key formatter, used in saveGraph. -class GTSAM_EXPORT OrderingIndexFormatter { -private: - Ordering ordering_; - KeyFormatter keyFormatter_; -public: - OrderingIndexFormatter(const Ordering& ordering, const KeyFormatter& keyFormatter) : - ordering_(ordering), keyFormatter_(keyFormatter) {} - std::string operator()(Index index) { - return keyFormatter_(ordering_.key(index)); } -}; - -} // \namespace gtsam - diff --git a/gtsam/inference/VariableIndexUnordered-inl.h b/gtsam/inference/VariableIndexUnordered-inl.h index 5e06d6686..4b7cbfd2a 100644 --- a/gtsam/inference/VariableIndexUnordered-inl.h +++ b/gtsam/inference/VariableIndexUnordered-inl.h @@ -34,7 +34,7 @@ void VariableIndexUnordered::augment(const FG& factors) for(size_t i = 0; i < factors.size(); ++i) { if(factors[i]) { const size_t globalI = originalNFactors + i; - BOOST_FOREACH(const Key key, factors[i]) { + BOOST_FOREACH(const Key key, *factors[i]) { index_[key].push_back(globalI); ++ nEntries_; } diff --git a/gtsam/inference/VariableIndexUnordered.h b/gtsam/inference/VariableIndexUnordered.h index fb9393b69..ada3a206e 100644 --- a/gtsam/inference/VariableIndexUnordered.h +++ b/gtsam/inference/VariableIndexUnordered.h @@ -70,7 +70,7 @@ public: * of a factor graph. */ template - VariableIndexUnordered(const FG& factorGraph) { augment(factorGraph); } + VariableIndexUnordered(const FG& factorGraph) : nFactors_(0), nEntries_(0) { augment(factorGraph); } /// @} /// @name Standard Interface diff --git a/gtsam/navigation/tests/testInertialNavFactor_GlobalVelocity.cpp b/gtsam/navigation/tests/testInertialNavFactor_GlobalVelocity.cpp index 6622e8bf9..00f8d107e 100644 --- a/gtsam/navigation/tests/testInertialNavFactor_GlobalVelocity.cpp +++ b/gtsam/navigation/tests/testInertialNavFactor_GlobalVelocity.cpp @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include #include diff --git a/gtsam/nonlinear/Ordering.h b/gtsam/nonlinear/Ordering.h index bc69ff1bd..0c3d276ad 100644 --- a/gtsam/nonlinear/Ordering.h +++ b/gtsam/nonlinear/Ordering.h @@ -17,7 +17,7 @@ #pragma once -#include +#include #include #include diff --git a/gtsam/nonlinear/Symbol.h b/gtsam/nonlinear/Symbol.h index 2c406be34..6963905e0 100644 --- a/gtsam/nonlinear/Symbol.h +++ b/gtsam/nonlinear/Symbol.h @@ -18,9 +18,10 @@ #pragma once -#include #include +#include + namespace gtsam { /** diff --git a/gtsam/nonlinear/Values.h b/gtsam/nonlinear/Values.h index e1f8def88..c8cd10d20 100644 --- a/gtsam/nonlinear/Values.h +++ b/gtsam/nonlinear/Values.h @@ -24,12 +24,6 @@ #pragma once -#include -#include -#include -#include -#include - #include #include #include @@ -49,6 +43,12 @@ #include #include +#include +#include +#include +#include +#include + namespace gtsam { // Forward declarations / utilities diff --git a/gtsam/nonlinear/nonlinearExceptions.h b/gtsam/nonlinear/nonlinearExceptions.h index 6f512f65f..413610f82 100644 --- a/gtsam/nonlinear/nonlinearExceptions.h +++ b/gtsam/nonlinear/nonlinearExceptions.h @@ -17,10 +17,11 @@ */ #pragma once -#include #include #include +#include + namespace gtsam { /** diff --git a/gtsam/symbolic/CMakeLists.txt b/gtsam/symbolic/CMakeLists.txt index 545a759b6..cf16b03aa 100644 --- a/gtsam/symbolic/CMakeLists.txt +++ b/gtsam/symbolic/CMakeLists.txt @@ -4,11 +4,11 @@ install(FILES ${symbolic_headers} DESTINATION include/gtsam/symbolic) # Components to link tests in this subfolder against set(symbolic_local_libs - symbolic inference geometry base ccolamd + symbolic ) # Files to exclude from compilation of tests and timing scripts diff --git a/gtsam/symbolic/SymbolicBayesNetUnordered.h b/gtsam/symbolic/SymbolicBayesNetUnordered.h index 025b0a7ff..523ea094b 100644 --- a/gtsam/symbolic/SymbolicBayesNetUnordered.h +++ b/gtsam/symbolic/SymbolicBayesNetUnordered.h @@ -20,6 +20,7 @@ #include #include +#include namespace gtsam { @@ -30,6 +31,9 @@ namespace gtsam { public: + typedef SymbolicFactorGraphUnordered Base; + typedef SymbolicConditionalUnordered ConditionalType; + /// @name Standard Constructors /// @{ diff --git a/gtsam/symbolic/SymbolicConditionalUnordered.h b/gtsam/symbolic/SymbolicConditionalUnordered.h index ca3694386..1bc810bb4 100644 --- a/gtsam/symbolic/SymbolicConditionalUnordered.h +++ b/gtsam/symbolic/SymbolicConditionalUnordered.h @@ -32,13 +32,13 @@ namespace gtsam { * class for conditionals. * \nosubgrouping */ - class SymbolicConditionalUnordered : public SymbolicFactorUnordered, public ConditionalUnordered { + class GTSAM_EXPORT SymbolicConditionalUnordered : public SymbolicFactorUnordered, public ConditionalUnordered { public: typedef SymbolicConditionalUnordered This; /// Typedef to this class typedef SymbolicFactorUnordered BaseFactor; /// Typedef to the factor base class - typedef ConditionalUnordered BaseConditional; /// Typedef to the conditional base class + typedef ConditionalUnordered BaseConditional; /// Typedef to the conditional base class typedef boost::shared_ptr shared_ptr; /// Boost shared_ptr to this class typedef BaseFactor::iterator iterator; /// iterator to keys typedef BaseFactor::const_iterator const_iterator; /// const_iterator to keys @@ -66,18 +66,14 @@ namespace gtsam { static SymbolicConditionalUnordered FromIterator(ITERATOR firstKey, ITERATOR lastKey, size_t nrFrontals) { SymbolicConditionalUnordered result; - result = BaseFactor::FromIterator(firstKey, lastKey); + (BaseFactor&)result = BaseFactor::FromIterator(firstKey, lastKey); result.nrFrontals_ = nrFrontals; return result; } /** Named constructor from an arbitrary number of keys and frontals */ template - static SymbolicConditionalUnordered FromKeys(const CONTAINER& keys, size_t nrFrontals) - { - SymbolicConditionalUnordered result; - result = BaseFactor::FromKeys(keys); - result.nrFrontals_ = nrFrontals; - return result; } + static SymbolicConditionalUnordered FromKeys(const CONTAINER& keys, size_t nrFrontals) { + return FromIterator(keys.begin(), keys.end(), nrFrontals); } /// @} diff --git a/gtsam/symbolic/SymbolicEliminationTreeUnordered.h b/gtsam/symbolic/SymbolicEliminationTreeUnordered.h index 0514e1492..5aa8b12e3 100644 --- a/gtsam/symbolic/SymbolicEliminationTreeUnordered.h +++ b/gtsam/symbolic/SymbolicEliminationTreeUnordered.h @@ -16,9 +16,9 @@ * @author Richard Roberts */ -#include #include #include +#include namespace gtsam { @@ -57,6 +57,13 @@ namespace gtsam { * copied, factors are not cloned. */ This& operator=(const This& other) { (void) Base::operator=(other); return *this; } + private: + + /// Private default constructor + SymbolicEliminationTreeUnordered() {} + + friend class ::EliminationTreeUnorderedTester; + }; } diff --git a/gtsam/symbolic/SymbolicFactorGraphUnordered.h b/gtsam/symbolic/SymbolicFactorGraphUnordered.h index c7f56dd08..b06b65139 100644 --- a/gtsam/symbolic/SymbolicFactorGraphUnordered.h +++ b/gtsam/symbolic/SymbolicFactorGraphUnordered.h @@ -27,31 +27,38 @@ namespace gtsam { /** Symbolic Factor Graph * \nosubgrouping */ - class SymbolicFactorGraphUnordered: public FactorGraphUnordered { + class GTSAM_EXPORT SymbolicFactorGraphUnordered: public FactorGraphUnordered { public: + typedef SymbolicFactorGraphUnordered This; + typedef FactorGraphUnordered Base; + /// @name Standard Constructors /// @{ /** Construct empty factor graph */ SymbolicFactorGraphUnordered() {} + /** Constructor from iterator over factors */ + template + SymbolicFactorGraphUnordered(ITERATOR firstFactor, ITERATOR lastFactor) : Base(firstFactor, lastFactor) {} + /// @} /// @name Standard Interface /// @{ /** Push back unary factor */ - GTSAM_EXPORT void push_factor(Key key); + void push_factor(Key key); /** Push back binary factor */ - GTSAM_EXPORT void push_factor(Key key1, Key key2); + void push_factor(Key key1, Key key2); /** Push back ternary factor */ - GTSAM_EXPORT void push_factor(Key key1, Key key2, Key key3); + void push_factor(Key key1, Key key2, Key key3); /** Push back 4-way factor */ - GTSAM_EXPORT void push_factor(Key key1, Key key2, Key key3, Key key4); + void push_factor(Key key1, Key key2, Key key3, Key key4); /// @} }; diff --git a/gtsam/symbolic/SymbolicFactorUnordered.cpp b/gtsam/symbolic/SymbolicFactorUnordered.cpp index 6a455958b..138a99668 100644 --- a/gtsam/symbolic/SymbolicFactorUnordered.cpp +++ b/gtsam/symbolic/SymbolicFactorUnordered.cpp @@ -34,6 +34,12 @@ namespace gtsam { BOOST_FOREACH(const SymbolicFactorUnordered::shared_ptr& factor, factors) { allKeys.insert(factor->begin(), factor->end()); } + // Check keys + BOOST_FOREACH(Key key, keys) { + if(allKeys.find(key) == allKeys.end()) + throw std::runtime_error("Requested to eliminate a key that is not in the factors"); + } + // Sort frontal keys FastSet frontals(keys); const size_t nFrontals = keys.size(); diff --git a/gtsam/symbolic/SymbolicFactorUnordered.h b/gtsam/symbolic/SymbolicFactorUnordered.h index 46c319fc5..7515fab09 100644 --- a/gtsam/symbolic/SymbolicFactorUnordered.h +++ b/gtsam/symbolic/SymbolicFactorUnordered.h @@ -17,6 +17,9 @@ #pragma once +#include +#include + #include #include @@ -33,7 +36,7 @@ namespace gtsam { * It derives from Factor with a key type of Key, an unsigned integer. * \nosubgrouping */ - class SymbolicFactorUnordered: public FactorUnordered { + class GTSAM_EXPORT SymbolicFactorUnordered: public FactorUnordered { public: @@ -47,12 +50,6 @@ namespace gtsam { /// @name Standard Interface /// @{ - /** Virtual destructor */ - ~SymbolicFactorUnordered() {} - - /** Copy constructor */ - SymbolicFactorUnordered(const This& f) : Base(f) {} - /** Default constructor for I/O */ SymbolicFactorUnordered() {} @@ -83,14 +80,14 @@ namespace gtsam { template static SymbolicFactorUnordered FromIterator(KEYITERATOR beginKey, KEYITERATOR endKey) { SymbolicFactorUnordered result; - result = Base::FromIterator(beginKey, endKey); + (Base&)result = Base::FromIterator(beginKey, endKey); return result; } /** Constructor from a collection of keys */ template static SymbolicFactorUnordered FromKeys(const CONTAINER& keys) { SymbolicFactorUnordered result; - result = Base::FromKeys(keys); + (Base&)result = Base::FromKeys(keys); return result; } /// @} @@ -105,7 +102,7 @@ namespace gtsam { }; // IndexFactor - std::pair, boost::shared_ptr > - EliminateSymbolicUnordered(const vector& factors, const vector& keys); + GTSAM_EXPORT std::pair, boost::shared_ptr > + EliminateSymbolicUnordered(const std::vector& factors, const std::vector& keys); } diff --git a/gtsam/symbolic/tests/testSymbolicEliminationTree.cpp b/gtsam/symbolic/tests/testSymbolicEliminationTree.cpp index 28f7cc72b..3db2363c4 100644 --- a/gtsam/symbolic/tests/testSymbolicEliminationTree.cpp +++ b/gtsam/symbolic/tests/testSymbolicEliminationTree.cpp @@ -17,6 +17,9 @@ */ #include + +#include + #include #include @@ -28,45 +31,54 @@ public: // build hardcoded tree static SymbolicEliminationTreeUnordered buildHardcodedTree(const SymbolicFactorGraphUnordered& fg) { - SymbolicEliminationTreeUnordered::sharedNode leaf0(new SymbolicEliminationTree); - leaf0->add(fg[0]); - leaf0->add(fg[1]); + SymbolicEliminationTreeUnordered::sharedNode leaf0(new SymbolicEliminationTreeUnordered::Node); + leaf0->key = 0; + leaf0->factors.push_back(fg[0]); + leaf0->factors.push_back(fg[1]); - SymbolicEliminationTreeUnordered::sharedNode node1(new SymbolicEliminationTree(1)); - node1->add(fg[2]); - node1->add(leaf0); + SymbolicEliminationTreeUnordered::sharedNode node1(new SymbolicEliminationTreeUnordered::Node); + node1->key = 1; + node1->factors.push_back(fg[2]); + node1->subTrees.push_back(leaf0); - SymbolicEliminationTreeUnordered::sharedNode node2(new SymbolicEliminationTree(2)); - node2->add(fg[3]); - node2->add(node1); + SymbolicEliminationTreeUnordered::sharedNode node2(new SymbolicEliminationTreeUnordered::Node); + node2->key = 2; + node2->factors.push_back(fg[3]); + node2->subTrees.push_back(node1); - SymbolicEliminationTreeUnordered::sharedNode leaf3(new SymbolicEliminationTree(3)); - leaf3->add(fg[4]); + SymbolicEliminationTreeUnordered::sharedNode leaf3(new SymbolicEliminationTreeUnordered::Node); + leaf3->key = 3; + leaf3->factors.push_back(fg[4]); - SymbolicEliminationTreeUnordered::sharedNode etree(new SymbolicEliminationTree(4)); - etree->add(leaf3); - etree->add(node2); + SymbolicEliminationTreeUnordered::sharedNode root(new SymbolicEliminationTreeUnordered::Node); + root->key = 4; + root->subTrees.push_back(leaf3); + root->subTrees.push_back(node2); - return etree; + SymbolicEliminationTreeUnordered tree; + tree.roots_.push_back(root); + return tree; } }; TEST(EliminationTree, Create) { // create example factor graph - SymbolicFactorGraph fg; + SymbolicFactorGraphUnordered fg; fg.push_factor(0, 1); fg.push_factor(0, 2); fg.push_factor(1, 4); fg.push_factor(2, 4); fg.push_factor(3, 4); - SymbolicEliminationTree::shared_ptr expected = EliminationTreeTester::buildHardcodedTree(fg); + SymbolicEliminationTreeUnordered expected = EliminationTreeUnorderedTester::buildHardcodedTree(fg); // Build from factor graph - SymbolicEliminationTree::shared_ptr actual = SymbolicEliminationTree::Create(fg); + vector order; + order += 0,1,2,3,4; + SymbolicEliminationTreeUnordered actual(fg, order); - CHECK(assert_equal(*expected,*actual)); + CHECK(assert_equal(expected, actual)); } /* ************************************************************************* */ @@ -74,18 +86,18 @@ TEST(EliminationTree, Create) // graph: f(0,1) f(0,2) f(1,4) f(2,4) f(3,4) /* ************************************************************************* */ -TEST(EliminationTree, eliminate ) +TEST_UNSAFE(EliminationTree, eliminate ) { // create expected Chordal bayes Net - SymbolicBayesNet expected; - expected.push_front(boost::make_shared(4)); - expected.push_front(boost::make_shared(3,4)); - expected.push_front(boost::make_shared(2,4)); - expected.push_front(boost::make_shared(1,2,4)); - expected.push_front(boost::make_shared(0,1,2)); + SymbolicBayesNetUnordered expected; + expected.push_back(boost::make_shared(4)); + expected.push_back(boost::make_shared(3,4)); + expected.push_back(boost::make_shared(2,4)); + expected.push_back(boost::make_shared(1,2,4)); + expected.push_back(boost::make_shared(0,1,2)); // Create factor graph - SymbolicFactorGraph fg; + SymbolicFactorGraphUnordered fg; fg.push_factor(0, 1); fg.push_factor(0, 2); fg.push_factor(1, 4); @@ -93,21 +105,23 @@ TEST(EliminationTree, eliminate ) fg.push_factor(3, 4); // eliminate - SymbolicBayesNet actual = *SymbolicSequentialSolver(fg).eliminate(); + vector order; + order += 0,1,2,3,4; + SymbolicBayesNetUnordered actual = *SymbolicEliminationTreeUnordered(fg,order).eliminate(EliminateSymbolicUnordered).first; CHECK(assert_equal(expected,actual)); } /* ************************************************************************* */ -TEST(EliminationTree, disconnected_graph) { - SymbolicFactorGraph fg; - fg.push_factor(0, 1); - fg.push_factor(0, 2); - fg.push_factor(1, 2); - fg.push_factor(3, 4); - - CHECK_EXCEPTION(SymbolicEliminationTree::Create(fg), DisconnectedGraphException); -} +//TEST(EliminationTree, disconnected_graph) { +// SymbolicFactorGraph fg; +// fg.push_factor(0, 1); +// fg.push_factor(0, 2); +// fg.push_factor(1, 2); +// fg.push_factor(3, 4); +// +// CHECK_EXCEPTION(SymbolicEliminationTree::Create(fg), DisconnectedGraphException); +//} /* ************************************************************************* */ int main() { diff --git a/gtsam_unstable/nonlinear/FixedLagSmoother.h b/gtsam_unstable/nonlinear/FixedLagSmoother.h index 89dba73ca..686cd239f 100644 --- a/gtsam_unstable/nonlinear/FixedLagSmoother.h +++ b/gtsam_unstable/nonlinear/FixedLagSmoother.h @@ -21,9 +21,9 @@ #pragma once #include +#include #include #include -#include #include namespace gtsam { diff --git a/gtsam_unstable/nonlinear/tests/testBatchFixedLagSmoother.cpp b/gtsam_unstable/nonlinear/tests/testBatchFixedLagSmoother.cpp index 09fe3c381..d2f17e9f3 100644 --- a/gtsam_unstable/nonlinear/tests/testBatchFixedLagSmoother.cpp +++ b/gtsam_unstable/nonlinear/tests/testBatchFixedLagSmoother.cpp @@ -18,16 +18,16 @@ #include #include -#include -#include +#include +#include +#include +#include +#include #include #include #include -#include -#include -#include -#include -#include +#include +#include using namespace std; using namespace gtsam; diff --git a/gtsam_unstable/nonlinear/tests/testConcurrentBatchFilter.cpp b/gtsam_unstable/nonlinear/tests/testConcurrentBatchFilter.cpp index fca4457cc..2a99ce31a 100644 --- a/gtsam_unstable/nonlinear/tests/testConcurrentBatchFilter.cpp +++ b/gtsam_unstable/nonlinear/tests/testConcurrentBatchFilter.cpp @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/gtsam_unstable/nonlinear/tests/testConcurrentBatchSmoother.cpp b/gtsam_unstable/nonlinear/tests/testConcurrentBatchSmoother.cpp index dfd297ace..550d8971d 100644 --- a/gtsam_unstable/nonlinear/tests/testConcurrentBatchSmoother.cpp +++ b/gtsam_unstable/nonlinear/tests/testConcurrentBatchSmoother.cpp @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/gtsam_unstable/nonlinear/tests/testIncrementalFixedLagSmoother.cpp b/gtsam_unstable/nonlinear/tests/testIncrementalFixedLagSmoother.cpp index 73bb8c0a3..2111f45ab 100644 --- a/gtsam_unstable/nonlinear/tests/testIncrementalFixedLagSmoother.cpp +++ b/gtsam_unstable/nonlinear/tests/testIncrementalFixedLagSmoother.cpp @@ -19,17 +19,17 @@ #include #include +#include +#include +#include +#include +#include #include #include #include #include #include #include -#include -#include -#include -#include -#include using namespace std; using namespace gtsam; diff --git a/gtsam_unstable/nonlinear/tests/testLinearizedFactor.cpp b/gtsam_unstable/nonlinear/tests/testLinearizedFactor.cpp index 426683806..66ed5f5c1 100644 --- a/gtsam_unstable/nonlinear/tests/testLinearizedFactor.cpp +++ b/gtsam_unstable/nonlinear/tests/testLinearizedFactor.cpp @@ -17,12 +17,12 @@ */ #include -#include +#include #include +#include #include #include -#include -#include +#include #include using namespace gtsam; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 0ebada21e..b29b444ec 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -15,6 +15,7 @@ set(tests_local_libs linear discrete inference + symbolic geometry base ccolamd