diff --git a/.cproject b/.cproject index aa9dd3b86..5d28b6cdb 100644 --- a/.cproject +++ b/.cproject @@ -490,9 +490,10 @@ false true - + make -testSymbolicBayesChain.run + +testSymbolicBayesNet.run true false true diff --git a/cpp/BayesNet-inl.h b/cpp/BayesNet-inl.h index 321ef7b87..3743d4c96 100644 --- a/cpp/BayesNet-inl.h +++ b/cpp/BayesNet-inl.h @@ -30,29 +30,8 @@ namespace gtsam { /* ************************************************************************* */ template bool BayesNet::equals(const BayesNet& cbn, double tol) const { - if(indices_ != cbn.indices_) return false; if(size() != cbn.size()) return false; - return equal(conditionals_.begin(),conditionals_.begin(),conditionals_.begin(),equals_star); - } - - /* ************************************************************************* */ - template - void BayesNet::push_back - (const boost::shared_ptr& conditional) { - indices_.insert(make_pair(conditional->key(),conditionals_.size())); - conditionals_.push_back(conditional); - } - - /* ************************************************************************* * - template - void BayesNet::erase(const string& key) { - list::iterator it; - for (it=keys_.begin(); it != keys_.end(); ++it){ - if( strcmp(key.c_str(), (*it).c_str()) == 0 ) - break; - } - keys_.erase(it); - conditionals_.erase(key); + return equal(conditionals_.begin(),conditionals_.end(),cbn.conditionals_.begin(),equals_star(tol)); } /* ************************************************************************* */ @@ -65,5 +44,24 @@ namespace gtsam { } /* ************************************************************************* */ + // predicate to check whether a conditional has the sought key + template + class HasKey { + const string& key_; + public: + HasKey(const std::string& key):key_(key) {} + bool operator()(const boost::shared_ptr& conditional) { + return (conditional->key()==key_); + } + }; + + template + boost::shared_ptr BayesNet::operator[](const std::string& key) const { + const_iterator it = find_if(conditionals_.begin(),conditionals_.end(),HasKey(key)); + if (it == conditionals_.end()) throw(invalid_argument( + "BayesNet::operator['"+key+"']: not found")); + return *it; + } + /* ************************************************************************* */ } // namespace gtsam diff --git a/cpp/BayesNet.h b/cpp/BayesNet.h index d22526b7e..8b5821e7e 100644 --- a/cpp/BayesNet.h +++ b/cpp/BayesNet.h @@ -8,10 +8,9 @@ #pragma once -#include +#include #include -#include -#include +#include #include #include "Testable.h" @@ -33,7 +32,8 @@ namespace gtsam { /** We store shared pointers to Conditional densities */ typedef typename boost::shared_ptr conditional_ptr; - typedef typename std::vector Conditionals; + typedef typename std::list Conditionals; + typedef typename Conditionals::const_iterator const_iterator; typedef typename Conditionals::const_reverse_iterator const_reverse_iterator; @@ -46,19 +46,6 @@ namespace gtsam { */ Conditionals conditionals_; - /** - * O(log n) random access on keys will provided by a map from keys to vector index. - */ - typedef std::map Indices; - Indices indices_; - - /** O(log n) lookup from key to node index */ - inline int index(const std::string& key) const { - Indices::const_iterator it = indices_.find(key); // get node index - assert( it != indices_.end() ); - return it->second; - } - public: /** print */ @@ -68,7 +55,14 @@ namespace gtsam { bool equals(const BayesNet& other, double tol = 1e-9) const; /** push_back: use reverse topological sort (i.e. parents last / elimination order) */ - void push_back(const boost::shared_ptr& conditional); + inline void push_back(const boost::shared_ptr& conditional) { + conditionals_.push_back(conditional); + } + + /** push_front: use topological sort (i.e. parents first / reverse elimination order) */ + inline void push_front(const boost::shared_ptr& conditional) { + conditionals_.push_front(conditional); + } /** size is the number of nodes */ inline size_t size() const { @@ -78,11 +72,8 @@ namespace gtsam { /** return keys in reverse topological sort order, i.e., elimination order */ Ordering ordering() const; - /** O(log n) random access to Conditional by key */ - inline conditional_ptr operator[](const std::string& key) const { - int i = index(key); - return conditionals_[i]; - } + /** SLOW O(n) random access to Conditional by key */ + conditional_ptr operator[](const std::string& key) const; /** return iterators. FD: breaks encapsulation? */ const_iterator const begin() const {return conditionals_.begin();} @@ -96,7 +87,6 @@ namespace gtsam { template void serialize(Archive & ar, const unsigned int version) { ar & BOOST_SERIALIZATION_NVP(conditionals_); - ar & BOOST_SERIALIZATION_NVP(indices_); } }; diff --git a/cpp/BayesTree-inl.h b/cpp/BayesTree-inl.h index 472110179..0442b82de 100644 --- a/cpp/BayesTree-inl.h +++ b/cpp/BayesTree-inl.h @@ -50,9 +50,8 @@ namespace gtsam { template BayesTree::BayesTree(const BayesNet& bayesNet, bool verbose) { typename BayesNet::const_reverse_iterator rit; - for ( rit=bayesNet.rbegin(); rit < bayesNet.rend(); ++rit ) { + for ( rit=bayesNet.rbegin(); rit != bayesNet.rend(); ++rit ) insert(*rit,verbose); - } } /* ************************************************************************* */ @@ -69,7 +68,7 @@ namespace gtsam { double tol) const { return size()==other.size() && equal(nodeMap_.begin(),nodeMap_.end(),other.nodeMap_.begin()) && - equal(nodes_.begin(),nodes_.end(),other.nodes_.begin(),equals_star); + equal(nodes_.begin(),nodes_.end(),other.nodes_.begin(),equals_star(tol)); } /* ************************************************************************* */ @@ -106,7 +105,7 @@ namespace gtsam { if (parent_clique->size() == parents.size()) { if (verbose) cout << "Adding to clique " << index << endl; nodeMap_.insert(make_pair(key, index)); - parent_clique->push_back(conditional); + parent_clique->push_front(conditional); return; } diff --git a/cpp/LinearFactor.cpp b/cpp/LinearFactor.cpp index 2ca9bc934..028e95430 100644 --- a/cpp/LinearFactor.cpp +++ b/cpp/LinearFactor.cpp @@ -25,7 +25,7 @@ using namespace gtsam; typedef pair& mypair; /* ************************************************************************* */ -LinearFactor::LinearFactor(const boost::shared_ptr cg) : +LinearFactor::LinearFactor(const boost::shared_ptr& cg) : b(cg->get_d()) { As.insert(make_pair(cg->key(), cg->get_R())); std::map::const_iterator it = cg->parentsBegin(); diff --git a/cpp/LinearFactor.h b/cpp/LinearFactor.h index 65bf22ff8..6d85e4d4f 100644 --- a/cpp/LinearFactor.h +++ b/cpp/LinearFactor.h @@ -82,7 +82,7 @@ public: } /** Construct from Conditional Gaussian */ - LinearFactor(const boost::shared_ptr cg); + LinearFactor(const boost::shared_ptr& cg); /** * Constructor that combines a set of factors diff --git a/cpp/SymbolicConditional.h b/cpp/SymbolicConditional.h index 7c1d4b253..130e96fef 100644 --- a/cpp/SymbolicConditional.h +++ b/cpp/SymbolicConditional.h @@ -65,7 +65,8 @@ namespace gtsam { /** print */ void print(const std::string& s = "SymbolicConditional") const { - std::cout << s << " P(" << key_ << " |"; + std::cout << s << " P(" << key_; + if (parents_.size()>0) std::cout << " |"; BOOST_FOREACH(std::string parent, parents_) std::cout << " " << parent; std::cout << ")" << std::endl; } diff --git a/cpp/Testable.h b/cpp/Testable.h index d69021b92..63ba92139 100644 --- a/cpp/Testable.h +++ b/cpp/Testable.h @@ -55,17 +55,24 @@ namespace gtsam { * Template to create a binary predicate */ template - bool equals(const V& expected, const V& actual, double tol = 1e-9) { - return (actual.equals(expected, tol)); - } + struct equals : public std::binary_function { + double tol_; + equals(double tol = 1e-9) : tol_(tol) {} + bool operator()(const V& expected, const V& actual) { + return (actual.equals(expected, tol_)); + } + }; /** * Binary predicate on shared pointers */ template - bool equals_star(const boost::shared_ptr& expected, - const boost::shared_ptr& actual, double tol = 1e-9) { - return (actual->equals(*expected, tol)); - } + struct equals_star : public std::binary_function&, const boost::shared_ptr&, bool> { + double tol_; + equals_star(double tol = 1e-9) : tol_(tol) {} + bool operator()(const boost::shared_ptr& expected, const boost::shared_ptr& actual) { + return (actual->equals(*expected, tol_)); + } + }; } // gtsam diff --git a/cpp/testBayesTree.cpp b/cpp/testBayesTree.cpp index dbcb6b3be..bde5c044c 100644 --- a/cpp/testBayesTree.cpp +++ b/cpp/testBayesTree.cpp @@ -54,9 +54,9 @@ TEST( BayesTree, constructor ) // Check root BayesNet expected_root; - expected_root.push_back(B); - expected_root.push_back(L); expected_root.push_back(E); + expected_root.push_back(L); + expected_root.push_back(B); BayesNet actual_root = bayesTree.root(); CHECK(assert_equal(expected_root,actual_root)); @@ -68,7 +68,7 @@ TEST( BayesTree, constructor ) ASIA.push_back(E); ASIA.push_back(L); ASIA.push_back(B); - bool verbose = true; + bool verbose = false; BayesTree bayesTree2(ASIA,verbose); if (verbose) bayesTree2.print("bayesTree2");