diff --git a/packages/CLPBN/examples/complex.fg b/packages/CLPBN/examples/complex.fg new file mode 100644 index 000000000..30f076ba4 --- /dev/null +++ b/packages/CLPBN/examples/complex.fg @@ -0,0 +1,137 @@ +10 + +2 +0 1 +2 2 +4 +0 1.02 +1 0.87 +2 0.88 +3 0.45 + +4 +1 2 3 4 +2 2 3 3 +36 +0 0.11 +1 1.11 +2 0.41 +3 0.12 +4 0.1 +5 0.17 +6 1.21 +7 1.1 +8 0.11 +9 0.41 +10 0.8 +11 0.71 +12 0.14 +13 0.24 +14 0.54 +15 1.4 +16 0.23 +17 0.24 +18 0.65 +19 0.05 +20 0.32 +21 0.12 +22 0.99 +23 0.69 +24 0.29 +25 1.29 +26 0.15 +27 1.24 +28 0.42 +29 0.124 +30 0.67 +31 0.078 +32 0.14 +33 0.55 +34 0.45 +35 0.1 + +3 +2 5 6 +2 2 3 +12 +0 0.15 +1 0.55 +2 2.21 +3 5.71 +4 0.44 +5 0.14 +6 0.5 +7 1.75 +8 1.29 +9 3.29 +10 0.36 +11 1.56 + +2 +7 2 +4 2 +8 +0 0.11 +1 0.59 +2 0.15 +3 0.124 +4 0.41 +5 2.11 +6 1.06 +7 0.929 + +1 +3 +3 +3 +0 0.1 +1 0.58 +2 0.74 + +1 +4 +3 +3 +0 3.2 +1 0.28 +2 1.24 + +2 +8 4 +2 3 +6 +0 0.19 +1 3.1 +2 0.49 +3 1.5 +4 2.1 +5 2.8 + +1 +5 +2 +2 +0 0.74 +1 0.14 + +1 +6 +3 +3 +0 0.032 +1 0.028 +2 0.24 + +2 +9 7 +2 4 +8 +0 0.61 +1 0.61 +2 1.4 +3 0.24 +4 0.09 +5 0.19 +6 1.4 +7 0.6 + diff --git a/packages/CLPBN/examples/complex.pfl b/packages/CLPBN/examples/complex.pfl new file mode 100644 index 000000000..14a78a4c5 --- /dev/null +++ b/packages/CLPBN/examples/complex.pfl @@ -0,0 +1,79 @@ +:- use_module(library(pfl)). + +%:- set_solver(ve). +%:- set_solver(hve). +%:- set_solver(jt). +%:- set_solver(bdd). +%:- set_solver(bp). +%:- set_solver(cbp). +%:- set_solver(gibbs). +%:- set_solver(lve). +%:- set_solver(lkc). +%:- set_solver(lbp). + +/* + + v01 v02 + \ / + \ / + \ / + v03 v04 v05 + / \ | / \ + / \ | / \ + / \ | / \ + v06 v07 v08 + | | + | | + | | + v09 v10 + +*/ + +markov v01::[a,b] ; table1 ; []. + +markov v02::[a,b,c] ; table2 ; []. + +markov v03::[a,b], v01, v02 ; table3 ; []. + +markov v04::[a,b,c] ; table4 ; []. + +markov v05::[a,b,c] ; table5 ; []. + +markov v06::[a,b,c,d], v03 ; table6 ; []. + +markov v07::[a,b], v03, v04, v05 ; table7 ; []. + +markov v08::[a,b], v05 ; table8 ; []. + +markov v09::[a,b], v06 ; table9 ; []. + +markov v10::[a,b], v07 ; table10 ; []. + +table1([ 0.74, 0.14 ]). + +table2([ 0.032, 0.028, 0.24 ]). + +table3([ + 0.15, 0.44, 1.29, 2.21, 0.5, 0.36, + 0.55, 0.14, 3.29, 5.71, 1.75, 1.56 +]). + +table4([ 0.1, 0.58, 0.74 ]). + +table5([ 3.2, 0.28, 1.24 ]). + +table6([ 0.11, 0.41, 0.59, 2.11, 0.15, 1.06, 0.124, 0.929 ]). + +table7([ + 0.11, 0.14, 0.29, 0.1, 0.23, 0.42, 0.11, 0.32, 0.14, + 0.41, 0.54, 0.15, 1.21, 0.65, 0.67, 0.8, 0.99, 0.45, + 1.11, 0.24, 1.29, 0.17, 0.24, 0.124, 0.41, 0.12, 0.55, + 0.12, 1.4, 1.24, 1.1, 0.05, 0.078, 0.71, 0.69, 0.1 +]). + +table8([ 0.19, 0.49, 2.1, 3.1, 1.5, 2.8 ]). + +table9([ 0.61, 1.4, 0.09, 1.4, 0.61, 0.24, 0.19, 0.6 ]). + +table10([ 1.02, 0.88, 0.87, 0.45 ]). + diff --git a/packages/CLPBN/horus/BayesBall.cpp b/packages/CLPBN/horus/BayesBall.cpp index da0c73ff5..f84b508b0 100644 --- a/packages/CLPBN/horus/BayesBall.cpp +++ b/packages/CLPBN/horus/BayesBall.cpp @@ -3,6 +3,25 @@ #include "BayesBall.h" +namespace Horus { + +BayesBall::BayesBall (FactorGraph& fg) + : fg_(fg) , dag_(fg.getStructure()) +{ + dag_.clear(); +} + + + +FactorGraph* +BayesBall::getMinimalFactorGraph (FactorGraph& fg, VarIds vids) +{ + BayesBall bb (fg); + return bb.getMinimalFactorGraph (vids); +} + + + FactorGraph* BayesBall::getMinimalFactorGraph (const VarIds& queryIds) { @@ -19,22 +38,22 @@ BayesBall::getMinimalFactorGraph (const VarIds& queryIds) BBNode* n = sch.node; n->setAsVisited(); if (n->hasEvidence() == false && sch.visitedFromChild) { - if (n->isMarkedOnTop() == false) { - n->markOnTop(); + if (n->isMarkedAbove() == false) { + n->markAbove(); scheduleParents (n, scheduling); } - if (n->isMarkedOnBottom() == false) { - n->markOnBottom(); + if (n->isMarkedBelow() == false) { + n->markBelow(); scheduleChilds (n, scheduling); } } if (sch.visitedFromParent) { - if (n->hasEvidence() && n->isMarkedOnTop() == false) { - n->markOnTop(); + if (n->hasEvidence() && n->isMarkedAbove() == false) { + n->markAbove(); scheduleParents (n, scheduling); } - if (n->hasEvidence() == false && n->isMarkedOnBottom() == false) { - n->markOnBottom(); + if (n->hasEvidence() == false && n->isMarkedBelow() == false) { + n->markBelow(); scheduleChilds (n, scheduling); } } @@ -55,7 +74,7 @@ BayesBall::constructGraph (FactorGraph* fg) const for (size_t i = 0; i < facNodes.size(); i++) { const BBNode* n = dag_.getNode ( facNodes[i]->factor().argument (0)); - if (n->isMarkedOnTop()) { + if (n->isMarkedAbove()) { fg->addFactor (facNodes[i]->factor()); } else if (n->hasEvidence() && n->isVisited()) { VarIds varIds = { facNodes[i]->factor().argument (0) }; @@ -76,3 +95,5 @@ BayesBall::constructGraph (FactorGraph* fg) const } } +} // namespace Horus + diff --git a/packages/CLPBN/horus/BayesBall.h b/packages/CLPBN/horus/BayesBall.h index 2057b6f01..0913a0ec6 100644 --- a/packages/CLPBN/horus/BayesBall.h +++ b/packages/CLPBN/horus/BayesBall.h @@ -1,5 +1,5 @@ -#ifndef HORUS_BAYESBALL_H -#define HORUS_BAYESBALL_H +#ifndef YAP_PACKAGES_CLPBN_HORUS_BAYESBALL_H_ +#define YAP_PACKAGES_CLPBN_HORUS_BAYESBALL_H_ #include #include @@ -9,41 +9,28 @@ #include "BayesBallGraph.h" #include "Horus.h" -using namespace std; +namespace Horus { -struct ScheduleInfo -{ - ScheduleInfo (BBNode* n, bool vfp, bool vfc) - : node(n), visitedFromParent(vfp), visitedFromChild(vfc) { } - - BBNode* node; - bool visitedFromParent; - bool visitedFromChild; -}; - - -typedef queue> Scheduling; - - -class BayesBall -{ +class BayesBall { public: - BayesBall (FactorGraph& fg) - : fg_(fg) , dag_(fg.getStructure()) - { - dag_.clear(); - } + BayesBall (FactorGraph& fg); FactorGraph* getMinimalFactorGraph (const VarIds&); - static FactorGraph* getMinimalFactorGraph (FactorGraph& fg, VarIds vids) - { - BayesBall bb (fg); - return bb.getMinimalFactorGraph (vids); - } + static FactorGraph* getMinimalFactorGraph (FactorGraph& fg, VarIds vids); private: + struct ScheduleInfo { + ScheduleInfo (BBNode* n, bool vfp, bool vfc) + : node(n), visitedFromParent(vfp), visitedFromChild(vfc) { } + + BBNode* node; + bool visitedFromParent; + bool visitedFromChild; + }; + + typedef std::queue> Scheduling; void constructGraph (FactorGraph* fg) const; @@ -51,9 +38,8 @@ class BayesBall void scheduleChilds (const BBNode* n, Scheduling& sch) const; - FactorGraph& fg_; - - BayesBallGraph& dag_; + FactorGraph& fg_; + BayesBallGraph& dag_; }; @@ -61,8 +47,8 @@ class BayesBall inline void BayesBall::scheduleParents (const BBNode* n, Scheduling& sch) const { - const vector& ps = n->parents(); - for (vector::const_iterator it = ps.begin(); + const std::vector& ps = n->parents(); + for (std::vector::const_iterator it = ps.begin(); it != ps.end(); ++it) { sch.push (ScheduleInfo (*it, false, true)); } @@ -73,12 +59,14 @@ BayesBall::scheduleParents (const BBNode* n, Scheduling& sch) const inline void BayesBall::scheduleChilds (const BBNode* n, Scheduling& sch) const { - const vector& cs = n->childs(); - for (vector::const_iterator it = cs.begin(); + const std::vector& cs = n->childs(); + for (std::vector::const_iterator it = cs.begin(); it != cs.end(); ++it) { sch.push (ScheduleInfo (*it, true, false)); } } -#endif // HORUS_BAYESBALL_H +} // namespace Horus + +#endif // YAP_PACKAGES_CLPBN_HORUS_BAYESBALL_H_ diff --git a/packages/CLPBN/horus/BayesBallGraph.cpp b/packages/CLPBN/horus/BayesBallGraph.cpp index 60db22bfe..898a0aa41 100644 --- a/packages/CLPBN/horus/BayesBallGraph.cpp +++ b/packages/CLPBN/horus/BayesBallGraph.cpp @@ -1,14 +1,15 @@ -#include #include #include -#include #include +#include #include "BayesBallGraph.h" #include "Util.h" +namespace Horus { + void BayesBallGraph::addNode (BBNode* n) { @@ -22,8 +23,8 @@ BayesBallGraph::addNode (BBNode* n) void BayesBallGraph::addEdge (VarId vid1, VarId vid2) { - unordered_map::iterator it1; - unordered_map::iterator it2; + std::unordered_map::iterator it1; + std::unordered_map::iterator it2; it1 = varMap_.find (vid1); it2 = varMap_.find (vid2); assert (it1 != varMap_.end()); @@ -37,7 +38,7 @@ BayesBallGraph::addEdge (VarId vid1, VarId vid2) const BBNode* BayesBallGraph::getNode (VarId vid) const { - unordered_map::const_iterator it; + std::unordered_map::const_iterator it; it = varMap_.find (vid); return it != varMap_.end() ? it->second : 0; } @@ -47,7 +48,7 @@ BayesBallGraph::getNode (VarId vid) const BBNode* BayesBallGraph::getNode (VarId vid) { - unordered_map::const_iterator it; + std::unordered_map::const_iterator it; it = varMap_.find (vid); return it != varMap_.end() ? it->second : 0; } @@ -55,7 +56,7 @@ BayesBallGraph::getNode (VarId vid) void -BayesBallGraph::setIndexes (void) +BayesBallGraph::setIndexes() { for (size_t i = 0; i < nodes_.size(); i++) { nodes_[i]->setIndex (i); @@ -65,7 +66,7 @@ BayesBallGraph::setIndexes (void) void -BayesBallGraph::clear (void) +BayesBallGraph::clear() { for (size_t i = 0; i < nodes_.size(); i++) { nodes_[i]->clear(); @@ -77,13 +78,14 @@ BayesBallGraph::clear (void) void BayesBallGraph::exportToGraphViz (const char* fileName) { - ofstream out (fileName); + std::ofstream out (fileName); if (!out.is_open()) { - cerr << "Error: couldn't open file '" << fileName << "'." ; + std::cerr << "Error: couldn't open file '" << fileName << "'." ; + std::cerr << std::endl; return; } - out << "digraph {" << endl; - out << "ranksep=1" << endl; + out << "digraph {" << std::endl; + out << "ranksep=1" << std::endl; for (size_t i = 0; i < nodes_.size(); i++) { out << nodes_[i]->varId() ; out << " [" ; @@ -91,16 +93,18 @@ BayesBallGraph::exportToGraphViz (const char* fileName) if (nodes_[i]->hasEvidence()) { out << ",style=filled, fillcolor=yellow" ; } - out << "]" << endl; + out << "]" << std::endl; } for (size_t i = 0; i < nodes_.size(); i++) { - const vector& childs = nodes_[i]->childs(); + const std::vector& childs = nodes_[i]->childs(); for (size_t j = 0; j < childs.size(); j++) { out << nodes_[i]->varId() << " -> " << childs[j]->varId(); - out << " [style=bold]" << endl ; + out << " [style=bold]" << std::endl; } } - out << "}" << endl; + out << "}" << std::endl; out.close(); } +} // namespace Horus + diff --git a/packages/CLPBN/horus/BayesBallGraph.h b/packages/CLPBN/horus/BayesBallGraph.h index eb44f0ae8..185003d7b 100644 --- a/packages/CLPBN/horus/BayesBallGraph.h +++ b/packages/CLPBN/horus/BayesBallGraph.h @@ -1,5 +1,5 @@ -#ifndef HORUS_BAYESBALLGRAPH_H -#define HORUS_BAYESBALLGRAPH_H +#ifndef YAP_PACKAGES_CLPBN_HORUS_BAYESBALLGRAPH_H_ +#define YAP_PACKAGES_CLPBN_HORUS_BAYESBALLGRAPH_H_ #include #include @@ -7,54 +7,55 @@ #include "Var.h" #include "Horus.h" -using namespace std; -class BBNode : public Var -{ +namespace Horus { + +class BBNode : public Var { public: BBNode (Var* v) : Var (v), visited_(false), - markedOnTop_(false), markedOnBottom_(false) { } + markedAbove_(false), markedBelow_(false) { } - const vector& childs (void) const { return childs_; } + const std::vector& childs() const { return childs_; } - vector& childs (void) { return childs_; } + std::vector& childs() { return childs_; } - const vector& parents (void) const { return parents_; } + const std::vector& parents() const { return parents_; } - vector& parents (void) { return parents_; } + std::vector& parents() { return parents_; } void addParent (BBNode* p) { parents_.push_back (p); } void addChild (BBNode* c) { childs_.push_back (c); } - bool isVisited (void) const { return visited_; } + bool isVisited() const { return visited_; } - void setAsVisited (void) { visited_ = true; } + void setAsVisited() { visited_ = true; } - bool isMarkedOnTop (void) const { return markedOnTop_; } + bool isMarkedAbove() const { return markedAbove_; } - void markOnTop (void) { markedOnTop_ = true; } + void markAbove() { markedAbove_ = true; } - bool isMarkedOnBottom (void) const { return markedOnBottom_; } + bool isMarkedBelow() const { return markedBelow_; } - void markOnBottom (void) { markedOnBottom_ = true; } + void markBelow() { markedBelow_ = true; } - void clear (void) { visited_ = markedOnTop_ = markedOnBottom_ = false; } + void clear() { visited_ = markedAbove_ = markedBelow_ = false; } private: bool visited_; - bool markedOnTop_; - bool markedOnBottom_; + bool markedAbove_; + bool markedBelow_; - vector childs_; - vector parents_; + std::vector childs_; + std::vector parents_; }; -class BayesBallGraph -{ +class BayesBallGraph { public: - BayesBallGraph (void) { } + BayesBallGraph() { } + + bool empty() const { return nodes_.empty(); } void addNode (BBNode* n); @@ -64,19 +65,18 @@ class BayesBallGraph BBNode* getNode (VarId vid); - bool empty (void) const { return nodes_.empty(); } + void setIndexes(); - void setIndexes (void); - - void clear (void); + void clear(); void exportToGraphViz (const char*); private: - vector nodes_; - - unordered_map varMap_; + std::vector nodes_; + std::unordered_map varMap_; }; -#endif // HORUS_BAYESBALLGRAPH_H +} // namespace Horus + +#endif // YAP_PACKAGES_CLPBN_HORUS_BAYESBALLGRAPH_H_ diff --git a/packages/CLPBN/horus/BeliefProp.cpp b/packages/CLPBN/horus/BeliefProp.cpp index 5ec3aafd5..16542b3fe 100644 --- a/packages/CLPBN/horus/BeliefProp.cpp +++ b/packages/CLPBN/horus/BeliefProp.cpp @@ -1,37 +1,39 @@ #include #include - #include +#include +#include #include "BeliefProp.h" #include "Indexer.h" #include "Horus.h" -double BeliefProp::accuracy_ = 0.0001; -unsigned BeliefProp::maxIter_ = 1000; -MsgSchedule BeliefProp::schedule_ = MsgSchedule::SEQ_FIXED; +namespace Horus { + +double BeliefProp::accuracy_ = 0.0001; +unsigned BeliefProp::maxIter_ = 1000; + +BeliefProp::MsgSchedule BeliefProp::schedule_ = + MsgSchedule::seqFixedSch; -BeliefProp::BeliefProp (const FactorGraph& fg) : GroundSolver (fg) + +BeliefProp::BeliefProp (const FactorGraph& fg) + : GroundSolver (fg), nIters_(0), runned_(false) { - runned_ = false; + } -BeliefProp::~BeliefProp (void) +BeliefProp::~BeliefProp() { - for (size_t i = 0; i < varsI_.size(); i++) { - delete varsI_[i]; - } - for (size_t i = 0; i < facsI_.size(); i++) { - delete facsI_[i]; - } for (size_t i = 0; i < links_.size(); i++) { delete links_[i]; } + links_.clear(); } @@ -48,22 +50,22 @@ BeliefProp::solveQuery (VarIds queryVids) void -BeliefProp::printSolverFlags (void) const +BeliefProp::printSolverFlags() const { - stringstream ss; + std::stringstream ss; ss << "belief propagation [" ; ss << "bp_msg_schedule=" ; switch (schedule_) { - case MsgSchedule::SEQ_FIXED: ss << "seq_fixed"; break; - case MsgSchedule::SEQ_RANDOM: ss << "seq_random"; break; - case MsgSchedule::PARALLEL: ss << "parallel"; break; - case MsgSchedule::MAX_RESIDUAL: ss << "max_residual"; break; + case MsgSchedule::seqFixedSch: ss << "seq_fixed"; break; + case MsgSchedule::seqRandomSch: ss << "seq_random"; break; + case MsgSchedule::parallelSch: ss << "parallel"; break; + case MsgSchedule::maxResidualSch: ss << "max_residual"; break; } - ss << ",bp_max_iter=" << Util::toString (maxIter_); - ss << ",bp_accuracy=" << Util::toString (accuracy_); - ss << ",log_domain=" << Util::toString (Globals::logDomain); + ss << ",bp_max_iter=" << Util::toString (maxIter_); + ss << ",bp_accuracy=" << Util::toString (accuracy_); + ss << ",log_domain=" << Util::toString (Globals::logDomain); ss << "]" ; - cout << ss.str() << endl; + std::cout << ss.str() << std::endl; } @@ -82,7 +84,7 @@ BeliefProp::getPosterioriOf (VarId vid) probs[var->getEvidence()] = LogAware::withEvidence(); } else { probs.resize (var->range(), LogAware::multIdenty()); - const BpLinks& links = ninf(var)->getLinks(); + const BpLinks& links = getLinks (var); if (Globals::logDomain) { for (size_t i = 0; i < links.size(); i++) { probs += links[i]->message(); @@ -133,7 +135,7 @@ BeliefProp::getFactorJoint ( runSolver(); } Factor res (fn->factor()); - const BpLinks& links = ninf(fn)->getLinks(); + const BpLinks& links = getLinks( fn); for (size_t i = 0; i < links.size(); i++) { Factor msg ({links[i]->varNode()->varId()}, {links[i]->varNode()->range()}, @@ -152,26 +154,119 @@ BeliefProp::getFactorJoint ( +BeliefProp::BpLink::BpLink (FacNode* fn, VarNode* vn) +{ + fac_ = fn; + var_ = vn; + v1_.resize (vn->range(), LogAware::log (1.0 / vn->range())); + v2_.resize (vn->range(), LogAware::log (1.0 / vn->range())); + currMsg_ = &v1_; + nextMsg_ = &v2_; + residual_ = 0.0; +} + + + void -BeliefProp::runSolver (void) +BeliefProp::BpLink::clearResidual() +{ + residual_ = 0.0; +} + + + +void +BeliefProp::BpLink::updateResidual() +{ + residual_ = LogAware::getMaxNorm (v1_, v2_); +} + + + +void +BeliefProp::BpLink::updateMessage() +{ + swap (currMsg_, nextMsg_); +} + + + +std::string +BeliefProp::BpLink::toString() const +{ + std::stringstream ss; + ss << fac_->getLabel(); + ss << " -- " ; + ss << var_->label(); + return ss.str(); +} + + + +void +BeliefProp::calculateAndUpdateMessage (BpLink* link, bool calcResidual) +{ + if (Globals::verbosity > 2) { + std::cout << "calculating & updating " << link->toString(); + std::cout << std::endl; + } + calcFactorToVarMsg (link); + if (calcResidual) { + link->updateResidual(); + } + link->updateMessage(); +} + + + +void +BeliefProp::calculateMessage (BpLink* link, bool calcResidual) +{ + if (Globals::verbosity > 2) { + std::cout << "calculating " << link->toString(); + std::cout << std::endl; + } + calcFactorToVarMsg (link); + if (calcResidual) { + link->updateResidual(); + } +} + + + +void +BeliefProp::updateMessage (BpLink* link) +{ + link->updateMessage(); + if (Globals::verbosity > 2) { + std::cout << "updating " << link->toString(); + std::cout << std::endl; + } +} + + + +void +BeliefProp::runSolver() { initializeSolver(); nIters_ = 0; while (!converged() && nIters_ < maxIter_) { nIters_ ++; if (Globals::verbosity > 1) { - Util::printHeader (string ("Iteration ") + Util::toString (nIters_)); + Util::printHeader (std::string ("Iteration ") + + Util::toString (nIters_)); } switch (schedule_) { - case MsgSchedule::SEQ_RANDOM: + case MsgSchedule::seqRandomSch: std::random_shuffle (links_.begin(), links_.end()); // no break - case MsgSchedule::SEQ_FIXED: + case MsgSchedule::seqFixedSch: for (size_t i = 0; i < links_.size(); i++) { calculateAndUpdateMessage (links_[i]); } break; - case MsgSchedule::PARALLEL: + case MsgSchedule::parallelSch: for (size_t i = 0; i < links_.size(); i++) { calculateMessage (links_[i]); } @@ -179,20 +274,21 @@ BeliefProp::runSolver (void) updateMessage(links_[i]); } break; - case MsgSchedule::MAX_RESIDUAL: + case MsgSchedule::maxResidualSch: maxResidualSchedule(); break; } } if (Globals::verbosity > 0) { if (nIters_ < maxIter_) { - cout << "Belief propagation converged in " ; - cout << nIters_ << " iterations" << endl; + std::cout << "Belief propagation converged in " ; + std::cout << nIters_ << " iterations" << std::endl; } else { - cout << "The maximum number of iterations was hit, terminating..." ; - cout << endl; + std::cout << "The maximum number of iterations was hit," ; + std::cout << " terminating..." ; + std::cout << std::endl; } - cout << endl; + std::cout << std::endl; } runned_ = true; } @@ -200,7 +296,7 @@ BeliefProp::runSolver (void) void -BeliefProp::createLinks (void) +BeliefProp::createLinks() { const FacNodes& facNodes = fg.facNodes(); for (size_t i = 0; i < facNodes.size(); i++) { @@ -214,7 +310,7 @@ BeliefProp::createLinks (void) void -BeliefProp::maxResidualSchedule (void) +BeliefProp::maxResidualSchedule() { if (nIters_ == 1) { for (size_t i = 0; i < links_.size(); i++) { @@ -227,11 +323,13 @@ BeliefProp::maxResidualSchedule (void) for (size_t c = 0; c < links_.size(); c++) { if (Globals::verbosity > 1) { - cout << "current residuals:" << endl; + std::cout << "current residuals:" << std::endl; for (SortedOrder::iterator it = sortedOrder_.begin(); it != sortedOrder_.end(); ++it) { - cout << " " << setw (30) << left << (*it)->toString(); - cout << "residual = " << (*it)->residual() << endl; + std::cout << " " << std::setw (30) << std::left; + std::cout << (*it)->toString(); + std::cout << "residual = " << (*it)->residual(); + std::cout << std::endl; } } @@ -249,7 +347,7 @@ BeliefProp::maxResidualSchedule (void) const FacNodes& factorNeighbors = link->varNode()->neighbors(); for (size_t i = 0; i < factorNeighbors.size(); i++) { if (factorNeighbors[i] != link->facNode()) { - const BpLinks& links = ninf(factorNeighbors[i])->getLinks(); + const BpLinks& links = getLinks (factorNeighbors[i]); for (size_t j = 0; j < links.size(); j++) { if (links[j]->varNode() != link->varNode()) { calculateMessage (links[j]); @@ -273,7 +371,7 @@ BeliefProp::calcFactorToVarMsg (BpLink* link) { FacNode* src = link->facNode(); const VarNode* dst = link->varNode(); - const BpLinks& links = ninf(src)->getLinks(); + const BpLinks& links = getLinks (src); // calculate the product of messages that were sent // to factor `src', except from var `dst' unsigned reps = 1; @@ -282,14 +380,14 @@ BeliefProp::calcFactorToVarMsg (BpLink* link) if (Globals::logDomain) { for (size_t i = links.size(); i-- > 0; ) { if (links[i]->varNode() != dst) { - if (Constants::SHOW_BP_CALCS) { - cout << " message from " << links[i]->varNode()->label(); - cout << ": " ; + if (Constants::showBpCalcs) { + std::cout << " message from " << links[i]->varNode()->label(); + std::cout << ": " ; } Util::apply_n_times (msgProduct, getVarToFactorMsg (links[i]), reps, std::plus()); - if (Constants::SHOW_BP_CALCS) { - cout << endl; + if (Constants::showBpCalcs) { + std::cout << std::endl; } } reps *= links[i]->varNode()->range(); @@ -297,14 +395,14 @@ BeliefProp::calcFactorToVarMsg (BpLink* link) } else { for (size_t i = links.size(); i-- > 0; ) { if (links[i]->varNode() != dst) { - if (Constants::SHOW_BP_CALCS) { - cout << " message from " << links[i]->varNode()->label(); - cout << ": " ; + if (Constants::showBpCalcs) { + std::cout << " message from " << links[i]->varNode()->label(); + std::cout << ": " ; } Util::apply_n_times (msgProduct, getVarToFactorMsg (links[i]), reps, std::multiplies()); - if (Constants::SHOW_BP_CALCS) { - cout << endl; + if (Constants::showBpCalcs) { + std::cout << std::endl; } } reps *= links[i]->varNode()->range(); @@ -313,27 +411,28 @@ BeliefProp::calcFactorToVarMsg (BpLink* link) Factor result (src->factor().arguments(), src->factor().ranges(), msgProduct); result.multiply (src->factor()); - if (Constants::SHOW_BP_CALCS) { - cout << " message product: " << msgProduct << endl; - cout << " original factor: " << src->factor().params() << endl; - cout << " factor product: " << result.params() << endl; + if (Constants::showBpCalcs) { + std::cout << " message product: " << msgProduct << std::endl; + std::cout << " original factor: " << src->factor().params(); + std::cout << std::endl; + std::cout << " factor product: " << result.params() << std::endl; } result.sumOutAllExcept (dst->varId()); - if (Constants::SHOW_BP_CALCS) { - cout << " marginalized: " << result.params() << endl; + if (Constants::showBpCalcs) { + std::cout << " marginalized: " << result.params() << std::endl; } link->nextMessage() = result.params(); LogAware::normalize (link->nextMessage()); - if (Constants::SHOW_BP_CALCS) { - cout << " curr msg: " << link->message() << endl; - cout << " next msg: " << link->nextMessage() << endl; + if (Constants::showBpCalcs) { + std::cout << " curr msg: " << link->message() << std::endl; + std::cout << " next msg: " << link->nextMessage() << std::endl; } } Params -BeliefProp::getVarToFactorMsg (const BpLink* link) const +BeliefProp::getVarToFactorMsg (const BpLink* link) { const VarNode* src = link->varNode(); Params msg; @@ -343,18 +442,18 @@ BeliefProp::getVarToFactorMsg (const BpLink* link) const } else { msg.resize (src->range(), LogAware::one()); } - if (Constants::SHOW_BP_CALCS) { - cout << msg; + if (Constants::showBpCalcs) { + std::cout << msg; } BpLinks::const_iterator it; - const BpLinks& links = ninf (src)->getLinks(); + const BpLinks& links = getLinks (src); if (Globals::logDomain) { for (it = links.begin(); it != links.end(); ++it) { if (*it != link) { msg += (*it)->message(); } - if (Constants::SHOW_BP_CALCS) { - cout << " x " << (*it)->message(); + if (Constants::showBpCalcs) { + std::cout << " x " << (*it)->message(); } } } else { @@ -362,13 +461,13 @@ BeliefProp::getVarToFactorMsg (const BpLink* link) const if (*it != link) { msg *= (*it)->message(); } - if (Constants::SHOW_BP_CALCS) { - cout << " x " << (*it)->message(); + if (Constants::showBpCalcs) { + std::cout << " x " << (*it)->message(); } } } - if (Constants::SHOW_BP_CALCS) { - cout << " = " << msg; + if (Constants::showBpCalcs) { + std::cout << " = " << msg; } return msg; } @@ -379,37 +478,37 @@ Params BeliefProp::getJointByConditioning (const VarIds& jointVarIds) const { return GroundSolver::getJointByConditioning ( - GroundSolverType::BP, fg, jointVarIds); + GroundSolverType::bpSolver, fg, jointVarIds); } void -BeliefProp::initializeSolver (void) +BeliefProp::initializeSolver() { const VarNodes& varNodes = fg.varNodes(); - varsI_.reserve (varNodes.size()); + varsLinks_.reserve (varNodes.size()); for (size_t i = 0; i < varNodes.size(); i++) { - varsI_.push_back (new SPNodeInfo()); + varsLinks_.push_back (BpLinks()); } const FacNodes& facNodes = fg.facNodes(); - facsI_.reserve (facNodes.size()); + facsLinks_.reserve (facNodes.size()); for (size_t i = 0; i < facNodes.size(); i++) { - facsI_.push_back (new SPNodeInfo()); + facsLinks_.push_back (BpLinks()); } createLinks(); for (size_t i = 0; i < links_.size(); i++) { FacNode* src = links_[i]->facNode(); VarNode* dst = links_[i]->varNode(); - ninf (dst)->addBpLink (links_[i]); - ninf (src)->addBpLink (links_[i]); + getLinks (dst).push_back (links_[i]); + getLinks (src).push_back (links_[i]); } } bool -BeliefProp::converged (void) +BeliefProp::converged() { if (links_.empty()) { return true; @@ -418,16 +517,16 @@ BeliefProp::converged (void) return false; } if (Globals::verbosity > 2) { - cout << endl; + std::cout << std::endl; } if (nIters_ == 1) { if (Globals::verbosity > 1) { - cout << "no residuals" << endl << endl; + std::cout << "no residuals" << std::endl << std::endl; } return false; } bool converged = true; - if (schedule_ == MsgSchedule::MAX_RESIDUAL) { + if (schedule_ == MsgSchedule::maxResidualSch) { double maxResidual = (*(sortedOrder_.begin()))->residual(); if (maxResidual > accuracy_) { converged = false; @@ -438,7 +537,8 @@ BeliefProp::converged (void) for (size_t i = 0; i < links_.size(); i++) { double residual = links_[i]->residual(); if (Globals::verbosity > 1) { - cout << links_[i]->toString() + " residual = " << residual << endl; + std::cout << links_[i]->toString() + " residual = " << residual; + std::cout << std::endl; } if (residual > accuracy_) { converged = false; @@ -448,7 +548,7 @@ BeliefProp::converged (void) } } if (Globals::verbosity > 1) { - cout << endl; + std::cout << std::endl; } } return converged; @@ -457,8 +557,10 @@ BeliefProp::converged (void) void -BeliefProp::printLinkInformation (void) const +BeliefProp::printLinkInformation() const { + using std::cout; + using std::endl; for (size_t i = 0; i < links_.size(); i++) { BpLink* l = links_[i]; cout << l->toString() << ":" << endl; @@ -470,3 +572,5 @@ BeliefProp::printLinkInformation (void) const } } +} // namespace Horus + diff --git a/packages/CLPBN/horus/BeliefProp.h b/packages/CLPBN/horus/BeliefProp.h index 5fad0c496..ed7641e43 100644 --- a/packages/CLPBN/horus/BeliefProp.h +++ b/packages/CLPBN/horus/BeliefProp.h @@ -1,111 +1,35 @@ -#ifndef HORUS_BELIEFPROP_H -#define HORUS_BELIEFPROP_H +#ifndef YAP_PACKAGES_CLPBN_HORUS_BELIEFPROP_H_ +#define YAP_PACKAGES_CLPBN_HORUS_BELIEFPROP_H_ -#include #include - -#include +#include +#include #include "GroundSolver.h" #include "FactorGraph.h" -using namespace std; - - -enum MsgSchedule { - SEQ_FIXED, - SEQ_RANDOM, - PARALLEL, - MAX_RESIDUAL -}; - - -class BpLink -{ - public: - BpLink (FacNode* fn, VarNode* vn) - { - fac_ = fn; - var_ = vn; - v1_.resize (vn->range(), LogAware::log (1.0 / vn->range())); - v2_.resize (vn->range(), LogAware::log (1.0 / vn->range())); - currMsg_ = &v1_; - nextMsg_ = &v2_; - residual_ = 0.0; - } - - virtual ~BpLink (void) { }; - - FacNode* facNode (void) const { return fac_; } - - VarNode* varNode (void) const { return var_; } - - const Params& message (void) const { return *currMsg_; } - - Params& nextMessage (void) { return *nextMsg_; } - - double residual (void) const { return residual_; } - - void clearResidual (void) { residual_ = 0.0; } - - void updateResidual (void) - { - residual_ = LogAware::getMaxNorm (v1_, v2_); - } - - virtual void updateMessage (void) - { - swap (currMsg_, nextMsg_); - } - - string toString (void) const - { - stringstream ss; - ss << fac_->getLabel(); - ss << " -- " ; - ss << var_->label(); - return ss.str(); - } - - protected: - FacNode* fac_; - VarNode* var_; - Params v1_; - Params v2_; - Params* currMsg_; - Params* nextMsg_; - double residual_; +namespace Horus { +class BeliefProp : public GroundSolver { private: - DISALLOW_COPY_AND_ASSIGN (BpLink); -}; + class SPNodeInfo; -typedef vector BpLinks; - - -class SPNodeInfo -{ public: - SPNodeInfo (void) { } - void addBpLink (BpLink* link) { links_.push_back (link); } - const BpLinks& getLinks (void) { return links_; } - private: - BpLinks links_; - DISALLOW_COPY_AND_ASSIGN (SPNodeInfo); -}; + enum class MsgSchedule { + seqFixedSch, + seqRandomSch, + parallelSch, + maxResidualSch + }; - -class BeliefProp : public GroundSolver -{ - public: BeliefProp (const FactorGraph&); - virtual ~BeliefProp (void); + virtual ~BeliefProp(); Params solveQuery (VarIds); - virtual void printSolverFlags (void) const; + virtual void printSolverFlags() const; virtual Params getPosterioriOf (VarId); @@ -113,105 +37,128 @@ class BeliefProp : public GroundSolver Params getFactorJoint (FacNode* fn, const VarIds&); - static double accuracy (void) { return accuracy_; } + static double accuracy() { return accuracy_; } static void setAccuracy (double acc) { accuracy_ = acc; } - static unsigned maxIterations (void) { return maxIter_; } + static unsigned maxIterations() { return maxIter_; } static void setMaxIterations (unsigned mi) { maxIter_ = mi; } - static MsgSchedule msgSchedule (void) { return schedule_; } + static MsgSchedule msgSchedule() { return schedule_; } static void setMsgSchedule (MsgSchedule sch) { schedule_ = sch; } protected: - SPNodeInfo* ninf (const VarNode* var) const - { - return varsI_[var->getIndex()]; - } + class BpLink { + public: + BpLink (FacNode* fn, VarNode* vn); - SPNodeInfo* ninf (const FacNode* fac) const - { - return facsI_[fac->getIndex()]; - } + virtual ~BpLink() { }; - void calculateAndUpdateMessage (BpLink* link, bool calcResidual = true) - { - if (Globals::verbosity > 2) { - cout << "calculating & updating " << link->toString() << endl; - } - calcFactorToVarMsg (link); - if (calcResidual) { - link->updateResidual(); - } - link->updateMessage(); - } + FacNode* facNode() const { return fac_; } - void calculateMessage (BpLink* link, bool calcResidual = true) - { - if (Globals::verbosity > 2) { - cout << "calculating " << link->toString() << endl; - } - calcFactorToVarMsg (link); - if (calcResidual) { - link->updateResidual(); - } - } + VarNode* varNode() const { return var_; } - void updateMessage (BpLink* link) - { - link->updateMessage(); - if (Globals::verbosity > 2) { - cout << "updating " << link->toString() << endl; - } - } + const Params& message() const { return *currMsg_; } - struct CompareResidual - { - inline bool operator() (const BpLink* link1, const BpLink* link2) - { - return link1->residual() > link2->residual(); - } + Params& nextMessage() { return *nextMsg_; } + + double residual() const { return residual_; } + + void clearResidual(); + + void updateResidual(); + + virtual void updateMessage(); + + std::string toString() const; + + protected: + FacNode* fac_; + VarNode* var_; + Params v1_; + Params v2_; + Params* currMsg_; + Params* nextMsg_; + double residual_; + + private: + DISALLOW_COPY_AND_ASSIGN (BpLink); }; - void runSolver (void); + struct CmpResidual { + bool operator() (const BpLink* l1, const BpLink* l2) { + return l1->residual() > l2->residual(); + }}; - virtual void createLinks (void); + typedef std::vector BpLinks; + typedef std::multiset SortedOrder; + typedef std::unordered_map BpLinkMap; - virtual void maxResidualSchedule (void); + BpLinks& getLinks (const VarNode* var); + + BpLinks& getLinks (const FacNode* fac); + + void calculateAndUpdateMessage (BpLink* link, bool calcResidual = true); + + void calculateMessage (BpLink* link, bool calcResidual = true); + + void updateMessage (BpLink* link); + + void runSolver(); + + virtual void createLinks(); + + virtual void maxResidualSchedule(); virtual void calcFactorToVarMsg (BpLink*); - virtual Params getVarToFactorMsg (const BpLink*) const; + virtual Params getVarToFactorMsg (const BpLink*); virtual Params getJointByConditioning (const VarIds&) const; - BpLinks links_; - unsigned nIters_; - vector varsI_; - vector facsI_; - bool runned_; + BpLinks links_; + unsigned nIters_; + bool runned_; + SortedOrder sortedOrder_; + BpLinkMap linkMap_; - typedef multiset SortedOrder; - SortedOrder sortedOrder_; - - typedef unordered_map BpLinkMap; - BpLinkMap linkMap_; - - static double accuracy_; - static unsigned maxIter_; - static MsgSchedule schedule_; + static double accuracy_; private: - void initializeSolver (void); + void initializeSolver(); - bool converged (void); + bool converged(); - virtual void printLinkInformation (void) const; + virtual void printLinkInformation() const; + + std::vector varsLinks_; + std::vector facsLinks_; + + static unsigned maxIter_; + static MsgSchedule schedule_; DISALLOW_COPY_AND_ASSIGN (BeliefProp); }; -#endif // HORUS_BELIEFPROP_H + + +inline BeliefProp::BpLinks& +BeliefProp::getLinks (const VarNode* var) +{ + return varsLinks_[var->getIndex()]; +} + + + +inline BeliefProp::BpLinks& +BeliefProp::getLinks (const FacNode* fac) +{ + return facsLinks_[fac->getIndex()]; +} + +} // namespace Horus + +#endif // YAP_PACKAGES_CLPBN_HORUS_BELIEFPROP_H_ diff --git a/packages/CLPBN/horus/ConstraintTree.cpp b/packages/CLPBN/horus/ConstraintTree.cpp index 599d28f37..49de4c49f 100644 --- a/packages/CLPBN/horus/ConstraintTree.cpp +++ b/packages/CLPBN/horus/ConstraintTree.cpp @@ -1,11 +1,88 @@ #include +#include +#include #include #include "ConstraintTree.h" #include "Util.h" +namespace Horus { + +class CTNode { + public: + CTNode (const CTNode& n, const CTChilds& chs = CTChilds()) + : symbol_(n.symbol()), childs_(chs), level_(n.level()) { } + + CTNode (Symbol s, unsigned l, const CTChilds& chs = CTChilds()) + : symbol_(s), childs_(chs), level_(l) { } + + unsigned level() const { return level_; } + + void setLevel (unsigned level) { level_ = level; } + + Symbol symbol() const { return symbol_; } + + void setSymbol (Symbol s) { symbol_ = s; } + + CTChilds& childs() { return childs_; } + + const CTChilds& childs() const { return childs_; } + + size_t nrChilds() const { return childs_.size(); } + + bool isRoot() const { return level_ == 0; } + + bool isLeaf() const { return childs_.empty(); } + + CTChilds::iterator findSymbol (Symbol symb); + + void mergeSubtree (CTNode*, bool = true); + + void removeChild (CTNode*); + + void removeChilds(); + + void removeAndDeleteChild (CTNode*); + + void removeAndDeleteAllChilds(); + + SymbolSet childSymbols() const; + + static CTNode* copySubtree (const CTNode*); + + static void deleteSubtree (CTNode*); + + private: + void updateChildLevels (CTNode*, unsigned); + + Symbol symbol_; + CTChilds childs_; + unsigned level_; + + DISALLOW_ASSIGN (CTNode); +}; + + + +inline CTChilds::iterator +CTNode::findSymbol (Symbol symb) +{ + CTNode tmp (symb, 0); + return childs_.find (&tmp); +} + + + +inline bool +CmpSymbol::operator() (const CTNode* n1, const CTNode* n2) const +{ + return n1->symbol() < n2->symbol(); +} + + + void CTNode::mergeSubtree (CTNode* n, bool updateLevels) { @@ -38,7 +115,7 @@ CTNode::removeChild (CTNode* child) void -CTNode::removeChilds (void) +CTNode::removeChilds() { childs_.clear(); } @@ -55,7 +132,7 @@ CTNode::removeAndDeleteChild (CTNode* child) void -CTNode::removeAndDeleteAllChilds (void) +CTNode::removeAndDeleteAllChilds() { for (CTChilds::const_iterator chIt = childs_.begin(); chIt != childs_.end(); ++ chIt) { @@ -67,7 +144,7 @@ CTNode::removeAndDeleteAllChilds (void) SymbolSet -CTNode::childSymbols (void) const +CTNode::childSymbols() const { SymbolSet symbols; for (CTChilds::const_iterator chIt = childs_.begin(); @@ -106,14 +183,14 @@ CTNode::copySubtree (const CTNode* root1) return new CTNode (*root1); } CTNode* root2 = new CTNode (*root1); - typedef pair StackPair; - vector stack = { StackPair (root1, root2) }; + typedef std::pair StackPair; + std::vector stack = { StackPair (root1, root2) }; while (stack.empty() == false) { const CTNode* n1 = stack.back().first; CTNode* n2 = stack.back().second; stack.pop_back(); - // cout << "n2 childs: " << n2->childs(); - // cout << "n1 childs: " << n1->childs(); + // std::cout << "n2 childs: " << n2->childs(); + // std::cout << "n1 childs: " << n1->childs(); n2->childs().reserve (n1->nrChilds()); stack.reserve (n1->nrChilds()); for (CTChilds::const_iterator chIt = n1->childs().begin(); @@ -144,7 +221,8 @@ CTNode::deleteSubtree (CTNode* n) -ostream& operator<< (ostream &out, const CTNode& n) +std::ostream& +operator<< (std::ostream& out, const CTNode& n) { out << "(" << n.level() << ") " ; out << n.symbol(); @@ -187,7 +265,8 @@ ConstraintTree::ConstraintTree ( -ConstraintTree::ConstraintTree (vector> names) +ConstraintTree::ConstraintTree ( + std::vector> names) { assert (names.empty() == false); assert (names.front().empty() == false); @@ -216,13 +295,33 @@ ConstraintTree::ConstraintTree (const ConstraintTree& ct) -ConstraintTree::~ConstraintTree (void) +ConstraintTree::ConstraintTree ( + const CTChilds& rootChilds, + const LogVars& logVars) + : root_(new CTNode (Symbol (0), unsigned (0), rootChilds)), + logVars_(logVars), + logVarSet_(logVars) +{ + +} + + + +ConstraintTree::~ConstraintTree() { CTNode::deleteSubtree (root_); } +bool +ConstraintTree::empty() const +{ + return root_->childs().empty(); +} + + + void ConstraintTree::addTuple (const Tuple& tuple) { @@ -448,7 +547,7 @@ ConstraintTree::ConstraintTree::isSingleton (LogVar X) LogVarSet -ConstraintTree::singletons (void) +ConstraintTree::singletons() { LogVarSet singletons; for (size_t i = 0; i < logVars_.size(); i++) { @@ -491,7 +590,7 @@ ConstraintTree::tupleSet (const LogVars& originalLvs) getTuples (root_, Tuples(), stopLevel, tuples, CTNodes() = {}); if (originalLvs.size() != uniqueLvs.size()) { - vector indexes; + std::vector indexes; indexes.reserve (originalLvs.size()); for (size_t i = 0; i < originalLvs.size(); i++) { indexes.push_back (Util::indexOf (uniqueLvs, originalLvs[i])); @@ -519,21 +618,22 @@ ConstraintTree::exportToGraphViz ( const char* fileName, bool showLogVars) const { - ofstream out (fileName); + std::ofstream out (fileName); if (!out.is_open()) { - cerr << "Error: couldn't open file '" << fileName << "'." ; + std::cerr << "Error: couldn't open file '" << fileName << "'." ; + std::cerr << std::endl; return; } - out << "digraph {" << endl; + out << "digraph {" << std::endl; ConstraintTree copy (*this); copy.moveToTop (copy.logVarSet_.elements()); CTNodes nodes = getNodesBelow (copy.root_); - out << "\"" << copy.root_ << "\"" << " [label=\"R\"]" << endl; + out << "\"" << copy.root_ << "\"" << " [label=\"R\"]" << std::endl; for (CTNodes::const_iterator it = ++ nodes.begin(); it != nodes.end(); ++ it) { out << "\"" << *it << "\""; out << " [label=\"" << **it << "\"]" ; - out << endl; + out << std::endl; } for (CTNodes::const_iterator it = nodes.begin(); it != nodes.end(); ++ it) { @@ -542,24 +642,24 @@ ConstraintTree::exportToGraphViz ( chIt != childs.end(); ++ chIt) { out << "\"" << *it << "\"" ; out << " -> " ; - out << "\"" << *chIt << "\"" << endl ; + out << "\"" << *chIt << "\"" << std::endl ; } } if (showLogVars) { - out << "Root [label=\"\", shape=plaintext]" << endl; + out << "Root [label=\"\", shape=plaintext]" << std::endl; for (size_t i = 0; i < copy.logVars_.size(); i++) { out << copy.logVars_[i] << " [label=" ; out << copy.logVars_[i] << ", " ; - out << "shape=plaintext, fontsize=14]" << endl; + out << "shape=plaintext, fontsize=14]" << std::endl; } out << "Root -> " << copy.logVars_[0]; - out << " [style=invis]" << endl; + out << " [style=invis]" << std::endl; for (size_t i = 0; i < copy.logVars_.size() - 1; i++) { out << copy.logVars_[i] << " -> " << copy.logVars_[i + 1]; - out << " [style=invis]" << endl; + out << " [style=invis]" << std::endl; } } - out << "}" << endl; + out << "}" <root(), commChilds, exclChilds, stopLevel); ConstraintTree* commCt = new ConstraintTree (commChilds, logVars_); ConstraintTree* exclCt = new ConstraintTree (exclChilds, logVars_); - // cout << commCt->tupleSet() << " + " ; - // cout << exclCt->tupleSet() << " = " ; - // cout << tupleSet() << endl; + // std::cout << commCt->tupleSet() << " + " ; + // std::cout << exclCt->tupleSet() << " = " ; + // std::cout << tupleSet() << std::endl; assert ((commCt->tupleSet() | exclCt->tupleSet()) == tupleSet()); assert ((exclCt->tupleSet (stopLevel) & ct->tupleSet (stopLevel)).empty()); return {commCt, exclCt}; @@ -710,20 +810,20 @@ ConstraintTree::countNormalize (const LogVarSet& Ys) } moveToTop (Zs.elements()); ConstraintTrees cts; - unordered_map countMap; + std::unordered_map countMap; unsigned stopLevel = getLevel (Zs.back()); const CTChilds& childs = root_->childs(); for (CTChilds::const_iterator chIt = childs.begin(); chIt != childs.end(); ++ chIt) { - const vector>& res = + const std::vector>& res = countNormalize (*chIt, stopLevel); for (size_t j = 0; j < res.size(); j++) { - unordered_map::iterator it + std::unordered_map::iterator it = countMap.find (res[j].second); if (it == countMap.end()) { ConstraintTree* newCt = new ConstraintTree (logVars_); - it = countMap.insert (make_pair (res[j].second, newCt)).first; + it = countMap.insert (std::make_pair (res[j].second, newCt)).first; cts.push_back (newCt); } it->second->root_->mergeSubtree (res[j].first); @@ -743,31 +843,31 @@ ConstraintTree::jointCountNormalize ( LogVar X_new2) { unsigned N = getConditionalCount (X); - // cout << "My tuples: " << tupleSet() << endl; - // cout << "CommCt tuples: " << commCt->tupleSet() << endl; - // cout << "ExclCt tuples: " << exclCt->tupleSet() << endl; - // cout << "Counted Lv: " << X << endl; - // cout << "X_new1: " << X_new1 << endl; - // cout << "X_new2: " << X_new2 << endl; - // cout << "Original N: " << N << endl; - // cout << endl; + // std::cout << "My tuples: " << tupleSet() << std::endl; + // std::cout << "CommCt tuples: " << commCt->tupleSet() << std::endl; + // std::cout << "ExclCt tuples: " << exclCt->tupleSet() << std::endl; + // std::cout << "Counted Lv: " << X << std::endl; + // std::cout << "X_new1: " << X_new1 << std::endl; + // std::cout << "X_new2: " << X_new2 << std::endl; + // std::cout << "Original N: " << N << std::endl; + // std::cout << endl; ConstraintTrees normCts1 = commCt->countNormalize (X); - vector counts1 (normCts1.size()); + std::vector counts1 (normCts1.size()); for (size_t i = 0; i < normCts1.size(); i++) { counts1[i] = normCts1[i]->getConditionalCount (X); - // cout << "normCts1[" << i << "] #" << counts1[i] ; - // cout << " " << normCts1[i]->tupleSet() << endl; + // std::cout << "normCts1[" << i << "] #" << counts1[i] ; + // std::cout << " " << normCts1[i]->tupleSet() << std::endl; } ConstraintTrees normCts2 = exclCt->countNormalize (X); - vector counts2 (normCts2.size()); + std::vector counts2 (normCts2.size()); for (size_t i = 0; i < normCts2.size(); i++) { counts2[i] = normCts2[i]->getConditionalCount (X); - // cout << "normCts2[" << i << "] #" << counts2[i] ; - // cout << " " << normCts2[i]->tupleSet() << endl; + // std::cout << "normCts2[" << i << "] #" << counts2[i] ; + // std::cout << " " << normCts2[i]->tupleSet() << std::endl; } - // cout << endl; + // std::cout << std::endl; ConstraintTree* excl1 = 0; for (size_t i = 0; i < normCts1.size(); i++) { @@ -775,7 +875,7 @@ ConstraintTree::jointCountNormalize ( excl1 = normCts1[i]; normCts1.erase (normCts1.begin() + i); counts1.erase (counts1.begin() + i); - // cout << "joint-count(" << N << ",0)" << endl; + // std::cout << "joint-count(" << N << ",0)" << std::endl; break; } } @@ -786,7 +886,7 @@ ConstraintTree::jointCountNormalize ( excl2 = normCts2[i]; normCts2.erase (normCts2.begin() + i); counts2.erase (counts2.begin() + i); - // cout << "joint-count(0," << N << ")" << endl; + // std::cout << "joint-count(0," << N << ")" << std::endl; break; } } @@ -794,8 +894,8 @@ ConstraintTree::jointCountNormalize ( for (size_t i = 0; i < normCts1.size(); i++) { unsigned j; for (j = 0; counts1[i] + counts2[j] != N; j++) ; - // cout << "joint-count(" << counts1[i] ; - // cout << "," << counts2[j] << ")" << endl; + // std::cout << "joint-count(" << counts1[i] ; + // std::cout << "," << counts2[j] << ")" << std::endl; const CTChilds& childs = normCts2[j]->root_->childs(); for (CTChilds::const_iterator chIt = childs.begin(); chIt != childs.end(); ++ chIt) { @@ -930,7 +1030,7 @@ CTNodes ConstraintTree::getNodesBelow (CTNode* fromHere) const { CTNodes nodes; - queue queue; + std::queue queue; queue.push (fromHere); while (queue.empty() == false) { CTNode* node = queue.front(); @@ -1016,7 +1116,7 @@ ConstraintTree::swapLogVar (LogVar X) { size_t pos = Util::indexOf (logVars_, X); assert (pos != logVars_.size()); - const CTNodes& nodes = getNodesAtLevel (pos); + CTNodes nodes = getNodesAtLevel (pos); for (CTNodes::const_iterator nodeIt = nodes.begin(); nodeIt != nodes.end(); ++ nodeIt) { CTChilds childsCopy = (*nodeIt)->childs(); @@ -1098,7 +1198,7 @@ ConstraintTree::getTuples ( unsigned -ConstraintTree::size (void) const +ConstraintTree::size() const { return countTuples (root_); } @@ -1114,26 +1214,26 @@ ConstraintTree::nrSymbols (LogVar X) -vector> +std::vector> ConstraintTree::countNormalize ( const CTNode* n, unsigned stopLevel) { if (n->level() == stopLevel) { - return vector>() = { - make_pair (CTNode::copySubtree (n), countTuples (n)) + return std::vector>() = { + std::make_pair (CTNode::copySubtree (n), countTuples (n)) }; } - vector> res; + std::vector> res; const CTChilds& childs = n->childs(); for (CTChilds::const_iterator chIt = childs.begin(); chIt != childs.end(); ++ chIt) { - const vector>& lowerRes = + const std::vector>& lowerRes = countNormalize (*chIt, stopLevel); for (size_t j = 0; j < lowerRes.size(); j++) { CTNode* newNode = new CTNode (*n); newNode->mergeSubtree (lowerRes[j].first); - res.push_back (make_pair (newNode, lowerRes[j].second)); + res.push_back (std::make_pair (newNode, lowerRes[j].second)); } } return res; @@ -1172,3 +1272,5 @@ ConstraintTree::split ( } } +} // namespace Horus + diff --git a/packages/CLPBN/horus/ConstraintTree.h b/packages/CLPBN/horus/ConstraintTree.h index 2c0c09464..416edf5f0 100644 --- a/packages/CLPBN/horus/ConstraintTree.h +++ b/packages/CLPBN/horus/ConstraintTree.h @@ -1,104 +1,35 @@ -#ifndef HORUS_CONSTRAINTTREE_H -#define HORUS_CONSTRAINTTREE_H +#ifndef YAP_PACKAGES_CLPBN_HORUS_CONSTRAINTTREE_H_ +#define YAP_PACKAGES_CLPBN_HORUS_CONSTRAINTTREE_H_ #include -#include -#include -#include +#include +#include +#include #include "TinySet.h" #include "LiftedUtils.h" -using namespace std; +namespace Horus { class CTNode; -typedef vector CTNodes; - class ConstraintTree; -typedef vector ConstraintTrees; -class CTNode -{ - public: - struct CompareSymbol - { - bool operator() (const CTNode* n1, const CTNode* n2) const - { - return n1->symbol() < n2->symbol(); - } - }; +typedef std::vector CTNodes; +typedef std::vector ConstraintTrees; - private: - typedef TinySet CTChilds_; - public: - CTNode (const CTNode& n, const CTChilds_& chs = CTChilds_()) - : symbol_(n.symbol()), childs_(chs), level_(n.level()) { } - - CTNode (Symbol s, unsigned l, const CTChilds_& chs = CTChilds_()) - : symbol_(s), childs_(chs), level_(l) { } - - unsigned level (void) const { return level_; } - - void setLevel (unsigned level) { level_ = level; } - - Symbol symbol (void) const { return symbol_; } - - void setSymbol (const Symbol s) { symbol_ = s; } - - CTChilds_& childs (void) { return childs_; } - - const CTChilds_& childs (void) const { return childs_; } - - size_t nrChilds (void) const { return childs_.size(); } - - bool isRoot (void) const { return level_ == 0; } - - bool isLeaf (void) const { return childs_.empty(); } - - CTChilds_::iterator findSymbol (Symbol symb) - { - CTNode tmp (symb, 0); - return childs_.find (&tmp); - } - - void mergeSubtree (CTNode*, bool = true); - - void removeChild (CTNode*); - - void removeChilds (void); - - void removeAndDeleteChild (CTNode*); - - void removeAndDeleteAllChilds (void); - - SymbolSet childSymbols (void) const; - - static CTNode* copySubtree (const CTNode*); - - static void deleteSubtree (CTNode*); - - private: - void updateChildLevels (CTNode*, unsigned); - - Symbol symbol_; - CTChilds_ childs_; - unsigned level_; - - DISALLOW_ASSIGN (CTNode); +struct CmpSymbol { + bool operator() (const CTNode* n1, const CTNode* n2) const; }; -ostream& operator<< (ostream &out, const CTNode&); + +typedef TinySet CTChilds; -typedef TinySet CTChilds; - - -class ConstraintTree -{ +class ConstraintTree { public: ConstraintTree (unsigned); @@ -106,38 +37,23 @@ class ConstraintTree ConstraintTree (const LogVars&, const Tuples&); - ConstraintTree (vector> names); + ConstraintTree (std::vector> names); ConstraintTree (const ConstraintTree&); - ConstraintTree (const CTChilds& rootChilds, const LogVars& logVars) - : root_(new CTNode (0, 0, rootChilds)), - logVars_(logVars), - logVarSet_(logVars) { } + ConstraintTree (const CTChilds& rootChilds, const LogVars& logVars); - ~ConstraintTree (void); + ~ConstraintTree(); - CTNode* root (void) const { return root_; } + CTNode* root() const { return root_; } - bool empty (void) const { return root_->childs().empty(); } + bool empty() const; - const LogVars& logVars (void) const - { - assert (LogVarSet (logVars_) == logVarSet_); - return logVars_; - } + const LogVars& logVars() const; - const LogVarSet& logVarSet (void) const - { - assert (LogVarSet (logVars_) == logVarSet_); - return logVarSet_; - } + const LogVarSet& logVarSet() const; - size_t nrLogVars (void) const - { - return logVars_.size(); - assert (LogVarSet (logVars_) == logVarSet_); - } + size_t nrLogVars() const; void addTuple (const Tuple&); @@ -163,13 +79,13 @@ class ConstraintTree bool isSingleton (LogVar); - LogVarSet singletons (void); + LogVarSet singletons(); TupleSet tupleSet (unsigned = 0) const; TupleSet tupleSet (const LogVars&); - unsigned size (void) const; + unsigned size() const; unsigned nrSymbols (LogVar); @@ -218,11 +134,10 @@ class ConstraintTree void getTuples (CTNode*, Tuples, unsigned, Tuples&, CTNodes&) const; - vector> countNormalize ( + std::vector> countNormalize ( const CTNode*, unsigned); - static void split ( - CTNode*, CTNode*, CTChilds&, CTChilds&, unsigned); + static void split (CTNode*, CTNode*, CTChilds&, CTChilds&, unsigned); CTNode* root_; LogVars logVars_; @@ -230,5 +145,33 @@ class ConstraintTree }; -#endif // HORUS_CONSTRAINTTREE_H + +inline const LogVars& +ConstraintTree::logVars() const +{ + assert (LogVarSet (logVars_) == logVarSet_); + return logVars_; +} + + + +inline const LogVarSet& +ConstraintTree::logVarSet() const +{ + assert (LogVarSet (logVars_) == logVarSet_); + return logVarSet_; +} + + + +inline size_t +ConstraintTree::nrLogVars() const +{ + assert (LogVarSet (logVars_) == logVarSet_); + return logVars_.size(); +} + +} // namespace Horus + +#endif // YAP_PACKAGES_CLPBN_HORUS_CONSTRAINTTREE_H_ diff --git a/packages/CLPBN/horus/CountingBp.cpp b/packages/CLPBN/horus/CountingBp.cpp index 4dc1b249e..05f70a7ce 100644 --- a/packages/CLPBN/horus/CountingBp.cpp +++ b/packages/CLPBN/horus/CountingBp.cpp @@ -1,7 +1,62 @@ +#include + +#include +#include + #include "CountingBp.h" #include "WeightedBp.h" +namespace Horus { + +class VarCluster { + public: + VarCluster (const VarNodes& vs) : members_(vs) { } + + const VarNode* first() const { return members_.front(); } + + const VarNodes& members() const { return members_; } + + VarNode* representative() const { return repr_; } + + void setRepresentative (VarNode* vn) { repr_ = vn; } + + private: + VarNodes members_; + VarNode* repr_; + + DISALLOW_COPY_AND_ASSIGN (VarCluster); +}; + + + +class FacCluster { + private: + typedef std::vector VarClusters; + + public: + FacCluster (const FacNodes& fcs, const VarClusters& vcs) + : members_(fcs), varClusters_(vcs) { } + + const FacNode* first() const { return members_.front(); } + + const FacNodes& members() const { return members_; } + + FacNode* representative() const { return repr_; } + + void setRepresentative (FacNode* fn) { repr_ = fn; } + + VarClusters& varClusters() { return varClusters_; } + + FacNodes members_; + FacNode* repr_; + VarClusters varClusters_; + + DISALLOW_COPY_AND_ASSIGN (FacCluster); +}; + + + bool CountingBp::fif_ = true; @@ -17,7 +72,7 @@ CountingBp::CountingBp (const FactorGraph& fg) -CountingBp::~CountingBp (void) +CountingBp::~CountingBp() { delete solver_; delete compressedFg_; @@ -32,23 +87,24 @@ CountingBp::~CountingBp (void) void -CountingBp::printSolverFlags (void) const +CountingBp::printSolverFlags() const { - stringstream ss; + std::stringstream ss; ss << "counting bp [" ; ss << "bp_msg_schedule=" ; + typedef WeightedBp::MsgSchedule MsgSchedule; switch (WeightedBp::msgSchedule()) { - case MsgSchedule::SEQ_FIXED: ss << "seq_fixed"; break; - case MsgSchedule::SEQ_RANDOM: ss << "seq_random"; break; - case MsgSchedule::PARALLEL: ss << "parallel"; break; - case MsgSchedule::MAX_RESIDUAL: ss << "max_residual"; break; + case MsgSchedule::seqFixedSch: ss << "seq_fixed"; break; + case MsgSchedule::seqRandomSch: ss << "seq_random"; break; + case MsgSchedule::parallelSch: ss << "parallel"; break; + case MsgSchedule::maxResidualSch: ss << "max_residual"; break; } ss << ",bp_max_iter=" << WeightedBp::maxIterations(); ss << ",bp_accuracy=" << WeightedBp::accuracy(); ss << ",log_domain=" << Util::toString (Globals::logDomain); ss << ",fif=" << Util::toString (CountingBp::fif_); ss << "]" ; - cout << ss.str() << endl; + std::cout << ss.str() << std::endl; } @@ -69,11 +125,10 @@ CountingBp::solveQuery (VarIds queryVids) idx = i; break; } - cout << endl; } if (idx == facNodes.size()) { res = GroundSolver::getJointByConditioning ( - GroundSolverType::CBP, fg, queryVids); + GroundSolverType::CbpSolver, fg, queryVids); } else { VarIds reprArgs; for (size_t i = 0; i < queryVids.size(); i++) { @@ -124,7 +179,7 @@ CountingBp::findIdenticalFactors() void -CountingBp::setInitialColors (void) +CountingBp::setInitialColors() { varColors_.resize (fg.nrVarNodes()); facColors_.resize (fg.nrFacNodes()); @@ -135,7 +190,7 @@ CountingBp::setInitialColors (void) unsigned range = varNodes[i]->range(); VarColorMap::iterator it = colorMap.find (range); if (it == colorMap.end()) { - it = colorMap.insert (make_pair ( + it = colorMap.insert (std::make_pair ( range, Colors (range + 1, -1))).first; } unsigned idx = varNodes[i]->hasEvidence() @@ -154,7 +209,8 @@ CountingBp::setInitialColors (void) unsigned distId = facNodes[i]->factor().distId(); DistColorMap::iterator it = distColors.find (distId); if (it == distColors.end()) { - it = distColors.insert (make_pair (distId, getNewColor())).first; + it = distColors.insert (std::make_pair ( + distId, getNewColor())).first; } setColor (facNodes[i], it->second); } @@ -163,7 +219,7 @@ CountingBp::setInitialColors (void) void -CountingBp::createGroups (void) +CountingBp::createGroups() { VarSignMap varGroups; FacSignMap facGroups; @@ -179,10 +235,11 @@ CountingBp::createGroups (void) size_t prevVarGroupsSize = varGroups.size(); varGroups.clear(); for (size_t i = 0; i < varNodes.size(); i++) { - const VarSignature& signature = getSignature (varNodes[i]); + VarSignature signature = getSignature (varNodes[i]); VarSignMap::iterator it = varGroups.find (signature); if (it == varGroups.end()) { - it = varGroups.insert (make_pair (signature, VarNodes())).first; + it = varGroups.insert (std::make_pair ( + signature, VarNodes())).first; } it->second.push_back (varNodes[i]); } @@ -199,10 +256,11 @@ CountingBp::createGroups (void) facGroups.clear(); // set a new color to the factors with the same signature for (size_t i = 0; i < facNodes.size(); i++) { - const FacSignature& signature = getSignature (facNodes[i]); + FacSignature signature = getSignature (facNodes[i]); FacSignMap::iterator it = facGroups.find (signature); if (it == facGroups.end()) { - it = facGroups.insert (make_pair (signature, FacNodes())).first; + it = facGroups.insert (std::make_pair ( + signature, FacNodes())).first; } it->second.push_back (facNodes[i]); } @@ -235,7 +293,8 @@ CountingBp::createClusters ( const VarNodes& groupVars = it->second; VarCluster* vc = new VarCluster (groupVars); for (size_t i = 0; i < groupVars.size(); i++) { - varClusterMap_.insert (make_pair (groupVars[i]->varId(), vc)); + varClusterMap_.insert (std::make_pair ( + groupVars[i]->varId(), vc)); } varClusters_.push_back (vc); } @@ -257,29 +316,29 @@ CountingBp::createClusters ( -VarSignature +CountingBp::VarSignature CountingBp::getSignature (const VarNode* varNode) { - const FacNodes& neighs = varNode->neighbors(); VarSignature sign; + const FacNodes& neighs = varNode->neighbors(); sign.reserve (neighs.size() + 1); for (size_t i = 0; i < neighs.size(); i++) { - sign.push_back (make_pair ( + sign.push_back (std::make_pair ( getColor (neighs[i]), neighs[i]->factor().indexOf (varNode->varId()))); } std::sort (sign.begin(), sign.end()); - sign.push_back (make_pair (getColor (varNode), 0)); + sign.push_back (std::make_pair (getColor (varNode), 0)); return sign; } -FacSignature +CountingBp::FacSignature CountingBp::getSignature (const FacNode* facNode) { - const VarNodes& neighs = facNode->neighbors(); FacSignature sign; + const VarNodes& neighs = facNode->neighbors(); sign.reserve (neighs.size() + 1); for (size_t i = 0; i < neighs.size(); i++) { sign.push_back (getColor (neighs[i])); @@ -314,7 +373,7 @@ CountingBp::getRepresentative (FacNode* fn) FactorGraph* -CountingBp::getCompressedFactorGraph (void) +CountingBp::getCompressedFactorGraph() { FactorGraph* fg = new FactorGraph(); for (size_t i = 0; i < varClusters_.size(); i++) { @@ -342,10 +401,10 @@ CountingBp::getCompressedFactorGraph (void) -vector> -CountingBp::getWeights (void) const +std::vector> +CountingBp::getWeights() const { - vector> weights; + std::vector> weights; weights.reserve (facClusters_.size()); for (size_t i = 0; i < facClusters_.size(); i++) { const VarClusters& neighs = facClusters_[i]->varClusters(); @@ -390,32 +449,34 @@ CountingBp::printGroups ( const FacSignMap& facGroups) const { unsigned count = 1; - cout << "variable groups:" << endl; + std::cout << "variable groups:" << std::endl; for (VarSignMap::const_iterator it = varGroups.begin(); it != varGroups.end(); ++it) { const VarNodes& groupMembers = it->second; if (groupMembers.size() > 0) { - cout << count << ": " ; + std::cout << count << ": " ; for (size_t i = 0; i < groupMembers.size(); i++) { - cout << groupMembers[i]->label() << " " ; + std::cout << groupMembers[i]->label() << " " ; } count ++; - cout << endl; + std::cout << std::endl; } } count = 1; - cout << endl << "factor groups:" << endl; + std::cout << std::endl << "factor groups:" << std::endl; for (FacSignMap::const_iterator it = facGroups.begin(); it != facGroups.end(); ++it) { const FacNodes& groupMembers = it->second; if (groupMembers.size() > 0) { - cout << ++count << ": " ; + std::cout << ++count << ": " ; for (size_t i = 0; i < groupMembers.size(); i++) { - cout << groupMembers[i]->getLabel() << " " ; + std::cout << groupMembers[i]->getLabel() << " " ; } count ++; - cout << endl; + std::cout << std::endl; } } } +} // namespace Horus + diff --git a/packages/CLPBN/horus/CountingBp.h b/packages/CLPBN/horus/CountingBp.h index 605fa8b22..2f556131e 100644 --- a/packages/CLPBN/horus/CountingBp.h +++ b/packages/CLPBN/horus/CountingBp.h @@ -1,155 +1,99 @@ -#ifndef HORUS_COUNTINGBP_H -#define HORUS_COUNTINGBP_H +#ifndef YAP_PACKAGES_CLPBN_HORUS_COUNTINGBP_H_ +#define YAP_PACKAGES_CLPBN_HORUS_COUNTINGBP_H_ +#include #include #include "GroundSolver.h" #include "FactorGraph.h" #include "Horus.h" + +namespace Horus { + class VarCluster; class FacCluster; class WeightedBp; -typedef long Color; -typedef vector Colors; -typedef vector> VarSignature; -typedef vector FacSignature; -typedef unordered_map DistColorMap; -typedef unordered_map VarColorMap; - -typedef unordered_map VarSignMap; -typedef unordered_map FacSignMap; - -typedef unordered_map VarClusterMap; - -typedef vector VarClusters; -typedef vector FacClusters; - -template -inline size_t hash_combine (size_t seed, const T& v) +template inline size_t +hash_combine (size_t seed, const T& v) { - return seed ^ (hash()(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2)); + return seed ^ (std::hash()(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2)); } +} // namespace Horus + namespace std { - template struct hash> - { - size_t operator() (const std::pair& p) const - { - return hash_combine (std::hash()(p.first), p.second); - } - }; - template struct hash> - { - size_t operator() (const std::vector& vec) const - { - size_t h = 0; - typename vector::const_iterator first = vec.begin(); - typename vector::const_iterator last = vec.end(); - for (; first != last; ++first) { - h = hash_combine (h, *first); - } - return h; - } - }; -} +template struct hash> { + size_t operator() (const std::pair& p) const { + return Horus::hash_combine (std::hash()(p.first), p.second); +}}; - -class VarCluster +template struct hash> { - public: - VarCluster (const VarNodes& vs) : members_(vs) { } - - const VarNode* first (void) const { return members_.front(); } - - const VarNodes& members (void) const { return members_; } - - VarNode* representative (void) const { return repr_; } - - void setRepresentative (VarNode* vn) { repr_ = vn; } - - private: - VarNodes members_; - VarNode* repr_; - - DISALLOW_COPY_AND_ASSIGN (VarCluster); + size_t operator() (const std::vector& vec) const + { + size_t h = 0; + typename std::vector::const_iterator first = vec.begin(); + typename std::vector::const_iterator last = vec.end(); + for (; first != last; ++first) { + h = Horus::hash_combine (h, *first); + } + return h; + } }; - -class FacCluster -{ - public: - FacCluster (const FacNodes& fcs, const VarClusters& vcs) - : members_(fcs), varClusters_(vcs) { } - - const FacNode* first (void) const { return members_.front(); } - - const FacNodes& members (void) const { return members_; } - - FacNode* representative (void) const { return repr_; } - - void setRepresentative (FacNode* fn) { repr_ = fn; } - - VarClusters& varClusters (void) { return varClusters_; } - - private: - FacNodes members_; - FacNode* repr_; - VarClusters varClusters_; - - DISALLOW_COPY_AND_ASSIGN (FacCluster); -}; +} // namespace std -class CountingBp : public GroundSolver -{ +namespace Horus { + +class CountingBp : public GroundSolver { public: CountingBp (const FactorGraph& fg); - ~CountingBp (void); + ~CountingBp(); - void printSolverFlags (void) const; + void printSolverFlags() const; Params solveQuery (VarIds); static void setFindIdenticalFactorsFlag (bool fif) { fif_ = fif; } private: - Color getNewColor (void) - { - ++ freeColor_; - return freeColor_ - 1; - } + typedef long Color; + typedef std::vector Colors; - Color getColor (const VarNode* vn) const - { - return varColors_[vn->getIndex()]; - } + typedef std::vector> VarSignature; + typedef std::vector FacSignature; - Color getColor (const FacNode* fn) const - { - return facColors_[fn->getIndex()]; - } + typedef std::vector VarClusters; + typedef std::vector FacClusters; - void setColor (const VarNode* vn, Color c) - { - varColors_[vn->getIndex()] = c; - } + typedef std::unordered_map DistColorMap; + typedef std::unordered_map VarColorMap; + typedef std::unordered_map VarSignMap; + typedef std::unordered_map FacSignMap; + typedef std::unordered_map VarClusterMap; - void setColor (const FacNode* fn, Color c) - { - facColors_[fn->getIndex()] = c; - } + Color getNewColor(); - void findIdenticalFactors (void); + Color getColor (const VarNode* vn) const; - void setInitialColors (void); + Color getColor (const FacNode* fn) const; - void createGroups (void); + void setColor (const VarNode* vn, Color c); + + void setColor (const FacNode* fn, Color c); + + void findIdenticalFactors(); + + void setInitialColors(); + + void createGroups(); void createClusters (const VarSignMap&, const FacSignMap&); @@ -163,12 +107,12 @@ class CountingBp : public GroundSolver FacNode* getRepresentative (FacNode*); - FactorGraph* getCompressedFactorGraph (void); + FactorGraph* getCompressedFactorGraph(); - vector> getWeights (void) const; + std::vector> getWeights() const; - unsigned getWeight (const FacCluster*, - const VarCluster*, size_t index) const; + unsigned getWeight (const FacCluster*, const VarCluster*, + size_t index) const; Color freeColor_; Colors varColors_; @@ -184,5 +128,48 @@ class CountingBp : public GroundSolver DISALLOW_COPY_AND_ASSIGN (CountingBp); }; -#endif // HORUS_COUNTINGBP_H + + +inline CountingBp::Color +CountingBp::getNewColor() +{ + ++ freeColor_; + return freeColor_ - 1; +} + + + +inline CountingBp::Color +CountingBp::getColor (const VarNode* vn) const +{ + return varColors_[vn->getIndex()]; +} + + + +inline CountingBp::Color +CountingBp::getColor (const FacNode* fn) const +{ + return facColors_[fn->getIndex()]; +} + + + +inline void +CountingBp::setColor (const VarNode* vn, CountingBp::Color c) +{ + varColors_[vn->getIndex()] = c; +} + + + +inline void +CountingBp::setColor (const FacNode* fn, Color c) +{ + facColors_[fn->getIndex()] = c; +} + +} // namespace Horus + +#endif // YAP_PACKAGES_CLPBN_HORUS_COUNTINGBP_H_ diff --git a/packages/CLPBN/horus/ElimGraph.cpp b/packages/CLPBN/horus/ElimGraph.cpp index 3a808a8c2..77ec5eda3 100644 --- a/packages/CLPBN/horus/ElimGraph.cpp +++ b/packages/CLPBN/horus/ElimGraph.cpp @@ -1,25 +1,30 @@ +#include #include #include "ElimGraph.h" -ElimHeuristic ElimGraph::elimHeuristic_ = MIN_NEIGHBORS; + +namespace Horus { + +ElimGraph::ElimHeuristic ElimGraph::elimHeuristic_ = + ElimHeuristic::minNeighborsEh; -ElimGraph::ElimGraph (const vector& factors) +ElimGraph::ElimGraph (const std::vector& factors) { for (size_t i = 0; i < factors.size(); i++) { if (factors[i]) { const VarIds& args = factors[i]->arguments(); for (size_t j = 0; j < args.size() - 1; j++) { - EgNode* n1 = getEgNode (args[j]); + EGNode* n1 = getEGNode (args[j]); if (!n1) { - n1 = new EgNode (args[j], factors[i]->range (j)); + n1 = new EGNode (args[j], factors[i]->range (j)); addNode (n1); } for (size_t k = j + 1; k < args.size(); k++) { - EgNode* n2 = getEgNode (args[k]); + EGNode* n2 = getEGNode (args[k]); if (!n2) { - n2 = new EgNode (args[k], factors[i]->range (k)); + n2 = new EGNode (args[k], factors[i]->range (k)); addNode (n2); } if (!neighbors (n1, n2)) { @@ -27,8 +32,8 @@ ElimGraph::ElimGraph (const vector& factors) } } } - if (args.size() == 1 && !getEgNode (args[0])) { - addNode (new EgNode (args[0], factors[i]->range (0))); + if (args.size() == 1 && !getEGNode (args[0])) { + addNode (new EGNode (args[0], factors[i]->range (0))); } } } @@ -36,7 +41,7 @@ ElimGraph::ElimGraph (const vector& factors) -ElimGraph::~ElimGraph (void) +ElimGraph::~ElimGraph() { for (size_t i = 0; i < nodes_.size(); i++) { delete nodes_[i]; @@ -57,7 +62,7 @@ ElimGraph::getEliminatingOrder (const VarIds& excludedVids) } size_t nrVarsToEliminate = nodes_.size() - excludedVids.size(); for (size_t i = 0; i < nrVarsToEliminate; i++) { - EgNode* node = getLowestCostNode(); + EGNode* node = getLowestCostNode(); unmarked_.remove (node); const EGNeighs& neighs = node->neighbors(); for (size_t j = 0; j < neighs.size(); j++) { @@ -72,15 +77,15 @@ ElimGraph::getEliminatingOrder (const VarIds& excludedVids) void -ElimGraph::print (void) const +ElimGraph::print() const { for (size_t i = 0; i < nodes_.size(); i++) { - cout << "node " << nodes_[i]->label() << " neighs:" ; + std::cout << "node " << nodes_[i]->label() << " neighs:" ; EGNeighs neighs = nodes_[i]->neighbors(); for (size_t j = 0; j < neighs.size(); j++) { - cout << " " << neighs[j]->label(); + std::cout << " " << neighs[j]->label(); } - cout << endl; + std::cout << std::endl; } } @@ -92,25 +97,27 @@ ElimGraph::exportToGraphViz ( bool showNeighborless, const VarIds& highlightVarIds) const { - ofstream out (fileName); + std::ofstream out (fileName); if (!out.is_open()) { - cerr << "Error: couldn't open file '" << fileName << "'." ; + std::cerr << "Error: couldn't open file '" << fileName << "'." ; + std::cerr << std::endl; return; } - out << "strict graph {" << endl; + out << "strict graph {" << std::endl; for (size_t i = 0; i < nodes_.size(); i++) { if (showNeighborless || nodes_[i]->neighbors().empty() == false) { - out << '"' << nodes_[i]->label() << '"' << endl; + out << '"' << nodes_[i]->label() << '"' << std::endl; } } for (size_t i = 0; i < highlightVarIds.size(); i++) { - EgNode* node =getEgNode (highlightVarIds[i]); + EGNode* node =getEGNode (highlightVarIds[i]); if (node) { out << '"' << node->label() << '"' ; - out << " [shape=box3d]" << endl; + out << " [shape=box3d]" << std::endl; } else { - cerr << "Error: invalid variable id: " << highlightVarIds[i] << "." ; - cerr << endl; + std::cerr << "Error: invalid variable id: " ; + std::cerr << highlightVarIds[i] << "." ; + std::cerr << std::endl; exit (EXIT_FAILURE); } } @@ -118,10 +125,10 @@ ElimGraph::exportToGraphViz ( EGNeighs neighs = nodes_[i]->neighbors(); for (size_t j = 0; j < neighs.size(); j++) { out << '"' << nodes_[i]->label() << '"' << " -- " ; - out << '"' << neighs[j]->label() << '"' << endl; + out << '"' << neighs[j]->label() << '"' << std::endl; } } - out << "}" << endl; + out << "}" << std::endl; out.close(); } @@ -132,7 +139,7 @@ ElimGraph::getEliminationOrder ( const Factors& factors, VarIds excludedVids) { - if (elimHeuristic_ == ElimHeuristic::SEQUENTIAL) { + if (elimHeuristic_ == ElimHeuristic::sequentialEh) { VarIds allVids; Factors::const_iterator first = factors.begin(); Factors::const_iterator end = factors.end(); @@ -150,33 +157,33 @@ ElimGraph::getEliminationOrder ( void -ElimGraph::addNode (EgNode* n) +ElimGraph::addNode (EGNode* n) { nodes_.push_back (n); n->setIndex (nodes_.size() - 1); - varMap_.insert (make_pair (n->varId(), n)); + varMap_.insert (std::make_pair (n->varId(), n)); } -EgNode* -ElimGraph::getEgNode (VarId vid) const +ElimGraph::EGNode* +ElimGraph::getEGNode (VarId vid) const { - unordered_map::const_iterator it; + std::unordered_map::const_iterator it; it = varMap_.find (vid); return (it != varMap_.end()) ? it->second : 0; } -EgNode* -ElimGraph::getLowestCostNode (void) const +ElimGraph::EGNode* +ElimGraph::getLowestCostNode() const { - EgNode* bestNode = 0; + EGNode* bestNode = 0; unsigned minCost = Util::maxUnsigned(); EGNeighs::const_iterator it; switch (elimHeuristic_) { - case MIN_NEIGHBORS: { + case ElimHeuristic::minNeighborsEh: { for (it = unmarked_.begin(); it != unmarked_.end(); ++ it) { unsigned cost = getNeighborsCost (*it); if (cost < minCost) { @@ -185,7 +192,7 @@ ElimGraph::getLowestCostNode (void) const } }} break; - case MIN_WEIGHT: { + case ElimHeuristic::minWeightEh: { for (it = unmarked_.begin(); it != unmarked_.end(); ++ it) { unsigned cost = getWeightCost (*it); if (cost < minCost) { @@ -194,7 +201,7 @@ ElimGraph::getLowestCostNode (void) const } }} break; - case MIN_FILL: { + case ElimHeuristic::minFillEh: { for (it = unmarked_.begin(); it != unmarked_.end(); ++ it) { unsigned cost = getFillCost (*it); if (cost < minCost) { @@ -203,7 +210,7 @@ ElimGraph::getLowestCostNode (void) const } }} break; - case WEIGHTED_MIN_FILL: { + case ElimHeuristic::weightedMinFillEh: { for (it = unmarked_.begin(); it != unmarked_.end(); ++ it) { unsigned cost = getWeightedFillCost (*it); if (cost < minCost) { @@ -222,7 +229,7 @@ ElimGraph::getLowestCostNode (void) const void -ElimGraph::connectAllNeighbors (const EgNode* n) +ElimGraph::connectAllNeighbors (const EGNode* n) { const EGNeighs& neighs = n->neighbors(); if (neighs.size() > 0) { @@ -236,3 +243,5 @@ ElimGraph::connectAllNeighbors (const EgNode* n) } } +} // namespace Horus + diff --git a/packages/CLPBN/horus/ElimGraph.h b/packages/CLPBN/horus/ElimGraph.h index a636d316d..3d4926288 100644 --- a/packages/CLPBN/horus/ElimGraph.h +++ b/packages/CLPBN/horus/ElimGraph.h @@ -1,143 +1,177 @@ -#ifndef HORUS_ELIMGRAPH_H -#define HORUS_ELIMGRAPH_H +#ifndef YAP_PACKAGES_CLPBN_HORUS_ELIMGRAPH_H_ +#define YAP_PACKAGES_CLPBN_HORUS_ELIMGRAPH_H_ -#include "unordered_map" +#include + +#include +#include #include "FactorGraph.h" #include "TinySet.h" #include "Horus.h" -using namespace std; -enum ElimHeuristic -{ - SEQUENTIAL, - MIN_NEIGHBORS, - MIN_WEIGHT, - MIN_FILL, - WEIGHTED_MIN_FILL -}; +namespace Horus { - -class EgNode; - -typedef TinySet EGNeighs; - - -class EgNode : public Var -{ +class ElimGraph { public: - EgNode (VarId vid, unsigned range) : Var (vid, range) { } + enum class ElimHeuristic { + sequentialEh, + minNeighborsEh, + minWeightEh, + minFillEh, + weightedMinFillEh + }; - void addNeighbor (EgNode* n) { neighs_.insert (n); } - - void removeNeighbor (EgNode* n) { neighs_.remove (n); } - - bool isNeighbor (EgNode* n) const { return neighs_.contains (n); } - - const EGNeighs& neighbors (void) const { return neighs_; } - - private: - EGNeighs neighs_; -}; - - -class ElimGraph -{ - public: ElimGraph (const Factors&); - ~ElimGraph (void); + ~ElimGraph(); VarIds getEliminatingOrder (const VarIds&); - void print (void) const; + void print() const; void exportToGraphViz (const char*, bool = true, const VarIds& = VarIds()) const; static VarIds getEliminationOrder (const Factors&, VarIds); - static ElimHeuristic elimHeuristic (void) { return elimHeuristic_; } + static ElimHeuristic elimHeuristic() { return elimHeuristic_; } static void setElimHeuristic (ElimHeuristic eh) { elimHeuristic_ = eh; } private: - void addEdge (EgNode* n1, EgNode* n2) - { - assert (n1 != n2); - n1->addNeighbor (n2); - n2->addNeighbor (n1); - } + class EGNode; - unsigned getNeighborsCost (const EgNode* n) const - { - return n->neighbors().size(); - } + typedef TinySet EGNeighs; - unsigned getWeightCost (const EgNode* n) const - { - unsigned cost = 1; - const EGNeighs& neighs = n->neighbors(); - for (size_t i = 0; i < neighs.size(); i++) { - cost *= neighs[i]->range(); - } - return cost; - } + class EGNode : public Var { + public: + EGNode (VarId vid, unsigned range) : Var (vid, range) { } - unsigned getFillCost (const EgNode* n) const - { - unsigned cost = 0; - const EGNeighs& neighs = n->neighbors(); - if (neighs.size() > 0) { - for (size_t i = 0; i < neighs.size() - 1; i++) { - for (size_t j = i + 1; j < neighs.size(); j++) { - if ( ! neighbors (neighs[i], neighs[j])) { - cost ++; - } - } - } - } - return cost; - } + void addNeighbor (EGNode* n) { neighs_.insert (n); } - unsigned getWeightedFillCost (const EgNode* n) const - { - unsigned cost = 0; - const EGNeighs& neighs = n->neighbors(); - if (neighs.size() > 0) { - for (size_t i = 0; i < neighs.size() - 1; i++) { - for (size_t j = i + 1; j < neighs.size(); j++) { - if ( ! neighbors (neighs[i], neighs[j])) { - cost += neighs[i]->range() * neighs[j]->range(); - } - } - } - } - return cost; - } + void removeNeighbor (EGNode* n) { neighs_.remove (n); } - bool neighbors (EgNode* n1, EgNode* n2) const - { - return n1->isNeighbor (n2); - } + bool isNeighbor (EGNode* n) const { return neighs_.contains (n); } - void addNode (EgNode*); + const EGNeighs& neighbors() const { return neighs_; } - EgNode* getEgNode (VarId) const; + private: + EGNeighs neighs_; + }; - EgNode* getLowestCostNode (void) const; + void addEdge (EGNode* n1, EGNode* n2); - void connectAllNeighbors (const EgNode*); + unsigned getNeighborsCost (const EGNode* n) const; - vector nodes_; - TinySet unmarked_; - unordered_map varMap_; + unsigned getWeightCost (const EGNode* n) const; + + unsigned getFillCost (const EGNode* n) const; + + unsigned getWeightedFillCost (const EGNode* n) const; + + bool neighbors (EGNode* n1, EGNode* n2) const; + + void addNode (EGNode*); + + EGNode* getEGNode (VarId) const; + + EGNode* getLowestCostNode() const; + + void connectAllNeighbors (const EGNode*); + + std::vector nodes_; + EGNeighs unmarked_; + std::unordered_map varMap_; static ElimHeuristic elimHeuristic_; DISALLOW_COPY_AND_ASSIGN (ElimGraph); }; -#endif // HORUS_ELIMGRAPH_H + + +/* Profiling shows that we should inline the following functions */ + + + +inline void +ElimGraph::addEdge (EGNode* n1, EGNode* n2) +{ + assert (n1 != n2); + n1->addNeighbor (n2); + n2->addNeighbor (n1); +} + + + +inline unsigned +ElimGraph::getNeighborsCost (const EGNode* n) const +{ + return n->neighbors().size(); +} + + + +inline unsigned +ElimGraph::getWeightCost (const EGNode* n) const +{ + unsigned cost = 1; + const EGNeighs& neighs = n->neighbors(); + for (size_t i = 0; i < neighs.size(); i++) { + cost *= neighs[i]->range(); + } + return cost; +} + + + +inline unsigned +ElimGraph::getFillCost (const EGNode* n) const +{ + unsigned cost = 0; + const EGNeighs& neighs = n->neighbors(); + if (neighs.size() > 0) { + for (size_t i = 0; i < neighs.size() - 1; i++) { + for (size_t j = i + 1; j < neighs.size(); j++) { + if ( ! neighbors (neighs[i], neighs[j])) { + cost ++; + } + } + } + } + return cost; +} + + + +inline unsigned +ElimGraph::getWeightedFillCost (const EGNode* n) const +{ + unsigned cost = 0; + const EGNeighs& neighs = n->neighbors(); + if (neighs.size() > 0) { + for (size_t i = 0; i < neighs.size() - 1; i++) { + for (size_t j = i + 1; j < neighs.size(); j++) { + if ( ! neighbors (neighs[i], neighs[j])) { + cost += neighs[i]->range() * neighs[j]->range(); + } + } + } + } + return cost; +} + + + +inline bool +ElimGraph::neighbors (EGNode* n1, EGNode* n2) const +{ + return n1->isNeighbor (n2); +} + +} // namespace Horus + +#endif // YAP_PACKAGES_CLPBN_HORUS_ELIMGRAPH_H_ diff --git a/packages/CLPBN/horus/Factor.cpp b/packages/CLPBN/horus/Factor.cpp index d0acade1f..f3fbc704b 100644 --- a/packages/CLPBN/horus/Factor.cpp +++ b/packages/CLPBN/horus/Factor.cpp @@ -1,21 +1,15 @@ -#include #include #include - #include #include #include "Factor.h" +#include "Indexer.h" #include "Var.h" -Factor::Factor (const Factor& g) -{ - clone (g); -} - - +namespace Horus { Factor::Factor ( const VarIds& vids, @@ -77,7 +71,7 @@ Factor::sumOutAllExcept (VarId vid) void Factor::sumOutAllExcept (const VarIds& vids) { - vector mask (args_.size(), false); + std::vector mask (args_.size(), false); for (unsigned i = 0; i < vids.size(); i++) { assert (indexOf (vids[i]) != args_.size()); mask[indexOf (vids[i])] = true; @@ -91,28 +85,30 @@ void Factor::sumOutAllExceptIndex (size_t idx) { assert (idx < args_.size()); - vector mask (args_.size(), false); + std::vector mask (args_.size(), false); mask[idx] = true; sumOutArgs (mask); } -void -Factor::multiply (Factor& g) + +Factor& +Factor::multiply (const Factor& g) { if (args_.empty()) { - clone (g); + operator= (g); } else { - TFactor::multiply (g); + GenericFactor::multiply (g); } + return *this; } -string -Factor::getLabel (void) const +std::string +Factor::getLabel() const { - stringstream ss; + std::stringstream ss; ss << "f(" ; for (size_t i = 0; i < args_.size(); i++) { if (i != 0) ss << "," ; @@ -125,19 +121,19 @@ Factor::getLabel (void) const void -Factor::print (void) const +Factor::print() const { Vars vars; for (size_t i = 0; i < args_.size(); i++) { vars.push_back (new Var (args_[i], ranges_[i])); } - vector jointStrings = Util::getStateLines (vars); + std::vector jointStrings = Util::getStateLines (vars); for (size_t i = 0; i < params_.size(); i++) { // cout << "[" << distId_ << "] " ; - cout << "f(" << jointStrings[i] << ")" ; - cout << " = " << params_[i] << endl; + std::cout << "f(" << jointStrings[i] << ")" ; + std::cout << " = " << params_[i] << std::endl; } - cout << endl; + std::cout << std::endl; for (size_t i = 0; i < vars.size(); i++) { delete vars[i]; } @@ -146,8 +142,9 @@ Factor::print (void) const void -Factor::sumOutFirstVariable (void) +Factor::sumOutFirstVariable() { + assert (ranges_.front() == 2); size_t sep = params_.size() / 2; if (Globals::logDomain) { std::transform ( @@ -169,19 +166,21 @@ Factor::sumOutFirstVariable (void) void -Factor::sumOutLastVariable (void) +Factor::sumOutLastVariable() { + assert (ranges_.back() == 2); Params::iterator first1 = params_.begin(); Params::iterator first2 = params_.begin(); Params::iterator last = params_.end(); if (Globals::logDomain) { while (first2 != last) { - // the arguments can be swaped, but that is ok - *first1++ = Util::logSum (*first2++, *first2++); + double tmp = *first2++; + *first1++ = Util::logSum (tmp, *first2++); } } else { while (first2 != last) { - *first1++ = (*first2++) + (*first2++); + *first1 = *first2++; + *first1++ += *first2++; } } params_.resize (params_.size() / 2); @@ -192,7 +191,7 @@ Factor::sumOutLastVariable (void) void -Factor::sumOutArgs (const vector& mask) +Factor::sumOutArgs (const std::vector& mask) { assert (mask.size() == args_.size()); size_t new_size = 1; @@ -224,14 +223,5 @@ Factor::sumOutArgs (const vector& mask) params_ = newps; } - - -void -Factor::clone (const Factor& g) -{ - args_ = g.arguments(); - ranges_ = g.ranges(); - params_ = g.params(); - distId_ = g.distId(); -} +} // namespace Horus diff --git a/packages/CLPBN/horus/Factor.h b/packages/CLPBN/horus/Factor.h index ea11d1137..1e1cb0ad1 100644 --- a/packages/CLPBN/horus/Factor.h +++ b/packages/CLPBN/horus/Factor.h @@ -1,262 +1,20 @@ -#ifndef HORUS_FACTOR_H -#define HORUS_FACTOR_H +#ifndef YAP_PACKAGES_CLPBN_HORUS_FACTOR_H_ +#define YAP_PACKAGES_CLPBN_HORUS_FACTOR_H_ + +#include #include +#include -#include "Indexer.h" +#include "GenericFactor.h" #include "Util.h" -using namespace std; +namespace Horus { - -template -class TFactor -{ +class Factor : public GenericFactor { public: - const vector& arguments (void) const { return args_; } - - vector& arguments (void) { return args_; } - - const Ranges& ranges (void) const { return ranges_; } - - const Params& params (void) const { return params_; } - - Params& params (void) { return params_; } - - size_t nrArguments (void) const { return args_.size(); } - - size_t size (void) const { return params_.size(); } - - unsigned distId (void) const { return distId_; } - - void setDistId (unsigned id) { distId_ = id; } - - void normalize (void) { LogAware::normalize (params_); } - - void randomize (void) - { - for (size_t i = 0; i < params_.size(); ++i) { - params_[i] = (double) std::rand() / RAND_MAX; - } - } - - void setParams (const Params& newParams) - { - params_ = newParams; - assert (params_.size() == Util::sizeExpected (ranges_)); - } - - size_t indexOf (const T& t) const - { - return Util::indexOf (args_, t); - } - - const T& argument (size_t idx) const - { - assert (idx < args_.size()); - return args_[idx]; - } - - T& argument (size_t idx) - { - assert (idx < args_.size()); - return args_[idx]; - } - - unsigned range (size_t idx) const - { - assert (idx < ranges_.size()); - return ranges_[idx]; - } - - void multiply (TFactor& g) - { - if (args_ == g.arguments()) { - // optimization - Globals::logDomain - ? params_ += g.params() - : params_ *= g.params(); - return; - } - unsigned range_prod = 1; - bool share_arguments = false; - const vector& g_args = g.arguments(); - const Ranges& g_ranges = g.ranges(); - const Params& g_params = g.params(); - for (size_t i = 0; i < g_args.size(); i++) { - size_t idx = indexOf (g_args[i]); - if (idx == args_.size()) { - range_prod *= g_ranges[i]; - args_.push_back (g_args[i]); - ranges_.push_back (g_ranges[i]); - } else { - share_arguments = true; - } - } - if (share_arguments == false) { - // optimization - cartesianProduct (g_params.begin(), g_params.end()); - } else { - extend (range_prod); - Params::iterator it = params_.begin(); - MapIndexer indexer (args_, ranges_, g_args, g_ranges); - if (Globals::logDomain) { - for (; indexer.valid(); ++it, ++indexer) { - *it += g_params[indexer]; - } - } else { - for (; indexer.valid(); ++it, ++indexer) { - *it *= g_params[indexer]; - } - } - } - } - - void sumOutIndex (size_t idx) - { - assert (idx < args_.size()); - assert (args_.size() > 1); - size_t new_size = params_.size() / ranges_[idx]; - Params newps (new_size, LogAware::addIdenty()); - Params::const_iterator first = params_.begin(); - Params::const_iterator last = params_.end(); - MapIndexer indexer (ranges_, idx); - if (Globals::logDomain) { - for (; first != last; ++indexer) { - newps[indexer] = Util::logSum (newps[indexer], *first++); - } - } else { - for (; first != last; ++indexer) { - newps[indexer] += *first++; - } - } - params_ = newps; - args_.erase (args_.begin() + idx); - ranges_.erase (ranges_.begin() + idx); - } - - void absorveEvidence (const T& arg, unsigned obsIdx) - { - size_t idx = indexOf (arg); - assert (idx != args_.size()); - assert (obsIdx < ranges_[idx]); - Params newps; - newps.reserve (params_.size() / ranges_[idx]); - Indexer indexer (ranges_); - for (unsigned i = 0; i < obsIdx; ++i) { - indexer.incrementDimension (idx); - } - while (indexer.valid()) { - newps.push_back (params_[indexer]); - indexer.incrementExceptDimension (idx); - } - params_ = newps; - args_.erase (args_.begin() + idx); - ranges_.erase (ranges_.begin() + idx); - } - - void reorderArguments (const vector new_args) - { - assert (new_args.size() == args_.size()); - if (new_args == args_) { - return; // already on the desired order - } - Ranges new_ranges; - for (size_t i = 0; i < new_args.size(); i++) { - size_t idx = indexOf (new_args[i]); - assert (idx != args_.size()); - new_ranges.push_back (ranges_[idx]); - } - Params newps; - newps.reserve (params_.size()); - MapIndexer indexer (new_args, new_ranges, args_, ranges_); - for (; indexer.valid(); ++indexer) { - newps.push_back (params_[indexer]); - } - params_ = newps; - args_ = new_args; - ranges_ = new_ranges; - } - - bool contains (const T& arg) const - { - return Util::contains (args_, arg); - } - - bool contains (const vector& args) const - { - for (size_t i = 0; i < args.size(); i++) { - if (contains (args[i]) == false) { - return false; - } - } - return true; - } - - double& operator[] (size_t idx) - { - assert (idx < params_.size()); - return params_[idx]; - } - - - protected: - vector args_; - Ranges ranges_; - Params params_; - unsigned distId_; - - private: - void extend (unsigned range_prod) - { - Params backup = params_; - params_.clear(); - params_.reserve (backup.size() * range_prod); - Params::const_iterator first = backup.begin(); - Params::const_iterator last = backup.end(); - for (; first != last; ++first) { - for (unsigned reps = 0; reps < range_prod; ++reps) { - params_.push_back (*first); - } - } - } - - void cartesianProduct ( - Params::const_iterator first2, - Params::const_iterator last2) - { - Params backup = params_; - params_.clear(); - params_.reserve (params_.size() * (last2 - first2)); - Params::const_iterator first1 = backup.begin(); - Params::const_iterator last1 = backup.end(); - Params::const_iterator tmp; - if (Globals::logDomain) { - for (; first1 != last1; ++first1) { - for (tmp = first2; tmp != last2; ++tmp) { - params_.push_back ((*first1) + (*tmp)); - } - } - } else { - for (; first1 != last1; ++first1) { - for (tmp = first2; tmp != last2; ++tmp) { - params_.push_back ((*first1) * (*tmp)); - } - } - } - } - -}; - - - -class Factor : public TFactor -{ - public: - Factor (void) { } - - Factor (const Factor&); + Factor() { } Factor (const VarIds&, const Ranges&, const Params&, unsigned = Util::maxUnsigned()); @@ -272,23 +30,21 @@ class Factor : public TFactor void sumOutAllExceptIndex (size_t idx); - void multiply (Factor&); + Factor& multiply (const Factor&); - string getLabel (void) const; + std::string getLabel() const; - void print (void) const; + void print() const; private: - void sumOutFirstVariable (void); + void sumOutFirstVariable(); - void sumOutLastVariable (void); + void sumOutLastVariable(); - void sumOutArgs (const vector& mask); - - void clone (const Factor& f); - - DISALLOW_ASSIGN (Factor); + void sumOutArgs (const std::vector& mask); }; -#endif // HORUS_FACTOR_H +} // namespace Horus + +#endif // YAP_PACKAGES_CLPBN_HORUS_FACTOR_H_ diff --git a/packages/CLPBN/horus/FactorGraph.cpp b/packages/CLPBN/horus/FactorGraph.cpp index 1f4c614b3..673a53035 100644 --- a/packages/CLPBN/horus/FactorGraph.cpp +++ b/packages/CLPBN/horus/FactorGraph.cpp @@ -1,17 +1,15 @@ +#include + #include - -#include -#include - #include -#include -#include #include "FactorGraph.h" #include "BayesBall.h" #include "Util.h" +namespace Horus { + bool FactorGraph::exportLd_ = false; bool FactorGraph::exportUai_ = false; bool FactorGraph::exportGv_ = false; @@ -20,25 +18,12 @@ bool FactorGraph::printFg_ = false; FactorGraph::FactorGraph (const FactorGraph& fg) { - const VarNodes& varNodes = fg.varNodes(); - for (size_t i = 0; i < varNodes.size(); i++) { - addVarNode (new VarNode (varNodes[i])); - } - const FacNodes& facNodes = fg.facNodes(); - for (size_t i = 0; i < facNodes.size(); i++) { - FacNode* facNode = new FacNode (facNodes[i]->factor()); - addFacNode (facNode); - const VarNodes& neighs = facNodes[i]->neighbors(); - for (size_t j = 0; j < neighs.size(); j++) { - addEdge (varNodes_[neighs[j]->getIndex()], facNode); - } - } - bayesFactors_ = fg.bayesianFactors(); + clone (fg); } -FactorGraph::~FactorGraph (void) +FactorGraph::~FactorGraph() { for (size_t i = 0; i < varNodes_.size(); i++) { delete varNodes_[i]; @@ -50,152 +35,6 @@ FactorGraph::~FactorGraph (void) -void -FactorGraph::readFromUaiFormat (const char* fileName) -{ - std::ifstream is (fileName); - if (!is.is_open()) { - cerr << "Error: couldn't open file '" << fileName << "'." ; - exit (EXIT_FAILURE); - } - ignoreLines (is); - string line; - getline (is, line); - if (line == "BAYES") { - bayesFactors_ = true; - } else if (line == "MARKOV") { - bayesFactors_ = false; - } else { - cerr << "Error: the type of network is missing." << endl; - exit (EXIT_FAILURE); - } - // read the number of vars - ignoreLines (is); - unsigned nrVars; - is >> nrVars; - // read the range of each var - ignoreLines (is); - Ranges ranges (nrVars); - for (unsigned i = 0; i < nrVars; i++) { - is >> ranges[i]; - } - unsigned nrFactors; - unsigned nrArgs; - unsigned vid; - is >> nrFactors; - vector allVarIds; - vector allRanges; - for (unsigned i = 0; i < nrFactors; i++) { - ignoreLines (is); - is >> nrArgs; - allVarIds.push_back ({ }); - allRanges.push_back ({ }); - for (unsigned j = 0; j < nrArgs; j++) { - is >> vid; - if (vid >= ranges.size()) { - cerr << "Error: invalid variable identifier `" << vid << "'. " ; - cerr << "Identifiers must be between 0 and " << ranges.size() - 1 ; - cerr << "." << endl; - exit (EXIT_FAILURE); - } - allVarIds.back().push_back (vid); - allRanges.back().push_back (ranges[vid]); - } - } - // read the parameters - unsigned nrParams; - for (unsigned i = 0; i < nrFactors; i++) { - ignoreLines (is); - is >> nrParams; - if (nrParams != Util::sizeExpected (allRanges[i])) { - cerr << "Error: invalid number of parameters for factor nº " << i ; - cerr << ", " << Util::sizeExpected (allRanges[i]); - cerr << " expected, " << nrParams << " given." << endl; - exit (EXIT_FAILURE); - } - Params params (nrParams); - for (unsigned j = 0; j < nrParams; j++) { - is >> params[j]; - } - if (Globals::logDomain) { - Util::log (params); - } - Factor f (allVarIds[i], allRanges[i], params); - if (bayesFactors_ && allVarIds[i].size() > 1) { - // In this format the child is the last variable, - // move it to be the first - std::swap (allVarIds[i].front(), allVarIds[i].back()); - f.reorderArguments (allVarIds[i]); - } - addFactor (f); - } - is.close(); -} - - - -void -FactorGraph::readFromLibDaiFormat (const char* fileName) -{ - std::ifstream is (fileName); - if (!is.is_open()) { - cerr << "Error: couldn't open file '" << fileName << "'." ; - exit (EXIT_FAILURE); - } - ignoreLines (is); - unsigned nrFactors; - unsigned nrArgs; - VarId vid; - is >> nrFactors; - for (unsigned i = 0; i < nrFactors; i++) { - ignoreLines (is); - // read the factor arguments - is >> nrArgs; - VarIds vids; - for (unsigned j = 0; j < nrArgs; j++) { - ignoreLines (is); - is >> vid; - vids.push_back (vid); - } - // read ranges - Ranges ranges (nrArgs); - for (unsigned j = 0; j < nrArgs; j++) { - ignoreLines (is); - is >> ranges[j]; - VarNode* var = getVarNode (vids[j]); - if (var && ranges[j] != var->range()) { - cerr << "Error: variable `" << vids[j] << "' appears in two or " ; - cerr << "more factors with a different range." << endl; - } - } - // read parameters - ignoreLines (is); - unsigned nNonzeros; - is >> nNonzeros; - Params params (Util::sizeExpected (ranges), 0); - for (unsigned j = 0; j < nNonzeros; j++) { - ignoreLines (is); - unsigned index; - is >> index; - ignoreLines (is); - double val; - is >> val; - params[index] = val; - } - if (Globals::logDomain) { - Util::log (params); - } - std::reverse (vids.begin(), vids.end()); - Factor f (vids, ranges, params); - std::reverse (vids.begin(), vids.end()); - f.reorderArguments (vids); - addFactor (f); - } - is.close(); -} - - - void FactorGraph::addFactor (const Factor& factor) { @@ -221,7 +60,7 @@ FactorGraph::addVarNode (VarNode* vn) { varNodes_.push_back (vn); vn->setIndex (varNodes_.size() - 1); - varMap_.insert (make_pair (vn->varId(), vn)); + varMap_.insert (std::make_pair (vn->varId(), vn)); } @@ -245,7 +84,7 @@ FactorGraph::addEdge (VarNode* vn, FacNode* fn) bool -FactorGraph::isTree (void) const +FactorGraph::isTree() const { return !containsCycle(); } @@ -253,7 +92,7 @@ FactorGraph::isTree (void) const BayesBallGraph& -FactorGraph::getStructure (void) +FactorGraph::getStructure() { assert (bayesFactors_); if (structure_.empty()) { @@ -273,8 +112,10 @@ FactorGraph::getStructure (void) void -FactorGraph::print (void) const +FactorGraph::print() const { + using std::cout; + using std::endl; for (size_t i = 0; i < varNodes_.size(); i++) { cout << "var id = " << varNodes_[i]->varId() << endl; cout << "label = " << varNodes_[i]->label() << endl; @@ -296,28 +137,29 @@ FactorGraph::print (void) const void FactorGraph::exportToLibDai (const char* fileName) const { - ofstream out (fileName); + std::ofstream out (fileName); if (!out.is_open()) { - cerr << "Error: couldn't open file '" << fileName << "'." ; + std::cerr << "Error: couldn't open file '" << fileName << "'." ; + std::cerr << std::endl; return; } - out << facNodes_.size() << endl << endl; + out << facNodes_.size() << std::endl << std::endl; for (size_t i = 0; i < facNodes_.size(); i++) { Factor f (facNodes_[i]->factor()); - out << f.nrArguments() << endl; - out << Util::elementsToString (f.arguments()) << endl; - out << Util::elementsToString (f.ranges()) << endl; + out << f.nrArguments() << std::endl; + out << Util::elementsToString (f.arguments()) << std::endl; + out << Util::elementsToString (f.ranges()) << std::endl; VarIds args = f.arguments(); std::reverse (args.begin(), args.end()); f.reorderArguments (args); if (Globals::logDomain) { Util::exp (f.params()); } - out << f.size() << endl; + out << f.size() << std::endl; for (size_t j = 0; j < f.size(); j++) { - out << j << " " << f[j] << endl; + out << j << " " << f[j] << std::endl; } - out << endl; + out << std::endl; } out.close(); } @@ -327,28 +169,30 @@ FactorGraph::exportToLibDai (const char* fileName) const void FactorGraph::exportToUai (const char* fileName) const { - ofstream out (fileName); + std::ofstream out (fileName); if (!out.is_open()) { - cerr << "Error: couldn't open file '" << fileName << "'." ; + std::cerr << "Error: couldn't open file '" << fileName << "'." ; + std::cerr << std::endl; return; } out << (bayesFactors_ ? "BAYES" : "MARKOV") ; - out << endl << endl; - out << varNodes_.size() << endl; + out << std::endl << std::endl; + out << varNodes_.size() << std::endl; VarNodes sortedVns = varNodes_; std::sort (sortedVns.begin(), sortedVns.end(), sortByVarId()); for (size_t i = 0; i < sortedVns.size(); i++) { out << ((i != 0) ? " " : "") << sortedVns[i]->range(); } - out << endl << facNodes_.size() << endl; + out << std::endl << facNodes_.size() << std::endl; for (size_t i = 0; i < facNodes_.size(); i++) { VarIds args = facNodes_[i]->factor().arguments(); if (bayesFactors_) { std::swap (args.front(), args.back()); } - out << args.size() << " " << Util::elementsToString (args) << endl; + out << args.size() << " " << Util::elementsToString (args); + out << std::endl; } - out << endl; + out << std::endl; for (size_t i = 0; i < facNodes_.size(); i++) { Factor f = facNodes_[i]->factor(); if (bayesFactors_) { @@ -360,8 +204,9 @@ FactorGraph::exportToUai (const char* fileName) const if (Globals::logDomain) { Util::exp (params); } - out << params.size() << endl << " " ; - out << Util::elementsToString (params) << endl << endl; + out << params.size() << std::endl << " " ; + out << Util::elementsToString (params); + out << std::endl << std::endl; } out.close(); } @@ -371,53 +216,239 @@ FactorGraph::exportToUai (const char* fileName) const void FactorGraph::exportToGraphViz (const char* fileName) const { - ofstream out (fileName); + std::ofstream out (fileName); if (!out.is_open()) { - cerr << "Error: couldn't open file '" << fileName << "'." ; + std::cerr << "Error: couldn't open file '" << fileName << "'." ; + std::cerr << std::endl; return; } - out << "graph \"" << fileName << "\" {" << endl; + out << "graph \"" << fileName << "\" {" << std::endl; for (size_t i = 0; i < varNodes_.size(); i++) { if (varNodes_[i]->hasEvidence()) { out << '"' << varNodes_[i]->label() << '"' ; - out << " [style=filled, fillcolor=yellow]" << endl; + out << " [style=filled, fillcolor=yellow]" << std::endl; } } for (size_t i = 0; i < facNodes_.size(); i++) { out << '"' << facNodes_[i]->getLabel() << '"' ; out << " [label=\"" << facNodes_[i]->getLabel(); - out << "\"" << ", shape=box]" << endl; + out << "\"" << ", shape=box]" << std::endl; } for (size_t i = 0; i < facNodes_.size(); i++) { const VarNodes& myVars = facNodes_[i]->neighbors(); for (size_t j = 0; j < myVars.size(); j++) { out << '"' << facNodes_[i]->getLabel() << '"' ; out << " -- " ; - out << '"' << myVars[j]->label() << '"' << endl; + out << '"' << myVars[j]->label() << '"' << std::endl; } } - out << "}" << endl; + out << "}" << std::endl; out.close(); } -void -FactorGraph::ignoreLines (std::ifstream& is) const +FactorGraph& +FactorGraph::operator= (const FactorGraph& fg) { - string ignoreStr; - while (is.peek() == '#' || is.peek() == '\n') { - getline (is, ignoreStr); + if (this != &fg) { + for (size_t i = 0; i < varNodes_.size(); i++) { + delete varNodes_[i]; + } + varNodes_.clear(); + for (size_t i = 0; i < facNodes_.size(); i++) { + delete facNodes_[i]; + } + facNodes_.clear(); + varMap_.clear(); + clone (fg); } + return *this; +} + + + +FactorGraph +FactorGraph::readFromUaiFormat (const char* fileName) +{ + std::ifstream is (fileName); + if (!is.is_open()) { + std::cerr << "Error: couldn't open file '" << fileName << "'." ; + std::cerr << std::endl; + exit (EXIT_FAILURE); + } + FactorGraph fg; + ignoreLines (is); + std::string line; + getline (is, line); + if (line == "BAYES") { + fg.bayesFactors_ = true; + } else if (line == "MARKOV") { + fg.bayesFactors_ = false; + } else { + std::cerr << "Error: the type of network is missing." << std::endl; + exit (EXIT_FAILURE); + } + // read the number of vars + ignoreLines (is); + unsigned nrVars; + is >> nrVars; + // read the range of each var + ignoreLines (is); + Ranges ranges (nrVars); + for (unsigned i = 0; i < nrVars; i++) { + is >> ranges[i]; + } + unsigned nrFactors; + unsigned nrArgs; + unsigned vid; + is >> nrFactors; + std::vector allVarIds; + std::vector allRanges; + for (unsigned i = 0; i < nrFactors; i++) { + ignoreLines (is); + is >> nrArgs; + allVarIds.push_back ({ }); + allRanges.push_back ({ }); + for (unsigned j = 0; j < nrArgs; j++) { + is >> vid; + if (vid >= ranges.size()) { + std::cerr << "Error: invalid variable identifier `" << vid << "'" ; + std::cerr << ". Identifiers must be between 0 and " ; + std::cerr << ranges.size() - 1 << "." << std::endl; + exit (EXIT_FAILURE); + } + allVarIds.back().push_back (vid); + allRanges.back().push_back (ranges[vid]); + } + } + // read the parameters + unsigned nrParams; + for (unsigned i = 0; i < nrFactors; i++) { + ignoreLines (is); + is >> nrParams; + if (nrParams != Util::sizeExpected (allRanges[i])) { + std::cerr << "Error: invalid number of parameters for factor nº " ; + std::cerr << i << ", " << Util::sizeExpected (allRanges[i]); + std::cerr << " expected, " << nrParams << " given." << std::endl; + exit (EXIT_FAILURE); + } + Params params (nrParams); + for (unsigned j = 0; j < nrParams; j++) { + is >> params[j]; + } + if (Globals::logDomain) { + Util::log (params); + } + Factor f (allVarIds[i], allRanges[i], params); + if (fg.bayesFactors_ && allVarIds[i].size() > 1) { + // In this format the child is the last variable, + // move it to be the first + std::swap (allVarIds[i].front(), allVarIds[i].back()); + f.reorderArguments (allVarIds[i]); + } + fg.addFactor (f); + } + is.close(); + return fg; +} + + + +FactorGraph +FactorGraph::readFromLibDaiFormat (const char* fileName) +{ + std::ifstream is (fileName); + if (!is.is_open()) { + std::cerr << "Error: couldn't open file '" << fileName << "'." ; + std::cerr << std::endl; + exit (EXIT_FAILURE); + } + FactorGraph fg; + ignoreLines (is); + unsigned nrFactors; + unsigned nrArgs; + VarId vid; + is >> nrFactors; + for (unsigned i = 0; i < nrFactors; i++) { + ignoreLines (is); + // read the factor arguments + is >> nrArgs; + VarIds vids; + for (unsigned j = 0; j < nrArgs; j++) { + ignoreLines (is); + is >> vid; + vids.push_back (vid); + } + // read ranges + Ranges ranges (nrArgs); + for (unsigned j = 0; j < nrArgs; j++) { + ignoreLines (is); + is >> ranges[j]; + VarNode* var = fg.getVarNode (vids[j]); + if (var && ranges[j] != var->range()) { + std::cerr << "Error: variable `" << vids[j] << "' appears" ; + std::cerr << " in two or more factors with a different range." ; + std::cerr << std::endl; + exit (EXIT_FAILURE); + } + } + // read parameters + ignoreLines (is); + unsigned nNonzeros; + is >> nNonzeros; + Params params (Util::sizeExpected (ranges), 0); + for (unsigned j = 0; j < nNonzeros; j++) { + ignoreLines (is); + unsigned index; + is >> index; + ignoreLines (is); + double val; + is >> val; + params[index] = val; + } + if (Globals::logDomain) { + Util::log (params); + } + std::reverse (vids.begin(), vids.end()); + std::reverse (ranges.begin(), ranges.end()); + Factor f (vids, ranges, params); + std::reverse (vids.begin(), vids.end()); + f.reorderArguments (vids); + fg.addFactor (f); + } + is.close(); + return fg; +} + + + +void +FactorGraph::clone (const FactorGraph& fg) +{ + const VarNodes& varNodes = fg.varNodes(); + for (size_t i = 0; i < varNodes.size(); i++) { + addVarNode (new VarNode (varNodes[i])); + } + const FacNodes& facNodes = fg.facNodes(); + for (size_t i = 0; i < facNodes.size(); i++) { + FacNode* facNode = new FacNode (facNodes[i]->factor()); + addFacNode (facNode); + const VarNodes& neighs = facNodes[i]->neighbors(); + for (size_t j = 0; j < neighs.size(); j++) { + addEdge (varNodes_[neighs[j]->getIndex()], facNode); + } + } + bayesFactors_ = fg.bayesianFactors(); } bool -FactorGraph::containsCycle (void) const +FactorGraph::containsCycle() const { - vector visitedVars (varNodes_.size(), false); - vector visitedFactors (facNodes_.size(), false); + std::vector visitedVars (varNodes_.size(), false); + std::vector visitedFactors (facNodes_.size(), false); for (size_t i = 0; i < varNodes_.size(); i++) { int v = varNodes_[i]->getIndex(); if (!visitedVars[v]) { @@ -435,8 +466,8 @@ bool FactorGraph::containsCycle ( const VarNode* v, const FacNode* p, - vector& visitedVars, - vector& visitedFactors) const + std::vector& visitedVars, + std::vector& visitedFactors) const { visitedVars[v->getIndex()] = true; const FacNodes& adjacencies = v->neighbors(); @@ -460,8 +491,8 @@ bool FactorGraph::containsCycle ( const FacNode* v, const VarNode* p, - vector& visitedVars, - vector& visitedFactors) const + std::vector& visitedVars, + std::vector& visitedFactors) const { visitedFactors[v->getIndex()] = true; const VarNodes& adjacencies = v->neighbors(); @@ -479,3 +510,16 @@ FactorGraph::containsCycle ( return false; // no cycle detected in this component } + + +void +FactorGraph::ignoreLines (std::ifstream& is) +{ + std::string ignoreStr; + while (is.peek() == '#' || is.peek() == '\n') { + getline (is, ignoreStr); + } +} + +} // namespace Horus + diff --git a/packages/CLPBN/horus/FactorGraph.h b/packages/CLPBN/horus/FactorGraph.h index e1cc9277c..a55135491 100644 --- a/packages/CLPBN/horus/FactorGraph.h +++ b/packages/CLPBN/horus/FactorGraph.h @@ -1,28 +1,32 @@ -#ifndef HORUS_FACTORGRAPH_H -#define HORUS_FACTORGRAPH_H +#ifndef YAP_PACKAGES_CLPBN_HORUS_FACTORGRAPH_H_ +#define YAP_PACKAGES_CLPBN_HORUS_FACTORGRAPH_H_ #include +#include +#include +#include #include "Factor.h" #include "BayesBallGraph.h" #include "Horus.h" -using namespace std; + +namespace Horus { class FacNode; -class VarNode : public Var -{ + +class VarNode : public Var { public: VarNode (VarId varId, unsigned nrStates, - int evidence = Constants::NO_EVIDENCE) + int evidence = Constants::unobserved) : Var (varId, nrStates, evidence) { } VarNode (const Var* v) : Var (v) { } void addNeighbor (FacNode* fn) { neighs_.push_back (fn); } - const FacNodes& neighbors (void) const { return neighs_; } + const FacNodes& neighbors() const { return neighs_; } private: FacNodes neighs_; @@ -32,24 +36,23 @@ class VarNode : public Var -class FacNode -{ +class FacNode { public: FacNode (const Factor& f) : factor_(f), index_(-1) { } - const Factor& factor (void) const { return factor_; } + const Factor& factor() const { return factor_; } - Factor& factor (void) { return factor_; } + Factor& factor() { return factor_; } void addNeighbor (VarNode* vn) { neighs_.push_back (vn); } - const VarNodes& neighbors (void) const { return neighs_; } + const VarNodes& neighbors() const { return neighs_; } - size_t getIndex (void) const { return index_; } + size_t getIndex() const { return index_; } void setIndex (size_t index) { index_ = index; } - string getLabel (void) { return factor_.getLabel(); } + std::string getLabel() { return factor_.getLabel(); } private: VarNodes neighs_; @@ -61,36 +64,27 @@ class FacNode -class FactorGraph -{ +class FactorGraph { public: - FactorGraph (void) : bayesFactors_(false) { } + FactorGraph() : bayesFactors_(false) { } FactorGraph (const FactorGraph&); - ~FactorGraph (void); + ~FactorGraph(); - const VarNodes& varNodes (void) const { return varNodes_; } + const VarNodes& varNodes() const { return varNodes_; } - const FacNodes& facNodes (void) const { return facNodes_; } + const FacNodes& facNodes() const { return facNodes_; } - void setFactorsAsBayesian (void) { bayesFactors_ = true; } + void setFactorsAsBayesian() { bayesFactors_ = true; } - bool bayesianFactors (void) const { return bayesFactors_; } + bool bayesianFactors() const { return bayesFactors_; } - size_t nrVarNodes (void) const { return varNodes_.size(); } + size_t nrVarNodes() const { return varNodes_.size(); } - size_t nrFacNodes (void) const { return facNodes_.size(); } + size_t nrFacNodes() const { return facNodes_.size(); } - VarNode* getVarNode (VarId vid) const - { - VarMap::const_iterator it = varMap_.find (vid); - return it != varMap_.end() ? it->second : 0; - } - - void readFromUaiFormat (const char*); - - void readFromLibDaiFormat (const char*); + VarNode* getVarNode (VarId vid) const; void addFactor (const Factor& factor); @@ -100,11 +94,11 @@ class FactorGraph void addEdge (VarNode*, FacNode*); - bool isTree (void) const; + bool isTree() const; - BayesBallGraph& getStructure (void); + BayesBallGraph& getStructure(); - void print (void) const; + void print() const; void exportToLibDai (const char*) const; @@ -112,67 +106,80 @@ class FactorGraph void exportToGraphViz (const char*) const; - static bool exportToLibDai (void) { return exportLd_; } + FactorGraph& operator= (const FactorGraph&); - static bool exportToUai (void) { return exportUai_; } + static FactorGraph readFromUaiFormat (const char*); - static bool exportGraphViz (void) { return exportGv_; } + static FactorGraph readFromLibDaiFormat (const char*); - static bool printFactorGraph (void) { return printFg_; } + static bool exportToLibDai() { return exportLd_; } - static void enableExportToLibDai (void) { exportLd_ = true; } + static bool exportToUai() { return exportUai_; } - static void disableExportToLibDai (void) { exportLd_ = false; } + static bool exportGraphViz() { return exportGv_; } - static void enableExportToUai (void) { exportUai_ = true; } + static bool printFactorGraph() { return printFg_; } - static void disableExportToUai (void) { exportUai_ = false; } + static void enableExportToLibDai() { exportLd_ = true; } - static void enableExportToGraphViz (void) { exportGv_ = true; } + static void disableExportToLibDai() { exportLd_ = false; } - static void disableExportToGraphViz (void) { exportGv_ = false; } + static void enableExportToUai() { exportUai_ = true; } - static void enablePrintFactorGraph (void) { printFg_ = true; } + static void disableExportToUai() { exportUai_ = false; } - static void disablePrintFactorGraph (void) { printFg_ = false; } + static void enableExportToGraphViz() { exportGv_ = true; } + + static void disableExportToGraphViz() { exportGv_ = false; } + + static void enablePrintFactorGraph() { printFg_ = true; } + + static void disablePrintFactorGraph() { printFg_ = false; } private: - void ignoreLines (std::ifstream&) const; + typedef std::unordered_map VarMap; - bool containsCycle (void) const; + void clone (const FactorGraph& fg); + + bool containsCycle() const; bool containsCycle (const VarNode*, const FacNode*, - vector&, vector&) const; + std::vector&, std::vector&) const; bool containsCycle (const FacNode*, const VarNode*, - vector&, vector&) const; + std::vector&, std::vector&) const; - VarNodes varNodes_; - FacNodes facNodes_; + static void ignoreLines (std::ifstream&); + VarNodes varNodes_; + FacNodes facNodes_; + VarMap varMap_; BayesBallGraph structure_; bool bayesFactors_; - typedef unordered_map VarMap; - VarMap varMap_; - - static bool exportLd_; - static bool exportUai_; - static bool exportGv_; - static bool printFg_; - - DISALLOW_ASSIGN (FactorGraph); + static bool exportLd_; + static bool exportUai_; + static bool exportGv_; + static bool printFg_; }; -struct sortByVarId +inline VarNode* +FactorGraph::getVarNode (VarId vid) const { + VarMap::const_iterator it = varMap_.find (vid); + return it != varMap_.end() ? it->second : 0; +} + + + +struct sortByVarId { bool operator()(VarNode* vn1, VarNode* vn2) { return vn1->varId() < vn2->varId(); - } -}; +}}; +} // namespace Horus -#endif // HORUS_FACTORGRAPH_H +#endif // YAP_PACKAGES_CLPBN_HORUS_FACTORGRAPH_H_ diff --git a/packages/CLPBN/horus/GenericFactor.cpp b/packages/CLPBN/horus/GenericFactor.cpp new file mode 100644 index 000000000..3d10180c2 --- /dev/null +++ b/packages/CLPBN/horus/GenericFactor.cpp @@ -0,0 +1,256 @@ +#include + +#include "GenericFactor.h" +#include "ProbFormula.h" +#include "Indexer.h" + + +namespace Horus { + +template const T& +GenericFactor::argument (size_t idx) const +{ + assert (idx < args_.size()); + return args_[idx]; +} + + + +template T& +GenericFactor::argument (size_t idx) +{ + assert (idx < args_.size()); + return args_[idx]; +} + + + +template unsigned +GenericFactor::range (size_t idx) const +{ + assert (idx < ranges_.size()); + return ranges_[idx]; +} + + + +template bool +GenericFactor::contains (const T& arg) const +{ + return Util::contains (args_, arg); +} + + + +template bool +GenericFactor::contains (const std::vector& args) const +{ + for (size_t i = 0; i < args.size(); i++) { + if (contains (args[i]) == false) { + return false; + } + } + return true; +} + + + +template void +GenericFactor::setParams (const Params& newParams) +{ + params_ = newParams; + assert (params_.size() == Util::sizeExpected (ranges_)); +} + + + +template double +GenericFactor::operator[] (size_t idx) const +{ + assert (idx < params_.size()); + return params_[idx]; +} + + + +template double& +GenericFactor::operator[] (size_t idx) +{ + assert (idx < params_.size()); + return params_[idx]; +} + + + +template GenericFactor& +GenericFactor::multiply (const GenericFactor& g) +{ + if (args_ == g.arguments()) { + // optimization + Globals::logDomain + ? params_ += g.params() + : params_ *= g.params(); + return *this; + } + unsigned range_prod = 1; + bool share_arguments = false; + const std::vector& g_args = g.arguments(); + const Ranges& g_ranges = g.ranges(); + const Params& g_params = g.params(); + for (size_t i = 0; i < g_args.size(); i++) { + size_t idx = indexOf (g_args[i]); + if (idx == args_.size()) { + range_prod *= g_ranges[i]; + args_.push_back (g_args[i]); + ranges_.push_back (g_ranges[i]); + } else { + share_arguments = true; + } + } + if (share_arguments == false) { + // optimization + cartesianProduct (g_params.begin(), g_params.end()); + } else { + extend (range_prod); + Params::iterator it = params_.begin(); + MapIndexer indexer (args_, ranges_, g_args, g_ranges); + if (Globals::logDomain) { + for (; indexer.valid(); ++it, ++indexer) { + *it += g_params[indexer]; + } + } else { + for (; indexer.valid(); ++it, ++indexer) { + *it *= g_params[indexer]; + } + } + } + return *this; +} + + + +template void +GenericFactor::sumOutIndex (size_t idx) +{ + assert (idx < args_.size()); + assert (args_.size() > 1); + size_t new_size = params_.size() / ranges_[idx]; + Params newps (new_size, LogAware::addIdenty()); + Params::const_iterator first = params_.begin(); + Params::const_iterator last = params_.end(); + MapIndexer indexer (ranges_, idx); + if (Globals::logDomain) { + for (; first != last; ++indexer) { + newps[indexer] = Util::logSum (newps[indexer], *first++); + } + } else { + for (; first != last; ++indexer) { + newps[indexer] += *first++; + } + } + params_ = newps; + args_.erase (args_.begin() + idx); + ranges_.erase (ranges_.begin() + idx); +} + + + +template void +GenericFactor::absorveEvidence (const T& arg, unsigned obsIdx) +{ + size_t idx = indexOf (arg); + assert (idx != args_.size()); + assert (obsIdx < ranges_[idx]); + Params newps; + newps.reserve (params_.size() / ranges_[idx]); + Indexer indexer (ranges_); + for (unsigned i = 0; i < obsIdx; ++i) { + indexer.incrementDimension (idx); + } + while (indexer.valid()) { + newps.push_back (params_[indexer]); + indexer.incrementExceptDimension (idx); + } + params_ = newps; + args_.erase (args_.begin() + idx); + ranges_.erase (ranges_.begin() + idx); +} + + + +template void +GenericFactor::reorderArguments (const std::vector& new_args) +{ + assert (new_args.size() == args_.size()); + if (new_args == args_) { + return; // already on the desired order + } + Ranges new_ranges; + for (size_t i = 0; i < new_args.size(); i++) { + size_t idx = indexOf (new_args[i]); + assert (idx != args_.size()); + new_ranges.push_back (ranges_[idx]); + } + Params newps; + newps.reserve (params_.size()); + MapIndexer indexer (new_args, new_ranges, args_, ranges_); + for (; indexer.valid(); ++indexer) { + newps.push_back (params_[indexer]); + } + params_ = newps; + args_ = new_args; + ranges_ = new_ranges; +} + + + +template void +GenericFactor::extend (unsigned range_prod) +{ + Params backup = params_; + params_.clear(); + params_.reserve (backup.size() * range_prod); + Params::const_iterator first = backup.begin(); + Params::const_iterator last = backup.end(); + for (; first != last; ++first) { + for (unsigned reps = 0; reps < range_prod; ++reps) { + params_.push_back (*first); + } + } +} + + + +template void +GenericFactor::cartesianProduct ( + Params::const_iterator first2, + Params::const_iterator last2) +{ + Params backup = params_; + params_.clear(); + params_.reserve (params_.size() * (last2 - first2)); + Params::const_iterator first1 = backup.begin(); + Params::const_iterator last1 = backup.end(); + Params::const_iterator tmp; + if (Globals::logDomain) { + for (; first1 != last1; ++first1) { + for (tmp = first2; tmp != last2; ++tmp) { + params_.push_back ((*first1) + (*tmp)); + } + } + } else { + for (; first1 != last1; ++first1) { + for (tmp = first2; tmp != last2; ++tmp) { + params_.push_back ((*first1) * (*tmp)); + } + } + } +} + + + +template class GenericFactor; +template class GenericFactor; + +} // namespace Horus + diff --git a/packages/CLPBN/horus/GenericFactor.h b/packages/CLPBN/horus/GenericFactor.h new file mode 100644 index 000000000..e771fa7b0 --- /dev/null +++ b/packages/CLPBN/horus/GenericFactor.h @@ -0,0 +1,76 @@ +#ifndef YAP_PACKAGES_CLPBN_HORUS_GENERICFACTOR_H_ +#define YAP_PACKAGES_CLPBN_HORUS_GENERICFACTOR_H_ + +#include + +#include "Util.h" + + +namespace Horus { + +template +class GenericFactor { + public: + const std::vector& arguments() const { return args_; } + + std::vector& arguments() { return args_; } + + const Ranges& ranges() const { return ranges_; } + + const Params& params() const { return params_; } + + Params& params() { return params_; } + + size_t nrArguments() const { return args_.size(); } + + size_t size() const { return params_.size(); } + + unsigned distId() const { return distId_; } + + void setDistId (unsigned id) { distId_ = id; } + + void normalize() { LogAware::normalize (params_); } + + size_t indexOf (const T& t) const { return Util::indexOf (args_, t); } + + const T& argument (size_t idx) const; + + T& argument (size_t idx); + + unsigned range (size_t idx) const; + + bool contains (const T& arg) const; + + bool contains (const std::vector& args) const; + + void setParams (const Params& newParams); + + double operator[] (size_t idx) const; + + double& operator[] (size_t idx); + + GenericFactor& multiply (const GenericFactor& g); + + void sumOutIndex (size_t idx); + + void absorveEvidence (const T& arg, unsigned obsIdx); + + void reorderArguments (const std::vector& new_args); + + protected: + std::vector args_; + Ranges ranges_; + Params params_; + unsigned distId_; + + private: + void extend (unsigned range_prod); + + void cartesianProduct ( + Params::const_iterator first2, Params::const_iterator last2); +}; + +} // namespace Horus + +#endif // YAP_PACKAGES_CLPBN_HORUS_GENERICFACTOR_H_ + diff --git a/packages/CLPBN/horus/GroundSolver.cpp b/packages/CLPBN/horus/GroundSolver.cpp index 1916315bb..c4ea6f50e 100644 --- a/packages/CLPBN/horus/GroundSolver.cpp +++ b/packages/CLPBN/horus/GroundSolver.cpp @@ -1,10 +1,20 @@ +#include + +#include +#include +#include +#include + #include "GroundSolver.h" #include "VarElim.h" #include "BeliefProp.h" #include "CountingBp.h" +#include "Indexer.h" #include "Util.h" +namespace Horus { + void GroundSolver::printAnswer (const VarIds& vids) { @@ -19,20 +29,21 @@ GroundSolver::printAnswer (const VarIds& vids) } if (unobservedVids.empty() == false) { Params res = solveQuery (unobservedVids); - vector stateLines = Util::getStateLines (unobservedVars); + std::vector stateLines = + Util::getStateLines (unobservedVars); for (size_t i = 0; i < res.size(); i++) { - cout << "P(" << stateLines[i] << ") = " ; - cout << std::setprecision (Constants::PRECISION) << res[i]; - cout << endl; + std::cout << "P(" << stateLines[i] << ") = " ; + std::cout << std::setprecision (Constants::precision) << res[i]; + std::cout << std::endl; } - cout << endl; + std::cout << std::endl; } } void -GroundSolver::printAllPosterioris (void) +GroundSolver::printAllPosterioris() { VarNodes vars = fg.varNodes(); std::sort (vars.begin(), vars.end(), sortByVarId()); @@ -57,9 +68,9 @@ GroundSolver::getJointByConditioning ( GroundSolver* solver = 0; switch (solverType) { - case GroundSolverType::BP: solver = new BeliefProp (fg); break; - case GroundSolverType::CBP: solver = new CountingBp (fg); break; - case GroundSolverType::VE: solver = new VarElim (fg); break; + case GroundSolverType::bpSolver: solver = new BeliefProp (fg); break; + case GroundSolverType::CbpSolver: solver = new CountingBp (fg); break; + case GroundSolverType::veSolver: solver = new VarElim (fg); break; } Params prevBeliefs = solver->solveQuery ({jointVarIds[0]}); VarIds observedVids = {jointVars[0]->varId()}; @@ -80,9 +91,9 @@ GroundSolver::getJointByConditioning ( } delete solver; switch (solverType) { - case GroundSolverType::BP: solver = new BeliefProp (fg); break; - case GroundSolverType::CBP: solver = new CountingBp (fg); break; - case GroundSolverType::VE: solver = new VarElim (fg); break; + case GroundSolverType::bpSolver: solver = new BeliefProp (fg); break; + case GroundSolverType::CbpSolver: solver = new CountingBp (fg); break; + case GroundSolverType::veSolver: solver = new VarElim (fg); break; } Params beliefs = solver->solveQuery ({jointVarIds[i]}); for (size_t k = 0; k < beliefs.size(); k++) { @@ -105,3 +116,5 @@ GroundSolver::getJointByConditioning ( return prevBeliefs; } +} // namespace Horus + diff --git a/packages/CLPBN/horus/GroundSolver.h b/packages/CLPBN/horus/GroundSolver.h index eac28b045..6c482b14c 100644 --- a/packages/CLPBN/horus/GroundSolver.h +++ b/packages/CLPBN/horus/GroundSolver.h @@ -1,16 +1,13 @@ -#ifndef HORUS_GROUNDSOLVER_H -#define HORUS_GROUNDSOLVER_H - -#include +#ifndef YAP_PACKAGES_CLPBN_HORUS_GROUNDSOLVER_H_ +#define YAP_PACKAGES_CLPBN_HORUS_GROUNDSOLVER_H_ #include "FactorGraph.h" #include "Horus.h" -using namespace std; +namespace Horus { -class GroundSolver -{ +class GroundSolver { public: GroundSolver (const FactorGraph& factorGraph) : fg(factorGraph) { } @@ -18,11 +15,11 @@ class GroundSolver virtual Params solveQuery (VarIds queryVids) = 0; - virtual void printSolverFlags (void) const = 0; + virtual void printSolverFlags() const = 0; void printAnswer (const VarIds& vids); - void printAllPosterioris (void); + void printAllPosterioris(); static Params getJointByConditioning (GroundSolverType, FactorGraph, const VarIds& jointVarIds); @@ -30,8 +27,11 @@ class GroundSolver protected: const FactorGraph& fg; + private: DISALLOW_COPY_AND_ASSIGN (GroundSolver); }; -#endif // HORUS_GROUNDSOLVER_H +} // namespace Horus + +#endif // YAP_PACKAGES_CLPBN_HORUS_GROUNDSOLVER_H_ diff --git a/packages/CLPBN/horus/Histogram.cpp b/packages/CLPBN/horus/Histogram.cpp index d5cf729e9..09f119737 100644 --- a/packages/CLPBN/horus/Histogram.cpp +++ b/packages/CLPBN/horus/Histogram.cpp @@ -7,6 +7,8 @@ #include "Util.h" +namespace Horus { + HistogramSet::HistogramSet (unsigned size, unsigned range) { size_ = size; @@ -17,7 +19,7 @@ HistogramSet::HistogramSet (unsigned size, unsigned range) void -HistogramSet::nextHistogram (void) +HistogramSet::nextHistogram() { for (size_t i = hist_.size() - 1; i-- > 0; ) { if (hist_[i] > 0) { @@ -43,7 +45,7 @@ HistogramSet::operator[] (size_t idx) const unsigned -HistogramSet::nrHistograms (void) const +HistogramSet::nrHistograms() const { return HistogramSet::nrHistograms (size_, hist_.size()); } @@ -51,7 +53,7 @@ HistogramSet::nrHistograms (void) const void -HistogramSet::reset (void) +HistogramSet::reset() { std::fill (hist_.begin() + 1, hist_.end(), 0); hist_[0] = size_; @@ -59,12 +61,12 @@ HistogramSet::reset (void) -vector +std::vector HistogramSet::getHistograms (unsigned N, unsigned R) { HistogramSet hs (N, R); unsigned H = hs.nrHistograms(); - vector histograms; + std::vector histograms; histograms.reserve (H); for (unsigned i = 0; i < H; i++) { histograms.push_back (hs.hist_); @@ -86,9 +88,9 @@ HistogramSet::nrHistograms (unsigned N, unsigned R) size_t HistogramSet::findIndex ( const Histogram& h, - const vector& hists) + const std::vector& hists) { - vector::const_iterator it = std::lower_bound ( + std::vector::const_iterator it = std::lower_bound ( hists.begin(), hists.end(), h, std::greater()); assert (it != hists.end() && *it == h); return std::distance (hists.begin(), it); @@ -96,13 +98,13 @@ HistogramSet::findIndex ( -vector +std::vector HistogramSet::getNumAssigns (unsigned N, unsigned R) { HistogramSet hs (N, R); double N_fac = Util::logFactorial (N); unsigned H = hs.nrHistograms(); - vector numAssigns; + std::vector numAssigns; numAssigns.reserve (H); for (unsigned h = 0; h < H; h++) { double prod = 0.0; @@ -118,14 +120,6 @@ HistogramSet::getNumAssigns (unsigned N, unsigned R) -ostream& operator<< (ostream &os, const HistogramSet& hs) -{ - os << "#" << hs.hist_; - return os; -} - - - unsigned HistogramSet::maxCount (size_t idx) const { @@ -144,3 +138,14 @@ HistogramSet::clearAfter (size_t idx) std::fill (hist_.begin() + idx + 1, hist_.end(), 0); } + + +std::ostream& +operator<< (std::ostream& os, const HistogramSet& hs) +{ + os << "#" << hs.hist_; + return os; +} + +} // namespace Horus + diff --git a/packages/CLPBN/horus/Histogram.h b/packages/CLPBN/horus/Histogram.h index d60c2d22f..79a821134 100644 --- a/packages/CLPBN/horus/Histogram.h +++ b/packages/CLPBN/horus/Histogram.h @@ -1,50 +1,51 @@ -#ifndef HORUS_HISTOGRAM_H -#define HORUS_HISTOGRAM_H +#ifndef YAP_PACKAGES_CLPBN_HORUS_HISTOGRAM_H_ +#define YAP_PACKAGES_CLPBN_HORUS_HISTOGRAM_H_ #include - #include #include "Horus.h" -using namespace std; +typedef std::vector Histogram; -typedef vector Histogram; -class HistogramSet -{ +namespace Horus { + +class HistogramSet { public: HistogramSet (unsigned, unsigned); - void nextHistogram (void); + void nextHistogram(); unsigned operator[] (size_t idx) const; - unsigned nrHistograms (void) const; + unsigned nrHistograms() const; - void reset (void); + void reset(); - static vector getHistograms (unsigned, unsigned); + static std::vector getHistograms (unsigned, unsigned); static unsigned nrHistograms (unsigned, unsigned); static size_t findIndex ( - const Histogram&, const vector&); + const Histogram&, const std::vector&); - static vector getNumAssigns (unsigned, unsigned); - - friend std::ostream& operator<< (ostream &os, const HistogramSet& hs); + static std::vector getNumAssigns (unsigned, unsigned); private: unsigned maxCount (size_t) const; void clearAfter (size_t); + friend std::ostream& operator<< (std::ostream&, const HistogramSet&); + unsigned size_; Histogram hist_; DISALLOW_COPY_AND_ASSIGN (HistogramSet); }; -#endif // HORUS_HISTOGRAM_H +} // namespace Horus + +#endif // YAP_PACKAGES_CLPBN_HORUS_HISTOGRAM_H_ diff --git a/packages/CLPBN/horus/Horus.h b/packages/CLPBN/horus/Horus.h index 045ca42f2..d76e82236 100644 --- a/packages/CLPBN/horus/Horus.h +++ b/packages/CLPBN/horus/Horus.h @@ -1,5 +1,5 @@ -#ifndef HORUS_HORUS_H -#define HORUS_HORUS_H +#ifndef YAP_PACKAGES_CLPBN_HORUS_HORUS_H_ +#define YAP_PACKAGES_CLPBN_HORUS_HORUS_H_ #define DISALLOW_COPY_AND_ASSIGN(TypeName) \ TypeName(const TypeName&); \ @@ -14,6 +14,9 @@ #include #include + +namespace Horus { + class Var; class Factor; class VarNode; @@ -31,19 +34,17 @@ typedef std::vector Ranges; typedef unsigned long long ullong; -enum LiftedSolverType -{ - LVE, // generalized counting first-order variable elimination (GC-FOVE) - LBP, // lifted first-order belief propagation - LKC // lifted first-order knowledge compilation +enum class LiftedSolverType { + lveSolver, // generalized counting first-order variable elimination + lbpSolver, // lifted first-order belief propagation + lkcSolver // lifted first-order knowledge compilation }; -enum GroundSolverType -{ - VE, // variable elimination - BP, // belief propagation - CBP // counting belief propagation +enum class GroundSolverType { + veSolver, // variable elimination + bpSolver, // belief propagation + CbpSolver // counting belief propagation }; @@ -57,20 +58,22 @@ extern unsigned verbosity; extern LiftedSolverType liftedSolver; extern GroundSolverType groundSolver; -}; +} namespace Constants { // show message calculation for belief propagation -const bool SHOW_BP_CALCS = false; +const bool showBpCalcs = false; -const int NO_EVIDENCE = -1; +const int unobserved = -1; // number of digits to show when printing a parameter -const unsigned PRECISION = 6; +const unsigned precision = 8; -}; +} -#endif // HORUS_HORUS_H +} // namespace Horus + +#endif // YAP_PACKAGES_CLPBN_HORUS_HORUS_H_ diff --git a/packages/CLPBN/horus/HorusCli.cpp b/packages/CLPBN/horus/HorusCli.cpp index 7fadd3d1a..a8b8f8b79 100644 --- a/packages/CLPBN/horus/HorusCli.cpp +++ b/packages/CLPBN/horus/HorusCli.cpp @@ -1,53 +1,61 @@ -#include +#include +#include #include -#include #include "FactorGraph.h" #include "VarElim.h" #include "BeliefProp.h" #include "CountingBp.h" -using namespace std; + +namespace { int readHorusFlags (int, const char* []); -void readFactorGraph (FactorGraph&, const char*); -VarIds readQueryAndEvidence (FactorGraph&, int, const char* [], int); -void runSolver (const FactorGraph&, const VarIds&); +void readFactorGraph (Horus::FactorGraph&, const char*); -const string USAGE = "usage: ./hcli [solver=hve|bp|cbp] \ +Horus::VarIds readQueryAndEvidence ( + Horus::FactorGraph&, int, const char* [], int); + +void runSolver (const Horus::FactorGraph&, const Horus::VarIds&); + +const std::string usage = "usage: ./hcli [solver=hve|bp|cbp] \ [