new version of bp
This commit is contained in:
parent
6e36498cac
commit
21d317b223
@ -8,6 +8,7 @@
|
||||
#include "xmlParser/xmlParser.h"
|
||||
|
||||
#include "BayesNet.h"
|
||||
#include "Util.h"
|
||||
|
||||
|
||||
|
||||
@ -75,7 +76,7 @@ BayesNet::readFromBifFormat (const char* fileName)
|
||||
}
|
||||
node->setParents (parents);
|
||||
unsigned count = 0;
|
||||
ParamSet params (nParams);
|
||||
Params params (nParams);
|
||||
stringstream s (def.getChildNode("TABLE").getText());
|
||||
while (!s.eof() && count < nParams) {
|
||||
s >> params[count];
|
||||
@ -93,27 +94,18 @@ BayesNet::readFromBifFormat (const char* fileName)
|
||||
}
|
||||
|
||||
setIndexes();
|
||||
if (NSPACE == NumberSpace::LOGARITHM) {
|
||||
if (Globals::logDomain) {
|
||||
distributionsToLogs();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
BayesNet::addNode (BayesNode* n)
|
||||
{
|
||||
indexMap_.insert (make_pair (n->varId(), nodes_.size()));
|
||||
nodes_.push_back (n);
|
||||
}
|
||||
|
||||
|
||||
|
||||
BayesNode*
|
||||
BayesNet::addNode (string label, const States& states)
|
||||
{
|
||||
VarId vid = nodes_.size();
|
||||
indexMap_.insert (make_pair (vid, nodes_.size()));
|
||||
varMap_.insert (make_pair (vid, nodes_.size()));
|
||||
GraphicalModel::addVariableInformation (vid, label, states);
|
||||
BayesNode* node = new BayesNode (VarNode (vid, states.size()));
|
||||
nodes_.push_back (node);
|
||||
@ -123,56 +115,20 @@ BayesNet::addNode (string label, const States& states)
|
||||
|
||||
|
||||
BayesNode*
|
||||
BayesNet::addNode (VarId vid,
|
||||
unsigned dsize,
|
||||
int evidence,
|
||||
BnNodeSet& parents,
|
||||
Distribution* dist)
|
||||
BayesNet::addNode (VarId vid, unsigned dsize, int evidence, Distribution* dist)
|
||||
{
|
||||
indexMap_.insert (make_pair (vid, nodes_.size()));
|
||||
nodes_.push_back (new BayesNode (vid, dsize, evidence, parents, dist));
|
||||
return nodes_.back();
|
||||
}
|
||||
|
||||
|
||||
|
||||
BayesNode*
|
||||
BayesNet::addNode (VarId vid,
|
||||
unsigned dsize,
|
||||
int evidence,
|
||||
Distribution* dist)
|
||||
{
|
||||
indexMap_.insert (make_pair (vid, nodes_.size()));
|
||||
varMap_.insert (make_pair (vid, nodes_.size()));
|
||||
nodes_.push_back (new BayesNode (vid, dsize, evidence, dist));
|
||||
return nodes_.back();
|
||||
}
|
||||
|
||||
|
||||
|
||||
BayesNode*
|
||||
BayesNet::addNode (string label,
|
||||
States states,
|
||||
BnNodeSet& parents,
|
||||
ParamSet& params)
|
||||
{
|
||||
VarId vid = nodes_.size();
|
||||
indexMap_.insert (make_pair (vid, nodes_.size()));
|
||||
GraphicalModel::addVariableInformation (vid, label, states);
|
||||
Distribution* dist = new Distribution (params);
|
||||
BayesNode* node = new BayesNode (
|
||||
vid, states.size(), NO_EVIDENCE, parents, dist);
|
||||
dists_.push_back (dist);
|
||||
nodes_.push_back (node);
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
|
||||
BayesNode*
|
||||
BayesNet::getBayesNode (VarId vid) const
|
||||
{
|
||||
IndexMap::const_iterator it = indexMap_.find (vid);
|
||||
if (it == indexMap_.end()) {
|
||||
IndexMap::const_iterator it = varMap_.find (vid);
|
||||
if (it == varMap_.end()) {
|
||||
return 0;
|
||||
} else {
|
||||
return nodes_[it->second];
|
||||
@ -233,7 +189,7 @@ BayesNet::getDistribution (unsigned distId) const
|
||||
{
|
||||
Distribution* dist = 0;
|
||||
for (unsigned i = 0; i < dists_.size(); i++) {
|
||||
if (dists_[i]->id == distId) {
|
||||
if (dists_[i]->id == (int) distId) {
|
||||
dist = dists_[i];
|
||||
break;
|
||||
}
|
||||
@ -290,33 +246,25 @@ BayesNet::getLeafNodes (void) const
|
||||
BayesNet*
|
||||
BayesNet::getMinimalRequesiteNetwork (VarId vid) const
|
||||
{
|
||||
return getMinimalRequesiteNetwork (VarIdSet() = {vid});
|
||||
return getMinimalRequesiteNetwork (VarIds() = {vid});
|
||||
}
|
||||
|
||||
|
||||
|
||||
BayesNet*
|
||||
BayesNet::getMinimalRequesiteNetwork (const VarIdSet& queryVarIds) const
|
||||
BayesNet::getMinimalRequesiteNetwork (const VarIds& queryVarIds) const
|
||||
{
|
||||
BnNodeSet queryVars;
|
||||
Scheduling scheduling;
|
||||
for (unsigned i = 0; i < queryVarIds.size(); i++) {
|
||||
assert (getBayesNode (queryVarIds[i]));
|
||||
queryVars.push_back (getBayesNode (queryVarIds[i]));
|
||||
BayesNode* n = getBayesNode (queryVarIds[i]);
|
||||
assert (n);
|
||||
queryVars.push_back (n);
|
||||
scheduling.push (ScheduleInfo (n, false, true));
|
||||
}
|
||||
// cout << "query vars: " ;
|
||||
// for (unsigned i = 0; i < queryVars.size(); i++) {
|
||||
// cout << queryVars[i]->label() << " " ;
|
||||
// }
|
||||
// cout << endl;
|
||||
|
||||
vector<StateInfo*> states (nodes_.size(), 0);
|
||||
|
||||
Scheduling scheduling;
|
||||
for (BnNodeSet::const_iterator it = queryVars.begin();
|
||||
it != queryVars.end(); it++) {
|
||||
scheduling.push (ScheduleInfo (*it, false, true));
|
||||
}
|
||||
|
||||
while (!scheduling.empty()) {
|
||||
ScheduleInfo& sch = scheduling.front();
|
||||
StateInfo* state = states[sch.node->getIndex()];
|
||||
@ -385,7 +333,7 @@ BayesNet::constructGraph (BayesNet* bn,
|
||||
const vector<StateInfo*>& states) const
|
||||
{
|
||||
BnNodeSet mrnNodes;
|
||||
vector<VarIdSet> parents;
|
||||
vector<VarIds> parents;
|
||||
for (unsigned i = 0; i < nodes_.size(); i++) {
|
||||
bool isRequired = false;
|
||||
if (states[i]) {
|
||||
@ -394,7 +342,7 @@ BayesNet::constructGraph (BayesNet* bn,
|
||||
states[i]->markedOnTop;
|
||||
}
|
||||
if (isRequired) {
|
||||
parents.push_back (VarIdSet());
|
||||
parents.push_back (VarIds());
|
||||
if (states[i]->markedOnTop) {
|
||||
const BnNodeSet& ps = nodes_[i]->getParents();
|
||||
for (unsigned j = 0; j < ps.size(); j++) {
|
||||
@ -473,7 +421,7 @@ BayesNet::printGraphicalModel (void) const
|
||||
void
|
||||
BayesNet::exportToGraphViz (const char* fileName,
|
||||
bool showNeighborless,
|
||||
const VarIdSet& highlightVarIds) const
|
||||
const VarIds& highlightVarIds) const
|
||||
{
|
||||
ofstream out (fileName);
|
||||
if (!out.is_open()) {
|
||||
@ -556,7 +504,7 @@ BayesNet::exportToBifFormat (const char* fileName) const
|
||||
out << "\t<GIVEN>" << parents[j]->label();
|
||||
out << "</GIVEN>" << endl;
|
||||
}
|
||||
ParamSet params = revertParameterReorder (nodes_[i]->getParameters(),
|
||||
Params params = revertParameterReorder (nodes_[i]->getParameters(),
|
||||
nodes_[i]->nrStates());
|
||||
out << "\t<TABLE>" ;
|
||||
for (unsigned j = 0; j < params.size(); j++) {
|
||||
@ -627,8 +575,8 @@ BayesNet::getAdjacentNodes (int v) const
|
||||
|
||||
|
||||
|
||||
ParamSet
|
||||
BayesNet::reorderParameters (const ParamSet& params, unsigned dsize) const
|
||||
Params
|
||||
BayesNet::reorderParameters (const Params& params, unsigned dsize) const
|
||||
{
|
||||
// the interchange format for bayesian networks keeps the probabilities
|
||||
// in the following order:
|
||||
@ -640,7 +588,7 @@ BayesNet::reorderParameters (const ParamSet& params, unsigned dsize) const
|
||||
// p(a2|b2,c1) p(a2|b2,c2).
|
||||
unsigned count = 0;
|
||||
unsigned rowSize = params.size() / dsize;
|
||||
ParamSet reordered;
|
||||
Params reordered;
|
||||
while (reordered.size() < params.size()) {
|
||||
unsigned idx = count;
|
||||
for (unsigned i = 0; i < rowSize; i++) {
|
||||
@ -654,12 +602,12 @@ BayesNet::reorderParameters (const ParamSet& params, unsigned dsize) const
|
||||
|
||||
|
||||
|
||||
ParamSet
|
||||
BayesNet::revertParameterReorder (const ParamSet& params, unsigned dsize) const
|
||||
Params
|
||||
BayesNet::revertParameterReorder (const Params& params, unsigned dsize) const
|
||||
{
|
||||
unsigned count = 0;
|
||||
unsigned rowSize = params.size() / dsize;
|
||||
ParamSet reordered;
|
||||
Params reordered;
|
||||
while (reordered.size() < params.size()) {
|
||||
unsigned idx = count;
|
||||
for (unsigned i = 0; i < dsize; i++) {
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
#include "GraphicalModel.h"
|
||||
#include "BayesNode.h"
|
||||
#include "Shared.h"
|
||||
#include "Horus.h"
|
||||
|
||||
|
||||
using namespace std;
|
||||
@ -53,11 +53,9 @@ class BayesNet : public GraphicalModel
|
||||
~BayesNet (void);
|
||||
|
||||
void readFromBifFormat (const char*);
|
||||
void addNode (BayesNode*);
|
||||
BayesNode* addNode (string, const States&);
|
||||
BayesNode* addNode (VarId, unsigned, int, BnNodeSet&, Distribution*);
|
||||
// BayesNode* addNode (VarId, unsigned, int, BnNodeSet&, Distribution*);
|
||||
BayesNode* addNode (VarId, unsigned, int, Distribution*);
|
||||
BayesNode* addNode (string, States, BnNodeSet&, ParamSet&);
|
||||
BayesNode* getBayesNode (VarId) const;
|
||||
BayesNode* getBayesNode (string) const;
|
||||
VarNode* getVariableNode (VarId) const;
|
||||
@ -69,7 +67,7 @@ class BayesNet : public GraphicalModel
|
||||
BnNodeSet getRootNodes (void) const;
|
||||
BnNodeSet getLeafNodes (void) const;
|
||||
BayesNet* getMinimalRequesiteNetwork (VarId) const;
|
||||
BayesNet* getMinimalRequesiteNetwork (const VarIdSet&) const;
|
||||
BayesNet* getMinimalRequesiteNetwork (const VarIds&) const;
|
||||
void constructGraph (
|
||||
BayesNet*, const vector<StateInfo*>&) const;
|
||||
bool isPolyTree (void) const;
|
||||
@ -78,7 +76,7 @@ class BayesNet : public GraphicalModel
|
||||
void freeDistributions (void);
|
||||
void printGraphicalModel (void) const;
|
||||
void exportToGraphViz (const char*, bool = true,
|
||||
const VarIdSet& = VarIdSet()) const;
|
||||
const VarIds& = VarIds()) const;
|
||||
void exportToBifFormat (const char*) const;
|
||||
|
||||
private:
|
||||
@ -87,8 +85,8 @@ class BayesNet : public GraphicalModel
|
||||
bool containsUndirectedCycle (void) const;
|
||||
bool containsUndirectedCycle (int, int, vector<bool>&)const;
|
||||
vector<int> getAdjacentNodes (int) const;
|
||||
ParamSet reorderParameters (const ParamSet&, unsigned) const;
|
||||
ParamSet revertParameterReorder (const ParamSet&, unsigned) const;
|
||||
Params reorderParameters (const Params&, unsigned) const;
|
||||
Params revertParameterReorder (const Params&, unsigned) const;
|
||||
void scheduleParents (const BayesNode*, Scheduling&) const;
|
||||
void scheduleChilds (const BayesNode*, Scheduling&) const;
|
||||
|
||||
@ -96,7 +94,7 @@ class BayesNet : public GraphicalModel
|
||||
DistSet dists_;
|
||||
|
||||
typedef unordered_map<unsigned, unsigned> IndexMap;
|
||||
IndexMap indexMap_;
|
||||
IndexMap varMap_;
|
||||
};
|
||||
|
||||
|
||||
|
@ -71,7 +71,7 @@ BayesNode::getDistribution (void)
|
||||
|
||||
|
||||
|
||||
const ParamSet&
|
||||
const Params&
|
||||
BayesNode::getParameters (void)
|
||||
{
|
||||
return dist_->params;
|
||||
@ -79,12 +79,12 @@ BayesNode::getParameters (void)
|
||||
|
||||
|
||||
|
||||
ParamSet
|
||||
Params
|
||||
BayesNode::getRow (int rowIndex) const
|
||||
{
|
||||
int rowSize = getRowSize();
|
||||
int offset = rowSize * rowIndex;
|
||||
ParamSet row (rowSize);
|
||||
Params row (rowSize);
|
||||
for (int i = 0; i < rowSize; i++) {
|
||||
row[i] = dist_->params[offset + i] ;
|
||||
}
|
||||
@ -124,41 +124,6 @@ BayesNode::getCptSize (void)
|
||||
|
||||
|
||||
|
||||
const vector<CptEntry>&
|
||||
BayesNode::getCptEntries (void)
|
||||
{
|
||||
if (dist_->entries.size() == 0) {
|
||||
unsigned rowSize = getRowSize();
|
||||
vector<DConf> confs (rowSize);
|
||||
|
||||
for (unsigned i = 0; i < rowSize; i++) {
|
||||
confs[i].resize (parents_.size());
|
||||
}
|
||||
|
||||
unsigned nReps = 1;
|
||||
for (int i = parents_.size() - 1; i >= 0; i--) {
|
||||
unsigned index = 0;
|
||||
while (index < rowSize) {
|
||||
for (unsigned j = 0; j < parents_[i]->nrStates(); j++) {
|
||||
for (unsigned r = 0; r < nReps; r++) {
|
||||
confs[index][i] = j;
|
||||
index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
nReps *= parents_[i]->nrStates();
|
||||
}
|
||||
|
||||
dist_->entries.reserve (rowSize);
|
||||
for (unsigned i = 0; i < rowSize; i++) {
|
||||
dist_->entries.push_back (CptEntry (i, confs[i]));
|
||||
}
|
||||
}
|
||||
return dist_->entries;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
BayesNode::getIndexOfParent (const BayesNode* parent) const
|
||||
{
|
||||
@ -173,42 +138,20 @@ BayesNode::getIndexOfParent (const BayesNode* parent) const
|
||||
|
||||
|
||||
string
|
||||
BayesNode::cptEntryToString (const CptEntry& entry) const
|
||||
BayesNode::cptEntryToString (
|
||||
int row,
|
||||
const vector<unsigned>& stateConf) const
|
||||
{
|
||||
stringstream ss;
|
||||
ss << "p(" ;
|
||||
const DConf& conf = entry.getDomainConfiguration();
|
||||
int row = entry.getParameterIndex() / getRowSize();
|
||||
ss << states()[row];
|
||||
if (parents_.size() > 0) {
|
||||
ss << "|" ;
|
||||
for (unsigned int i = 0; i < conf.size(); i++) {
|
||||
for (unsigned int i = 0; i < stateConf.size(); i++) {
|
||||
if (i != 0) {
|
||||
ss << ",";
|
||||
}
|
||||
ss << parents_[i]->states()[conf[i]];
|
||||
}
|
||||
}
|
||||
ss << ")" ;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
|
||||
|
||||
string
|
||||
BayesNode::cptEntryToString (int row, const CptEntry& entry) const
|
||||
{
|
||||
stringstream ss;
|
||||
ss << "p(" ;
|
||||
const DConf& conf = entry.getDomainConfiguration();
|
||||
ss << states()[row];
|
||||
if (parents_.size() > 0) {
|
||||
ss << "|" ;
|
||||
for (unsigned int i = 0; i < conf.size(); i++) {
|
||||
if (i != 0) {
|
||||
ss << ",";
|
||||
}
|
||||
ss << parents_[i]->states()[conf[i]];
|
||||
ss << parents_[i]->states()[stateConf[i]];
|
||||
}
|
||||
}
|
||||
ss << ")" ;
|
||||
@ -334,7 +277,7 @@ operator << (ostream& o, const BayesNode& node)
|
||||
o << endl;
|
||||
|
||||
for (unsigned int i = 0; i < states.size(); i++) {
|
||||
ParamSet row = node.getRow (i);
|
||||
Params row = node.getRow (i);
|
||||
o << left << setw (domainWidth) << states[i] << right;
|
||||
for (unsigned j = 0; j < node.getRowSize(); j++) {
|
||||
o << setw (widths[j]) << row[j];
|
||||
|
@ -4,9 +4,8 @@
|
||||
#include <vector>
|
||||
|
||||
#include "VarNode.h"
|
||||
#include "CptEntry.h"
|
||||
#include "Distribution.h"
|
||||
#include "Shared.h"
|
||||
#include "Horus.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -22,17 +21,14 @@ class BayesNode : public VarNode
|
||||
void addChild (BayesNode*);
|
||||
void setDistribution (Distribution*);
|
||||
Distribution* getDistribution (void);
|
||||
const ParamSet& getParameters (void);
|
||||
ParamSet getRow (int) const;
|
||||
void setProbability (int, const CptEntry&, double);
|
||||
const Params& getParameters (void);
|
||||
Params getRow (int) const;
|
||||
bool isRoot (void);
|
||||
bool isLeaf (void);
|
||||
bool hasNeighbors (void) const;
|
||||
int getCptSize (void);
|
||||
const vector<CptEntry>& getCptEntries (void);
|
||||
int getIndexOfParent (const BayesNode*) const;
|
||||
string cptEntryToString (const CptEntry&) const;
|
||||
string cptEntryToString (int, const CptEntry&) const;
|
||||
string cptEntryToString (int, const vector<unsigned>&) const;
|
||||
|
||||
const BnNodeSet& getParents (void) const { return parents_; }
|
||||
const BnNodeSet& getChilds (void) const { return childs_; }
|
||||
@ -42,9 +38,8 @@ class BayesNode : public VarNode
|
||||
return dist_->params.size() / nrStates();
|
||||
}
|
||||
|
||||
double getProbability (int row, const CptEntry& entry)
|
||||
double getProbability (int row, unsigned col)
|
||||
{
|
||||
int col = entry.getParameterIndex();
|
||||
int idx = (row * getRowSize()) + col;
|
||||
return dist_->params[idx];
|
||||
}
|
||||
|
@ -9,12 +9,11 @@
|
||||
#include <iomanip>
|
||||
|
||||
#include "BnBpSolver.h"
|
||||
#include "Indexer.h"
|
||||
|
||||
BnBpSolver::BnBpSolver (const BayesNet& bn) : Solver (&bn)
|
||||
{
|
||||
bayesNet_ = &bn;
|
||||
jointCalcType_ = CHAIN_RULE;
|
||||
//jointCalcType_ = JUNCTION_NODE;
|
||||
}
|
||||
|
||||
|
||||
@ -39,21 +38,18 @@ BnBpSolver::runSolver (void)
|
||||
start = clock();
|
||||
}
|
||||
initializeSolver();
|
||||
if (!BpOptions::useAlwaysLoopySolver && bayesNet_->isPolyTree()) {
|
||||
runPolyTreeSolver();
|
||||
} else {
|
||||
runLoopySolver();
|
||||
if (DL >= 2) {
|
||||
runLoopySolver();
|
||||
if (DL >= 2) {
|
||||
cout << endl;
|
||||
if (nIters_ < BpOptions::maxIter) {
|
||||
cout << "Belief propagation converged in " ;
|
||||
cout << nIters_ << " iterations" << endl;
|
||||
} else {
|
||||
cout << "The maximum number of iterations was hit, terminating..." ;
|
||||
cout << endl;
|
||||
if (nIters_ < BpOptions::maxIter) {
|
||||
cout << "Belief propagation converged in " ;
|
||||
cout << nIters_ << " iterations" << endl;
|
||||
} else {
|
||||
cout << "The maximum number of iterations was hit, terminating..." ;
|
||||
cout << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned size = bayesNet_->nrNodes();
|
||||
if (COLLECT_STATISTICS) {
|
||||
unsigned nIters = 0;
|
||||
@ -71,7 +67,7 @@ BnBpSolver::runSolver (void)
|
||||
|
||||
|
||||
|
||||
ParamSet
|
||||
Params
|
||||
BnBpSolver::getPosterioriOf (VarId vid)
|
||||
{
|
||||
BayesNode* node = bayesNet_->getBayesNode (vid);
|
||||
@ -81,8 +77,8 @@ BnBpSolver::getPosterioriOf (VarId vid)
|
||||
|
||||
|
||||
|
||||
ParamSet
|
||||
BnBpSolver::getJointDistributionOf (const VarIdSet& jointVarIds)
|
||||
Params
|
||||
BnBpSolver::getJointDistributionOf (const VarIds& jointVarIds)
|
||||
{
|
||||
if (DL >= 2) {
|
||||
cout << "calculating joint distribution on: " ;
|
||||
@ -92,12 +88,7 @@ BnBpSolver::getJointDistributionOf (const VarIdSet& jointVarIds)
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
if (jointCalcType_ == JUNCTION_NODE) {
|
||||
return getJointByJunctionNode (jointVarIds);
|
||||
} else {
|
||||
return getJointByChainRule (jointVarIds);
|
||||
}
|
||||
return getJointByConditioning (jointVarIds);
|
||||
}
|
||||
|
||||
|
||||
@ -121,8 +112,8 @@ BnBpSolver::initializeSolver (void)
|
||||
|
||||
BnNodeSet roots = bayesNet_->getRootNodes();
|
||||
for (unsigned i = 0; i < roots.size(); i++) {
|
||||
const ParamSet& params = roots[i]->getParameters();
|
||||
ParamSet& piVals = ninf(roots[i])->getPiValues();
|
||||
const Params& params = roots[i]->getParameters();
|
||||
Params& piVals = ninf(roots[i])->getPiValues();
|
||||
for (unsigned ri = 0; ri < roots[i]->nrStates(); ri++) {
|
||||
piVals[ri] = params[ri];
|
||||
}
|
||||
@ -149,8 +140,8 @@ BnBpSolver::initializeSolver (void)
|
||||
|
||||
for (unsigned i = 0; i < nodes.size(); i++) {
|
||||
if (nodes[i]->hasEvidence()) {
|
||||
ParamSet& piVals = ninf(nodes[i])->getPiValues();
|
||||
ParamSet& ldVals = ninf(nodes[i])->getLambdaValues();
|
||||
Params& piVals = ninf(nodes[i])->getPiValues();
|
||||
Params& ldVals = ninf(nodes[i])->getLambdaValues();
|
||||
for (unsigned xi = 0; xi < nodes[i]->nrStates(); xi++) {
|
||||
piVals[xi] = Util::noEvidence();
|
||||
ldVals[xi] = Util::noEvidence();
|
||||
@ -163,76 +154,6 @@ BnBpSolver::initializeSolver (void)
|
||||
|
||||
|
||||
|
||||
void
|
||||
BnBpSolver::runPolyTreeSolver (void)
|
||||
{
|
||||
const BnNodeSet& nodes = bayesNet_->getBayesNodes();
|
||||
for (unsigned i = 0; i < nodes.size(); i++) {
|
||||
if (nodes[i]->isRoot()) {
|
||||
ninf(nodes[i])->markPiValuesAsCalculated();
|
||||
}
|
||||
if (nodes[i]->isLeaf()) {
|
||||
ninf(nodes[i])->markLambdaValuesAsCalculated();
|
||||
}
|
||||
}
|
||||
|
||||
bool finish = false;
|
||||
while (!finish) {
|
||||
finish = true;
|
||||
for (unsigned i = 0; i < nodes.size(); i++) {
|
||||
if (ninf(nodes[i])->piValuesCalculated() == false
|
||||
&& ninf(nodes[i])->receivedAllPiMessages()) {
|
||||
if (!nodes[i]->hasEvidence()) {
|
||||
updatePiValues (nodes[i]);
|
||||
}
|
||||
ninf(nodes[i])->markPiValuesAsCalculated();
|
||||
finish = false;
|
||||
}
|
||||
|
||||
if (ninf(nodes[i])->lambdaValuesCalculated() == false
|
||||
&& ninf(nodes[i])->receivedAllLambdaMessages()) {
|
||||
if (!nodes[i]->hasEvidence()) {
|
||||
updateLambdaValues (nodes[i]);
|
||||
}
|
||||
ninf(nodes[i])->markLambdaValuesAsCalculated();
|
||||
finish = false;
|
||||
}
|
||||
|
||||
if (ninf(nodes[i])->piValuesCalculated()) {
|
||||
const BpLinkSet& outChildLinks
|
||||
= ninf(nodes[i])->getOutcomingChildLinks();
|
||||
for (unsigned j = 0; j < outChildLinks.size(); j++) {
|
||||
BayesNode* child = outChildLinks[j]->getDestination();
|
||||
if (!outChildLinks[j]->messageWasSended()) {
|
||||
if (ninf(nodes[i])->readyToSendPiMsgTo (child)) {
|
||||
calculateAndUpdateMessage (outChildLinks[j], false);
|
||||
ninf(child)->incNumPiMsgsReceived();
|
||||
}
|
||||
finish = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ninf(nodes[i])->lambdaValuesCalculated()) {
|
||||
const BpLinkSet& outParentLinks =
|
||||
ninf(nodes[i])->getOutcomingParentLinks();
|
||||
for (unsigned j = 0; j < outParentLinks.size(); j++) {
|
||||
BayesNode* parent = outParentLinks[j]->getDestination();
|
||||
if (!outParentLinks[j]->messageWasSended()) {
|
||||
if (ninf(nodes[i])->readyToSendLambdaMsgTo (parent)) {
|
||||
calculateAndUpdateMessage (outParentLinks[j], false);
|
||||
ninf(parent)->incNumLambdaMsgsReceived();
|
||||
}
|
||||
finish = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
BnBpSolver::runLoopySolver()
|
||||
{
|
||||
@ -298,7 +219,7 @@ BnBpSolver::converged (void) const
|
||||
}
|
||||
bool converged = true;
|
||||
if (BpOptions::schedule == BpOptions::Schedule::MAX_RESIDUAL) {
|
||||
Param maxResidual = (*(sortedOrder_.begin()))->getResidual();
|
||||
double maxResidual = (*(sortedOrder_.begin()))->getResidual();
|
||||
if (maxResidual < BpOptions::accuracy) {
|
||||
converged = true;
|
||||
} else {
|
||||
@ -306,7 +227,7 @@ BnBpSolver::converged (void) const
|
||||
}
|
||||
} else {
|
||||
for (unsigned i = 0; i < links_.size(); i++) {
|
||||
Param residual = links_[i]->getResidual();
|
||||
double residual = links_[i]->getResidual();
|
||||
if (DL >= 2) {
|
||||
cout << links_[i]->toString() + " residual change = " ;
|
||||
cout << residual << endl;
|
||||
@ -395,36 +316,38 @@ BnBpSolver::updatePiValues (BayesNode* x)
|
||||
if (DL >= 3) {
|
||||
cout << "updating " << PI_SYMBOL << " values for " << x->label() << endl;
|
||||
}
|
||||
ParamSet& piValues = ninf(x)->getPiValues();
|
||||
const BpLinkSet& parentLinks = ninf(x)->getIncomingParentLinks();
|
||||
const vector<CptEntry>& entries = x->getCptEntries();
|
||||
Params& piValues = ninf(x)->getPiValues();
|
||||
const BpLinkSet& parentLinks = ninf(x)->getIncomingParentLinks();
|
||||
const BnNodeSet& ps = x->getParents();
|
||||
Ranges ranges;
|
||||
for (unsigned i = 0; i < ps.size(); i++) {
|
||||
ranges.push_back (ps[i]->nrStates());
|
||||
}
|
||||
StatesIndexer indexer (ranges, false);
|
||||
stringstream* calcs1 = 0;
|
||||
stringstream* calcs2 = 0;
|
||||
|
||||
ParamSet messageProducts (entries.size());
|
||||
for (unsigned k = 0; k < entries.size(); k++) {
|
||||
Params messageProducts (indexer.size());
|
||||
for (unsigned k = 0; k < indexer.size(); k++) {
|
||||
if (DL >= 5) {
|
||||
calcs1 = new stringstream;
|
||||
calcs2 = new stringstream;
|
||||
}
|
||||
double messageProduct = Util::multIdenty();
|
||||
const DConf& conf = entries[k].getDomainConfiguration();
|
||||
switch (NSPACE) {
|
||||
case NumberSpace::NORMAL:
|
||||
for (unsigned i = 0; i < parentLinks.size(); i++) {
|
||||
messageProduct *= parentLinks[i]->getMessage()[conf[i]];
|
||||
if (DL >= 5) {
|
||||
if (i != 0) *calcs1 << " + " ;
|
||||
if (i != 0) *calcs2 << " + " ;
|
||||
*calcs1 << parentLinks[i]->toString (conf[i]);
|
||||
*calcs2 << parentLinks[i]->getMessage()[conf[i]];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NumberSpace::LOGARITHM:
|
||||
for (unsigned i = 0; i < parentLinks.size(); i++) {
|
||||
messageProduct += parentLinks[i]->getMessage()[conf[i]];
|
||||
if (Globals::logDomain) {
|
||||
for (unsigned i = 0; i < parentLinks.size(); i++) {
|
||||
messageProduct += parentLinks[i]->getMessage()[indexer[i]];
|
||||
}
|
||||
} else {
|
||||
for (unsigned i = 0; i < parentLinks.size(); i++) {
|
||||
messageProduct *= parentLinks[i]->getMessage()[indexer[i]];
|
||||
if (DL >= 5) {
|
||||
if (i != 0) *calcs1 << " + " ;
|
||||
if (i != 0) *calcs2 << " + " ;
|
||||
*calcs1 << parentLinks[i]->toString (indexer[i]);
|
||||
*calcs2 << parentLinks[i]->getMessage()[indexer[i]];
|
||||
}
|
||||
}
|
||||
}
|
||||
messageProducts[k] = messageProduct;
|
||||
if (DL >= 5) {
|
||||
@ -439,6 +362,7 @@ BnBpSolver::updatePiValues (BayesNode* x)
|
||||
delete calcs1;
|
||||
delete calcs2;
|
||||
}
|
||||
++ indexer;
|
||||
}
|
||||
|
||||
for (unsigned xi = 0; xi < x->nrStates(); xi++) {
|
||||
@ -447,26 +371,28 @@ BnBpSolver::updatePiValues (BayesNode* x)
|
||||
calcs1 = new stringstream;
|
||||
calcs2 = new stringstream;
|
||||
}
|
||||
switch (NSPACE) {
|
||||
case NumberSpace::NORMAL:
|
||||
for (unsigned k = 0; k < entries.size(); k++) {
|
||||
sum += x->getProbability (xi, entries[k]) * messageProducts[k];
|
||||
if (DL >= 5) {
|
||||
if (k != 0) *calcs1 << " + " ;
|
||||
if (k != 0) *calcs2 << " + " ;
|
||||
*calcs1 << x->cptEntryToString (xi, entries[k]);
|
||||
*calcs1 << ".mp" << k;
|
||||
*calcs2 << Util::fl (x->getProbability (xi, entries[k]));
|
||||
*calcs2 << "*" << messageProducts[k];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NumberSpace::LOGARITHM:
|
||||
for (unsigned k = 0; k < entries.size(); k++) {
|
||||
Util::logSum (sum,
|
||||
x->getProbability(xi,entries[k]) + messageProducts[k]);
|
||||
indexer.reset();
|
||||
if (Globals::logDomain) {
|
||||
for (unsigned k = 0; k < indexer.size(); k++) {
|
||||
Util::logSum (sum,
|
||||
x->getProbability(xi, indexer.linearIndex()) + messageProducts[k]);
|
||||
++ indexer;
|
||||
}
|
||||
} else {
|
||||
for (unsigned k = 0; k < indexer.size(); k++) {
|
||||
sum += x->getProbability (xi, indexer.linearIndex()) * messageProducts[k];
|
||||
if (DL >= 5) {
|
||||
if (k != 0) *calcs1 << " + " ;
|
||||
if (k != 0) *calcs2 << " + " ;
|
||||
*calcs1 << x->cptEntryToString (xi, indexer.indices());
|
||||
*calcs1 << ".mp" << k;
|
||||
*calcs2 << Util::fl (x->getProbability (xi, indexer.linearIndex()));
|
||||
*calcs2 << "*" << messageProducts[k];
|
||||
}
|
||||
++ indexer;
|
||||
}
|
||||
}
|
||||
|
||||
piValues[xi] = sum;
|
||||
if (DL >= 5) {
|
||||
cout << " " << PI_SYMBOL << "(" << x->label() << ")" ;
|
||||
@ -489,7 +415,7 @@ BnBpSolver::updateLambdaValues (BayesNode* x)
|
||||
if (DL >= 3) {
|
||||
cout << "updating " << LD_SYMBOL << " values for " << x->label() << endl;
|
||||
}
|
||||
ParamSet& lambdaValues = ninf(x)->getLambdaValues();
|
||||
Params& lambdaValues = ninf(x)->getLambdaValues();
|
||||
const BpLinkSet& childLinks = ninf(x)->getIncomingChildLinks();
|
||||
stringstream* calcs1 = 0;
|
||||
stringstream* calcs2 = 0;
|
||||
@ -500,22 +426,20 @@ BnBpSolver::updateLambdaValues (BayesNode* x)
|
||||
calcs2 = new stringstream;
|
||||
}
|
||||
double product = Util::multIdenty();
|
||||
switch (NSPACE) {
|
||||
case NumberSpace::NORMAL:
|
||||
for (unsigned i = 0; i < childLinks.size(); i++) {
|
||||
product *= childLinks[i]->getMessage()[xi];
|
||||
if (DL >= 5) {
|
||||
if (i != 0) *calcs1 << "." ;
|
||||
if (i != 0) *calcs2 << "*" ;
|
||||
*calcs1 << childLinks[i]->toString (xi);
|
||||
*calcs2 << childLinks[i]->getMessage()[xi];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NumberSpace::LOGARITHM:
|
||||
for (unsigned i = 0; i < childLinks.size(); i++) {
|
||||
product += childLinks[i]->getMessage()[xi];
|
||||
if (Globals::logDomain) {
|
||||
for (unsigned i = 0; i < childLinks.size(); i++) {
|
||||
product += childLinks[i]->getMessage()[xi];
|
||||
}
|
||||
} else {
|
||||
for (unsigned i = 0; i < childLinks.size(); i++) {
|
||||
product *= childLinks[i]->getMessage()[xi];
|
||||
if (DL >= 5) {
|
||||
if (i != 0) *calcs1 << "." ;
|
||||
if (i != 0) *calcs2 << "*" ;
|
||||
*calcs1 << childLinks[i]->toString (xi);
|
||||
*calcs2 << childLinks[i]->getMessage()[xi];
|
||||
}
|
||||
}
|
||||
}
|
||||
lambdaValues[xi] = product;
|
||||
if (DL >= 5) {
|
||||
@ -542,12 +466,12 @@ BnBpSolver::calculatePiMessage (BpLink* link)
|
||||
// πX(Zi)
|
||||
BayesNode* z = link->getSource();
|
||||
BayesNode* x = link->getDestination();
|
||||
ParamSet& zxPiNextMessage = link->getNextMessage();
|
||||
Params& zxPiNextMessage = link->getNextMessage();
|
||||
const BpLinkSet& zChildLinks = ninf(z)->getIncomingChildLinks();
|
||||
stringstream* calcs1 = 0;
|
||||
stringstream* calcs2 = 0;
|
||||
|
||||
const ParamSet& zPiValues = ninf(z)->getPiValues();
|
||||
const Params& zPiValues = ninf(z)->getPiValues();
|
||||
for (unsigned zi = 0; zi < z->nrStates(); zi++) {
|
||||
double product = zPiValues[zi];
|
||||
if (DL >= 5) {
|
||||
@ -557,24 +481,22 @@ BnBpSolver::calculatePiMessage (BpLink* link)
|
||||
*calcs1 << "[" << z->states()[zi] << "]" ;
|
||||
*calcs2 << product;
|
||||
}
|
||||
switch (NSPACE) {
|
||||
case NumberSpace::NORMAL:
|
||||
for (unsigned i = 0; i < zChildLinks.size(); i++) {
|
||||
if (zChildLinks[i]->getSource() != x) {
|
||||
product *= zChildLinks[i]->getMessage()[zi];
|
||||
if (DL >= 5) {
|
||||
*calcs1 << "." << zChildLinks[i]->toString (zi);
|
||||
*calcs2 << " * " << zChildLinks[i]->getMessage()[zi];
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NumberSpace::LOGARITHM:
|
||||
for (unsigned i = 0; i < zChildLinks.size(); i++) {
|
||||
if (zChildLinks[i]->getSource() != x) {
|
||||
product += zChildLinks[i]->getMessage()[zi];
|
||||
if (Globals::logDomain) {
|
||||
for (unsigned i = 0; i < zChildLinks.size(); i++) {
|
||||
if (zChildLinks[i]->getSource() != x) {
|
||||
product += zChildLinks[i]->getMessage()[zi];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (unsigned i = 0; i < zChildLinks.size(); i++) {
|
||||
if (zChildLinks[i]->getSource() != x) {
|
||||
product *= zChildLinks[i]->getMessage()[zi];
|
||||
if (DL >= 5) {
|
||||
*calcs1 << "." << zChildLinks[i]->toString (zi);
|
||||
*calcs2 << " * " << zChildLinks[i]->getMessage()[zi];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
zxPiNextMessage[zi] = product;
|
||||
if (DL >= 5) {
|
||||
@ -605,52 +527,53 @@ BnBpSolver::calculateLambdaMessage (BpLink* link)
|
||||
if (x->hasEvidence()) {
|
||||
return;
|
||||
}
|
||||
ParamSet& yxLambdaNextMessage = link->getNextMessage();
|
||||
Params& yxLambdaNextMessage = link->getNextMessage();
|
||||
const BpLinkSet& yParentLinks = ninf(y)->getIncomingParentLinks();
|
||||
const ParamSet& yLambdaValues = ninf(y)->getLambdaValues();
|
||||
const vector<CptEntry>& allEntries = y->getCptEntries();
|
||||
const Params& yLambdaValues = ninf(y)->getLambdaValues();
|
||||
int parentIndex = y->getIndexOfParent (x);
|
||||
stringstream* calcs1 = 0;
|
||||
stringstream* calcs2 = 0;
|
||||
|
||||
vector<CptEntry> entries;
|
||||
DConstraint constr = make_pair (parentIndex, 0);
|
||||
for (unsigned i = 0; i < allEntries.size(); i++) {
|
||||
if (allEntries[i].matchConstraints(constr)) {
|
||||
entries.push_back (allEntries[i]);
|
||||
}
|
||||
}
|
||||
|
||||
ParamSet messageProducts (entries.size());
|
||||
for (unsigned k = 0; k < entries.size(); k++) {
|
||||
const BnNodeSet& ps = y->getParents();
|
||||
Ranges ranges;
|
||||
for (unsigned i = 0; i < ps.size(); i++) {
|
||||
ranges.push_back (ps[i]->nrStates());
|
||||
}
|
||||
StatesIndexer indexer (ranges, false);
|
||||
|
||||
|
||||
unsigned N = indexer.size() / x->nrStates();
|
||||
Params messageProducts (N);
|
||||
for (unsigned k = 0; k < N; k++) {
|
||||
while (indexer[parentIndex] != 0) {
|
||||
++ indexer;
|
||||
}
|
||||
if (DL >= 5) {
|
||||
calcs1 = new stringstream;
|
||||
calcs2 = new stringstream;
|
||||
}
|
||||
double messageProduct = Util::multIdenty();
|
||||
const DConf& conf = entries[k].getDomainConfiguration();
|
||||
switch (NSPACE) {
|
||||
case NumberSpace::NORMAL:
|
||||
for (unsigned i = 0; i < yParentLinks.size(); i++) {
|
||||
if (yParentLinks[i]->getSource() != x) {
|
||||
if (DL >= 5) {
|
||||
if (messageProduct != Util::multIdenty()) *calcs1 << "*" ;
|
||||
if (messageProduct != Util::multIdenty()) *calcs2 << "*" ;
|
||||
*calcs1 << yParentLinks[i]->toString (conf[i]);
|
||||
*calcs2 << yParentLinks[i]->getMessage()[conf[i]];
|
||||
}
|
||||
messageProduct *= yParentLinks[i]->getMessage()[conf[i]];
|
||||
}
|
||||
if (Globals::logDomain) {
|
||||
for (unsigned i = 0; i < yParentLinks.size(); i++) {
|
||||
if (yParentLinks[i]->getSource() != x) {
|
||||
messageProduct += yParentLinks[i]->getMessage()[indexer[i]];
|
||||
}
|
||||
break;
|
||||
case NumberSpace::LOGARITHM:
|
||||
for (unsigned i = 0; i < yParentLinks.size(); i++) {
|
||||
if (yParentLinks[i]->getSource() != x) {
|
||||
messageProduct += yParentLinks[i]->getMessage()[conf[i]];
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (unsigned i = 0; i < yParentLinks.size(); i++) {
|
||||
if (yParentLinks[i]->getSource() != x) {
|
||||
if (DL >= 5) {
|
||||
if (messageProduct != Util::multIdenty()) *calcs1 << "*" ;
|
||||
if (messageProduct != Util::multIdenty()) *calcs2 << "*" ;
|
||||
*calcs1 << yParentLinks[i]->toString (indexer[i]);
|
||||
*calcs2 << yParentLinks[i]->getMessage()[indexer[i]];
|
||||
}
|
||||
messageProduct *= yParentLinks[i]->getMessage()[indexer[i]];
|
||||
}
|
||||
}
|
||||
}
|
||||
messageProducts[k] = messageProduct;
|
||||
++ indexer;
|
||||
if (DL >= 5) {
|
||||
cout << " mp" << k;
|
||||
cout << " = " << (*calcs1).str();
|
||||
@ -672,13 +595,6 @@ BnBpSolver::calculateLambdaMessage (BpLink* link)
|
||||
calcs1 = new stringstream;
|
||||
calcs2 = new stringstream;
|
||||
}
|
||||
vector<CptEntry> entries;
|
||||
DConstraint constr = make_pair (parentIndex, xi);
|
||||
for (unsigned i = 0; i < allEntries.size(); i++) {
|
||||
if (allEntries[i].matchConstraints(constr)) {
|
||||
entries.push_back (allEntries[i]);
|
||||
}
|
||||
}
|
||||
double outerSum = Util::addIdenty();
|
||||
for (unsigned yi = 0; yi < y->nrStates(); yi++) {
|
||||
if (DL >= 5) {
|
||||
@ -686,27 +602,35 @@ BnBpSolver::calculateLambdaMessage (BpLink* link)
|
||||
(yi != 0) ? *calcs2 << " + {" : *calcs2 << "{" ;
|
||||
}
|
||||
double innerSum = Util::addIdenty();
|
||||
switch (NSPACE) {
|
||||
case NumberSpace::NORMAL:
|
||||
for (unsigned k = 0; k < entries.size(); k++) {
|
||||
if (DL >= 5) {
|
||||
if (k != 0) *calcs1 << " + " ;
|
||||
if (k != 0) *calcs2 << " + " ;
|
||||
*calcs1 << y->cptEntryToString (yi, entries[k]);
|
||||
*calcs1 << ".mp" << k;
|
||||
*calcs2 << y->getProbability (yi, entries[k]);
|
||||
*calcs2 << "*" << messageProducts[k];
|
||||
}
|
||||
innerSum += y->getProbability (yi, entries[k]) * messageProducts[k];
|
||||
indexer.reset();
|
||||
if (Globals::logDomain) {
|
||||
for (unsigned k = 0; k < N; k++) {
|
||||
while (indexer[parentIndex] != xi) {
|
||||
++ indexer;
|
||||
}
|
||||
outerSum += innerSum * yLambdaValues[yi];
|
||||
break;
|
||||
case NumberSpace::LOGARITHM:
|
||||
for (unsigned k = 0; k < entries.size(); k++) {
|
||||
Util::logSum (innerSum,
|
||||
y->getProbability(yi, entries[k]) + messageProducts[k]);
|
||||
}
|
||||
Util::logSum (outerSum, innerSum + yLambdaValues[yi]);
|
||||
Util::logSum (innerSum, y->getProbability (
|
||||
yi, indexer.linearIndex()) + messageProducts[k]);
|
||||
++ indexer;
|
||||
}
|
||||
Util::logSum (outerSum, innerSum + yLambdaValues[yi]);
|
||||
} else {
|
||||
for (unsigned k = 0; k < N; k++) {
|
||||
while (indexer[parentIndex] != xi) {
|
||||
++ indexer;
|
||||
}
|
||||
if (DL >= 5) {
|
||||
if (k != 0) *calcs1 << " + " ;
|
||||
if (k != 0) *calcs2 << " + " ;
|
||||
*calcs1 << y->cptEntryToString (yi, indexer.indices());
|
||||
*calcs1 << ".mp" << k;
|
||||
*calcs2 << y->getProbability (yi, indexer.linearIndex());
|
||||
*calcs2 << "*" << messageProducts[k];
|
||||
}
|
||||
innerSum += y->getProbability (
|
||||
yi, indexer.linearIndex()) * messageProducts[k];
|
||||
++ indexer;
|
||||
}
|
||||
outerSum += innerSum * yLambdaValues[yi];
|
||||
}
|
||||
if (DL >= 5) {
|
||||
*calcs1 << "}." << LD_SYMBOL << "(" << y->label() << ")" ;
|
||||
@ -730,62 +654,45 @@ BnBpSolver::calculateLambdaMessage (BpLink* link)
|
||||
|
||||
|
||||
|
||||
ParamSet
|
||||
BnBpSolver::getJointByJunctionNode (const VarIdSet& jointVarIds)
|
||||
{
|
||||
unsigned msgSize = 1;
|
||||
vector<unsigned> dsizes (jointVarIds.size());
|
||||
for (unsigned i = 0; i < jointVarIds.size(); i++) {
|
||||
dsizes[i] = bayesNet_->getBayesNode (jointVarIds[i])->nrStates();
|
||||
msgSize *= dsizes[i];
|
||||
}
|
||||
unsigned reps = 1;
|
||||
ParamSet jointDist (msgSize, Util::multIdenty());
|
||||
for (int i = jointVarIds.size() - 1 ; i >= 0; i--) {
|
||||
Util::multiply (jointDist, getPosterioriOf (jointVarIds[i]), reps);
|
||||
reps *= dsizes[i] ;
|
||||
}
|
||||
return jointDist;
|
||||
}
|
||||
|
||||
|
||||
|
||||
ParamSet
|
||||
BnBpSolver::getJointByChainRule (const VarIdSet& jointVarIds) const
|
||||
Params
|
||||
BnBpSolver::getJointByConditioning (const VarIds& jointVarIds) const
|
||||
{
|
||||
BnNodeSet jointVars;
|
||||
for (unsigned i = 0; i < jointVarIds.size(); i++) {
|
||||
assert (bayesNet_->getBayesNode (jointVarIds[i]));
|
||||
jointVars.push_back (bayesNet_->getBayesNode (jointVarIds[i]));
|
||||
}
|
||||
|
||||
BayesNet* mrn = bayesNet_->getMinimalRequesiteNetwork (jointVarIds[0]);
|
||||
BnBpSolver solver (*mrn);
|
||||
solver.runSolver();
|
||||
ParamSet prevBeliefs = solver.getPosterioriOf (jointVarIds[0]);
|
||||
Params prevBeliefs = solver.getPosterioriOf (jointVarIds[0]);
|
||||
delete mrn;
|
||||
|
||||
VarNodes observedVars = {jointVars[0]};
|
||||
VarIds observedVids = {jointVars[0]->varId()};
|
||||
|
||||
for (unsigned i = 1; i < jointVarIds.size(); i++) {
|
||||
mrn = bayesNet_->getMinimalRequesiteNetwork (jointVarIds[i]);
|
||||
ParamSet newBeliefs;
|
||||
vector<DConf> confs =
|
||||
Util::getDomainConfigurations (observedVars);
|
||||
for (unsigned j = 0; j < confs.size(); j++) {
|
||||
for (unsigned k = 0; k < observedVars.size(); k++) {
|
||||
if (!observedVars[k]->hasEvidence()) {
|
||||
BayesNode* node = mrn->getBayesNode (observedVars[k]->varId());
|
||||
if (node) {
|
||||
node->setEvidence (confs[j][k]);
|
||||
}
|
||||
}
|
||||
assert (jointVars[i]->hasEvidence() == false);
|
||||
VarIds reqVars = {jointVarIds[i]};
|
||||
reqVars.insert (reqVars.end(), observedVids.begin(), observedVids.end());
|
||||
mrn = bayesNet_->getMinimalRequesiteNetwork (reqVars);
|
||||
Params newBeliefs;
|
||||
VarNodes observedVars;
|
||||
for (unsigned j = 0; j < observedVids.size(); j++) {
|
||||
observedVars.push_back (mrn->getBayesNode (observedVids[j]));
|
||||
}
|
||||
StatesIndexer idx (observedVars, false);
|
||||
while (idx.valid()) {
|
||||
for (unsigned j = 0; j < observedVars.size(); j++) {
|
||||
observedVars[j]->setEvidence (idx[j]);
|
||||
}
|
||||
BnBpSolver solver (*mrn);
|
||||
solver.runSolver();
|
||||
ParamSet beliefs = solver.getPosterioriOf (jointVarIds[i]);
|
||||
Params beliefs = solver.getPosterioriOf (jointVarIds[i]);
|
||||
for (unsigned k = 0; k < beliefs.size(); k++) {
|
||||
newBeliefs.push_back (beliefs[k]);
|
||||
}
|
||||
++ idx;
|
||||
}
|
||||
|
||||
int count = -1;
|
||||
@ -796,7 +703,7 @@ BnBpSolver::getJointByChainRule (const VarIdSet& jointVarIds) const
|
||||
newBeliefs[j] *= prevBeliefs[count];
|
||||
}
|
||||
prevBeliefs = newBeliefs;
|
||||
observedVars.push_back (jointVars[i]);
|
||||
observedVids.push_back (jointVars[i]->varId());
|
||||
delete mrn;
|
||||
}
|
||||
return prevBeliefs;
|
||||
@ -817,9 +724,9 @@ BnBpSolver::printPiLambdaValues (const BayesNode* var) const
|
||||
cout << "--------------------------------" ;
|
||||
cout << endl;
|
||||
const States& states = var->states();
|
||||
const ParamSet& piVals = ninf(var)->getPiValues();
|
||||
const ParamSet& ldVals = ninf(var)->getLambdaValues();
|
||||
const ParamSet& beliefs = ninf(var)->getBeliefs();
|
||||
const Params& piVals = ninf(var)->getPiValues();
|
||||
const Params& ldVals = ninf(var)->getLambdaValues();
|
||||
const Params& beliefs = ninf(var)->getBeliefs();
|
||||
for (unsigned xi = 0; xi < var->nrStates(); xi++) {
|
||||
cout << setw (10) << states[xi];
|
||||
cout << setw (19) << piVals[xi];
|
||||
@ -847,33 +754,27 @@ BnBpSolver::printAllMessageStatus (void) const
|
||||
BpNodeInfo::BpNodeInfo (BayesNode* node)
|
||||
{
|
||||
node_ = node;
|
||||
piValsCalc_ = false;
|
||||
ldValsCalc_ = false;
|
||||
nPiMsgsRcv_ = 0;
|
||||
nLdMsgsRcv_ = 0;
|
||||
piVals_.resize (node->nrStates(), Util::one());
|
||||
ldVals_.resize (node->nrStates(), Util::one());
|
||||
}
|
||||
|
||||
|
||||
|
||||
ParamSet
|
||||
Params
|
||||
BpNodeInfo::getBeliefs (void) const
|
||||
{
|
||||
double sum = 0.0;
|
||||
ParamSet beliefs (node_->nrStates());
|
||||
switch (NSPACE) {
|
||||
case NumberSpace::NORMAL:
|
||||
for (unsigned xi = 0; xi < node_->nrStates(); xi++) {
|
||||
beliefs[xi] = piVals_[xi] * ldVals_[xi];
|
||||
sum += beliefs[xi];
|
||||
}
|
||||
break;
|
||||
case NumberSpace::LOGARITHM:
|
||||
for (unsigned xi = 0; xi < node_->nrStates(); xi++) {
|
||||
beliefs[xi] = exp (piVals_[xi] + ldVals_[xi]);
|
||||
sum += beliefs[xi];
|
||||
}
|
||||
Params beliefs (node_->nrStates());
|
||||
if (Globals::logDomain) {
|
||||
for (unsigned xi = 0; xi < node_->nrStates(); xi++) {
|
||||
beliefs[xi] = exp (piVals_[xi] + ldVals_[xi]);
|
||||
sum += beliefs[xi];
|
||||
}
|
||||
} else {
|
||||
for (unsigned xi = 0; xi < node_->nrStates(); xi++) {
|
||||
beliefs[xi] = piVals_[xi] * ldVals_[xi];
|
||||
sum += beliefs[xi];
|
||||
}
|
||||
}
|
||||
assert (sum);
|
||||
for (unsigned xi = 0; xi < node_->nrStates(); xi++) {
|
||||
@ -884,66 +785,6 @@ BpNodeInfo::getBeliefs (void) const
|
||||
|
||||
|
||||
|
||||
void
|
||||
BpNodeInfo::markPiValuesAsCalculated (void)
|
||||
{
|
||||
piValsCalc_ = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
BpNodeInfo::markLambdaValuesAsCalculated (void)
|
||||
{
|
||||
ldValsCalc_ = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
BpNodeInfo::receivedAllPiMessages (void)
|
||||
{
|
||||
return node_->getParents().size() == nPiMsgsRcv_;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
BpNodeInfo::receivedAllLambdaMessages (void)
|
||||
{
|
||||
return node_->getChilds().size() == nLdMsgsRcv_;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
BpNodeInfo::readyToSendPiMsgTo (const BayesNode* child) const
|
||||
{
|
||||
for (unsigned i = 0; i < inChildLinks_.size(); i++) {
|
||||
if (inChildLinks_[i]->getSource() != child
|
||||
&& inChildLinks_[i]->messageWasSended() == false) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
BpNodeInfo::readyToSendLambdaMsgTo (const BayesNode* parent) const
|
||||
{
|
||||
for (unsigned i = 0; i < inParentLinks_.size(); i++) {
|
||||
if (inParentLinks_[i]->getSource() != parent
|
||||
&& inParentLinks_[i]->messageWasSended() == false) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
BpNodeInfo::receivedBottomInfluence (void) const
|
||||
{
|
||||
|
@ -6,7 +6,8 @@
|
||||
|
||||
#include "Solver.h"
|
||||
#include "BayesNet.h"
|
||||
#include "Shared.h"
|
||||
#include "Horus.h"
|
||||
#include "Util.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -16,7 +17,6 @@ static const string PI_SYMBOL = "pi" ;
|
||||
static const string LD_SYMBOL = "ld" ;
|
||||
|
||||
enum LinkOrientation {UP, DOWN};
|
||||
enum JointCalcType {CHAIN_RULE, JUNCTION_NODE};
|
||||
|
||||
class BpLink
|
||||
{
|
||||
@ -27,11 +27,11 @@ class BpLink
|
||||
destin_ = d;
|
||||
orientation_ = o;
|
||||
if (orientation_ == LinkOrientation::DOWN) {
|
||||
v1_.resize (s->nrStates(), Util::tl (1.0/s->nrStates()));
|
||||
v2_.resize (s->nrStates(), Util::tl (1.0/s->nrStates()));
|
||||
v1_.resize (s->nrStates(), Util::tl (1.0 / s->nrStates()));
|
||||
v2_.resize (s->nrStates(), Util::tl (1.0 / s->nrStates()));
|
||||
} else {
|
||||
v1_.resize (d->nrStates(), Util::tl (1.0/d->nrStates()));
|
||||
v2_.resize (d->nrStates(), Util::tl (1.0/d->nrStates()));
|
||||
v1_.resize (d->nrStates(), Util::tl (1.0 / d->nrStates()));
|
||||
v2_.resize (d->nrStates(), Util::tl (1.0 / d->nrStates()));
|
||||
}
|
||||
currMsg_ = &v1_;
|
||||
nextMsg_ = &v2_;
|
||||
@ -78,8 +78,8 @@ class BpLink
|
||||
BayesNode* getSource (void) const { return source_; }
|
||||
BayesNode* getDestination (void) const { return destin_; }
|
||||
LinkOrientation getOrientation (void) const { return orientation_; }
|
||||
const ParamSet& getMessage (void) const { return *currMsg_; }
|
||||
ParamSet& getNextMessage (void) { return *nextMsg_; }
|
||||
const Params& getMessage (void) const { return *currMsg_; }
|
||||
Params& getNextMessage (void) { return *nextMsg_; }
|
||||
bool messageWasSended (void) const { return msgSended_; }
|
||||
double getResidual (void) const { return residual_; }
|
||||
void clearResidual (void) { residual_ = 0;}
|
||||
@ -88,10 +88,10 @@ class BpLink
|
||||
BayesNode* source_;
|
||||
BayesNode* destin_;
|
||||
LinkOrientation orientation_;
|
||||
ParamSet v1_;
|
||||
ParamSet v2_;
|
||||
ParamSet* currMsg_;
|
||||
ParamSet* nextMsg_;
|
||||
Params v1_;
|
||||
Params v2_;
|
||||
Params* currMsg_;
|
||||
Params* nextMsg_;
|
||||
bool msgSended_;
|
||||
double residual_;
|
||||
};
|
||||
@ -105,22 +105,11 @@ class BpNodeInfo
|
||||
public:
|
||||
BpNodeInfo (BayesNode*);
|
||||
|
||||
ParamSet getBeliefs (void) const;
|
||||
Params getBeliefs (void) const;
|
||||
bool receivedBottomInfluence (void) const;
|
||||
|
||||
ParamSet& getPiValues (void) { return piVals_; }
|
||||
ParamSet& getLambdaValues (void) { return ldVals_; }
|
||||
void incNumPiMsgsReceived (void) { nPiMsgsRcv_ ++; }
|
||||
void incNumLambdaMsgsReceived (void) { nLdMsgsRcv_ ++; }
|
||||
bool piValuesCalculated (void) { return piValsCalc_; }
|
||||
bool lambdaValuesCalculated (void) { return ldValsCalc_; }
|
||||
|
||||
void markPiValuesAsCalculated (void);
|
||||
void markLambdaValuesAsCalculated (void);
|
||||
bool receivedAllPiMessages (void);
|
||||
bool receivedAllLambdaMessages (void);
|
||||
bool readyToSendPiMsgTo (const BayesNode*) const ;
|
||||
bool readyToSendLambdaMsgTo (const BayesNode*) const;
|
||||
Params& getPiValues (void) { return piVals_; }
|
||||
Params& getLambdaValues (void) { return ldVals_; }
|
||||
|
||||
const BpLinkSet& getIncomingParentLinks (void) { return inParentLinks_; }
|
||||
const BpLinkSet& getIncomingChildLinks (void) { return inChildLinks_; }
|
||||
@ -135,17 +124,13 @@ class BpNodeInfo
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN (BpNodeInfo);
|
||||
|
||||
ParamSet piVals_; // pi values
|
||||
ParamSet ldVals_; // lambda values
|
||||
unsigned nPiMsgsRcv_;
|
||||
unsigned nLdMsgsRcv_;
|
||||
bool piValsCalc_;
|
||||
bool ldValsCalc_;
|
||||
const BayesNode* node_;
|
||||
Params piVals_; // pi values
|
||||
Params ldVals_; // lambda values
|
||||
BpLinkSet inParentLinks_;
|
||||
BpLinkSet inChildLinks_;
|
||||
BpLinkSet outParentLinks_;
|
||||
BpLinkSet outChildLinks_;
|
||||
const BayesNode* node_;
|
||||
};
|
||||
|
||||
|
||||
@ -157,15 +142,14 @@ class BnBpSolver : public Solver
|
||||
~BnBpSolver (void);
|
||||
|
||||
void runSolver (void);
|
||||
ParamSet getPosterioriOf (VarId);
|
||||
ParamSet getJointDistributionOf (const VarIdSet&);
|
||||
Params getPosterioriOf (VarId);
|
||||
Params getJointDistributionOf (const VarIds&);
|
||||
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN (BnBpSolver);
|
||||
|
||||
void initializeSolver (void);
|
||||
void runPolyTreeSolver (void);
|
||||
void runLoopySolver (void);
|
||||
void maxResidualSchedule (void);
|
||||
bool converged (void) const;
|
||||
@ -173,8 +157,8 @@ class BnBpSolver : public Solver
|
||||
void updateLambdaValues (BayesNode*);
|
||||
void calculateLambdaMessage (BpLink*);
|
||||
void calculatePiMessage (BpLink*);
|
||||
ParamSet getJointByJunctionNode (const VarIdSet&);
|
||||
ParamSet getJointByChainRule (const VarIdSet&) const;
|
||||
Params getJointByJunctionNode (const VarIds&);
|
||||
Params getJointByConditioning (const VarIds&) const;
|
||||
void printPiLambdaValues (const BayesNode*) const;
|
||||
void printAllMessageStatus (void) const;
|
||||
|
||||
@ -240,7 +224,6 @@ class BnBpSolver : public Solver
|
||||
vector<BpLink*> links_;
|
||||
vector<BpNodeInfo*> nodesI_;
|
||||
unsigned nIters_;
|
||||
JointCalcType jointCalcType_;
|
||||
|
||||
struct compare
|
||||
{
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include "Distribution.h"
|
||||
|
||||
|
||||
bool CFactorGraph::checkForIdenticalFactors_ = true;
|
||||
bool CFactorGraph::checkForIdenticalFactors = true;
|
||||
|
||||
CFactorGraph::CFactorGraph (const FactorGraph& fg)
|
||||
{
|
||||
@ -38,8 +38,8 @@ CFactorGraph::~CFactorGraph (void)
|
||||
for (unsigned i = 0; i < varClusters_.size(); i++) {
|
||||
delete varClusters_[i];
|
||||
}
|
||||
for (unsigned i = 0; i < factorClusters_.size(); i++) {
|
||||
delete factorClusters_[i];
|
||||
for (unsigned i = 0; i < facClusters_.size(); i++) {
|
||||
delete facClusters_[i];
|
||||
}
|
||||
}
|
||||
|
||||
@ -72,33 +72,17 @@ CFactorGraph::setInitialColors (void)
|
||||
}
|
||||
|
||||
const FgFacSet& facNodes = groundFg_->getFactorNodes();
|
||||
if (checkForIdenticalFactors_) {
|
||||
for (unsigned i = 0; i < facNodes.size() - 1; i++) {
|
||||
// facNodes[i]->factor()->orderFactorVariables();
|
||||
// FIXME
|
||||
}
|
||||
if (checkForIdenticalFactors) {
|
||||
for (unsigned i = 0, s = facNodes.size(); i < s; i++) {
|
||||
Distribution* dist1 = facNodes[i]->getDistribution();
|
||||
for (unsigned j = 0; j < i; j++) {
|
||||
Distribution* dist2 = facNodes[j]->getDistribution();
|
||||
if (dist1 != dist2 && dist1->params == dist2->params) {
|
||||
facNodes[i]->factor()->setDistribution (dist2);
|
||||
// delete dist2;
|
||||
break;
|
||||
}
|
||||
/*
|
||||
if (ok) {
|
||||
const FgVarSet& fiVars = factors[i]->getFgVarNodes();
|
||||
const FgVarSet& fjVars = factors[j]->getFgVarNodes();
|
||||
if (fiVars.size() != fjVars.size()) continue;
|
||||
for (unsigned k = 0; k < fiVars.size(); k++) {
|
||||
if (fiVars[k]->nrStates() != fjVars[k]->nrStates()) {
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
if (facNodes[i]->factor()->getRanges() ==
|
||||
facNodes[j]->factor()->getRanges()) {
|
||||
facNodes[i]->factor()->setDistribution (dist2);
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -194,7 +178,7 @@ CFactorGraph::createClusters (const VarSignMap& varGroups,
|
||||
varClusters_.push_back (vc);
|
||||
}
|
||||
|
||||
factorClusters_.reserve (factorGroups.size());
|
||||
facClusters_.reserve (factorGroups.size());
|
||||
for (FacSignMap::const_iterator it = factorGroups.begin();
|
||||
it != factorGroups.end(); it++) {
|
||||
FgFacNode* groupFactor = it->second[0];
|
||||
@ -205,7 +189,7 @@ CFactorGraph::createClusters (const VarSignMap& varGroups,
|
||||
VarId vid = neighs[i]->varId();
|
||||
varClusters.push_back (vid2VarCluster_.find (vid)->second);
|
||||
}
|
||||
factorClusters_.push_back (new FacCluster (it->second, varClusters));
|
||||
facClusters_.push_back (new FacCluster (it->second, varClusters));
|
||||
}
|
||||
}
|
||||
|
||||
@ -220,7 +204,7 @@ CFactorGraph::getSignature (const FgVarNode* varNode)
|
||||
for (unsigned i = 0; i < neighs.size(); i++) {
|
||||
*it = getColor (neighs[i]);
|
||||
it ++;
|
||||
*it = neighs[i]->factor()->getPositionOf (varNode->varId());
|
||||
*it = neighs[i]->factor()->indexOf (varNode->varId());
|
||||
it ++;
|
||||
}
|
||||
*it = getColor (varNode);
|
||||
@ -256,8 +240,8 @@ CFactorGraph::getCompressedFactorGraph (void)
|
||||
fg->addVariable (newVar);
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < factorClusters_.size(); i++) {
|
||||
const VarClusterSet& myVarClusters = factorClusters_[i]->getVarClusters();
|
||||
for (unsigned i = 0; i < facClusters_.size(); i++) {
|
||||
const VarClusterSet& myVarClusters = facClusters_[i]->getVarClusters();
|
||||
VarNodes myGroundVars;
|
||||
myGroundVars.reserve (myVarClusters.size());
|
||||
for (unsigned j = 0; j < myVarClusters.size(); j++) {
|
||||
@ -265,9 +249,9 @@ CFactorGraph::getCompressedFactorGraph (void)
|
||||
myGroundVars.push_back (v);
|
||||
}
|
||||
Factor* newFactor = new Factor (myGroundVars,
|
||||
factorClusters_[i]->getGroundFactors()[0]->getDistribution());
|
||||
facClusters_[i]->getGroundFactors()[0]->getDistribution());
|
||||
FgFacNode* fn = new FgFacNode (newFactor);
|
||||
factorClusters_[i]->setRepresentativeFactor (fn);
|
||||
facClusters_[i]->setRepresentativeFactor (fn);
|
||||
fg->addFactor (fn);
|
||||
for (unsigned j = 0; j < myGroundVars.size(); j++) {
|
||||
fg->addEdge (fn, static_cast<FgVarNode*> (myGroundVars[j]));
|
||||
@ -280,14 +264,15 @@ CFactorGraph::getCompressedFactorGraph (void)
|
||||
|
||||
|
||||
unsigned
|
||||
CFactorGraph::getGroundEdgeCount (const FacCluster* fc,
|
||||
const VarCluster* vc) const
|
||||
CFactorGraph::getGroundEdgeCount (
|
||||
const FacCluster* fc,
|
||||
const VarCluster* vc) const
|
||||
{
|
||||
const FgFacSet& clusterGroundFactors = fc->getGroundFactors();
|
||||
FgVarNode* varNode = vc->getGroundFgVarNodes()[0];
|
||||
unsigned count = 0;
|
||||
for (unsigned i = 0; i < clusterGroundFactors.size(); i++) {
|
||||
if (clusterGroundFactors[i]->factor()->getPositionOf (varNode->varId()) != -1) {
|
||||
if (clusterGroundFactors[i]->factor()->indexOf (varNode->varId()) != -1) {
|
||||
count ++;
|
||||
}
|
||||
}
|
||||
@ -296,7 +281,7 @@ CFactorGraph::getGroundEdgeCount (const FacCluster* fc,
|
||||
// FgVarNode* var = vc->getGroundFgVarNodes()[i];
|
||||
// unsigned count2 = 0;
|
||||
// for (unsigned i = 0; i < clusterGroundFactors.size(); i++) {
|
||||
// if (clusterGroundFactors[i]->getPositionOf (var) != -1) {
|
||||
// if (clusterGroundFactors[i]->getPosition (var) != -1) {
|
||||
// count2 ++;
|
||||
// }
|
||||
// }
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
#include "FactorGraph.h"
|
||||
#include "Factor.h"
|
||||
#include "Shared.h"
|
||||
#include "Horus.h"
|
||||
|
||||
class VarCluster;
|
||||
class FacCluster;
|
||||
@ -18,15 +18,16 @@ class SignatureHash;
|
||||
typedef long Color;
|
||||
typedef unordered_map<unsigned, vector<Color> > VarColorMap;
|
||||
typedef unordered_map<const Distribution*, Color> DistColorMap;
|
||||
typedef unordered_map<VarId, VarCluster*> VarId2VarCluster;
|
||||
typedef unordered_map<VarId, VarCluster*> VarId2VarCluster;
|
||||
typedef vector<VarCluster*> VarClusterSet;
|
||||
typedef vector<FacCluster*> FacClusterSet;
|
||||
typedef unordered_map<Signature, FgVarSet, SignatureHash> VarSignMap;
|
||||
typedef unordered_map<Signature, FgVarSet, SignatureHash> VarSignMap;
|
||||
typedef unordered_map<Signature, FgFacSet, SignatureHash> FacSignMap;
|
||||
|
||||
|
||||
|
||||
struct Signature {
|
||||
struct Signature
|
||||
{
|
||||
Signature (unsigned size)
|
||||
{
|
||||
colors.resize (size);
|
||||
@ -90,12 +91,12 @@ class VarCluster
|
||||
|
||||
void addFacCluster (FacCluster* fc)
|
||||
{
|
||||
factorClusters_.push_back (fc);
|
||||
facClusters_.push_back (fc);
|
||||
}
|
||||
|
||||
const FacClusterSet& getFacClusters (void) const
|
||||
{
|
||||
return factorClusters_;
|
||||
return facClusters_;
|
||||
}
|
||||
|
||||
FgVarNode* getRepresentativeVariable (void) const { return representVar_; }
|
||||
@ -103,9 +104,9 @@ class VarCluster
|
||||
const FgVarSet& getGroundFgVarNodes (void) const { return groundVars_; }
|
||||
|
||||
private:
|
||||
FgVarSet groundVars_;
|
||||
FacClusterSet factorClusters_;
|
||||
FgVarNode* representVar_;
|
||||
FgVarSet groundVars_;
|
||||
FacClusterSet facClusters_;
|
||||
FgVarNode* representVar_;
|
||||
};
|
||||
|
||||
|
||||
@ -151,9 +152,9 @@ class FacCluster
|
||||
|
||||
|
||||
private:
|
||||
FgFacSet groundFactors_;
|
||||
FgFacSet groundFactors_;
|
||||
VarClusterSet varClusters_;
|
||||
FgFacNode* representFactor_;
|
||||
FgFacNode* representFactor_;
|
||||
};
|
||||
|
||||
|
||||
@ -172,18 +173,10 @@ class CFactorGraph
|
||||
return vc->getRepresentativeVariable();
|
||||
}
|
||||
|
||||
const VarClusterSet& getVariableClusters (void) { return varClusters_; }
|
||||
const FacClusterSet& getFacClusters (void) { return factorClusters_; }
|
||||
const VarClusterSet& getVarClusters (void) { return varClusters_; }
|
||||
const FacClusterSet& getFacClusters (void) { return facClusters_; }
|
||||
|
||||
static void enableCheckForIdenticalFactors (void)
|
||||
{
|
||||
checkForIdenticalFactors_ = true;
|
||||
}
|
||||
|
||||
static void disableCheckForIdenticalFactors (void)
|
||||
{
|
||||
checkForIdenticalFactors_ = false;
|
||||
}
|
||||
static bool checkForIdenticalFactors;
|
||||
|
||||
private:
|
||||
void setInitialColors (void);
|
||||
@ -227,10 +220,9 @@ class CFactorGraph
|
||||
vector<Signature> varSignatures_;
|
||||
vector<Signature> factorSignatures_;
|
||||
VarClusterSet varClusters_;
|
||||
FacClusterSet factorClusters_;
|
||||
FacClusterSet facClusters_;
|
||||
VarId2VarCluster vid2VarCluster_;
|
||||
const FactorGraph* groundFg_;
|
||||
bool static checkForIdenticalFactors_;
|
||||
};
|
||||
|
||||
#endif // HORUS_CFACTORGRAPH_H
|
||||
|
@ -13,32 +13,31 @@ CbpSolver::~CbpSolver (void)
|
||||
|
||||
|
||||
|
||||
ParamSet
|
||||
Params
|
||||
CbpSolver::getPosterioriOf (VarId vid)
|
||||
{
|
||||
assert (lfg_->getEquivalentVariable (vid));
|
||||
FgVarNode* var = lfg_->getEquivalentVariable (vid);
|
||||
ParamSet probs;
|
||||
Params probs;
|
||||
if (var->hasEvidence()) {
|
||||
probs.resize (var->nrStates(), Util::noEvidence());
|
||||
probs[var->getEvidence()] = Util::withEvidence();
|
||||
} else {
|
||||
probs.resize (var->nrStates(), Util::multIdenty());
|
||||
const SpLinkSet& links = ninf(var)->getLinks();
|
||||
switch (NSPACE) {
|
||||
case NumberSpace::NORMAL:
|
||||
for (unsigned i = 0; i < links.size(); i++) {
|
||||
CbpSolverLink* l = static_cast<CbpSolverLink*> (links[i]);
|
||||
Util::multiply (probs, l->getPoweredMessage());
|
||||
}
|
||||
Util::normalize (probs);
|
||||
break;
|
||||
case NumberSpace::LOGARITHM:
|
||||
if (Globals::logDomain) {
|
||||
for (unsigned i = 0; i < links.size(); i++) {
|
||||
CbpSolverLink* l = static_cast<CbpSolverLink*> (links[i]);
|
||||
Util::add (probs, l->getPoweredMessage());
|
||||
}
|
||||
Util::normalize (probs);
|
||||
Util::fromLog (probs);
|
||||
} else {
|
||||
for (unsigned i = 0; i < links.size(); i++) {
|
||||
CbpSolverLink* l = static_cast<CbpSolverLink*> (links[i]);
|
||||
Util::multiply (probs, l->getPoweredMessage());
|
||||
}
|
||||
Util::normalize (probs);
|
||||
}
|
||||
}
|
||||
return probs;
|
||||
@ -46,26 +45,19 @@ CbpSolver::getPosterioriOf (VarId vid)
|
||||
|
||||
|
||||
|
||||
ParamSet
|
||||
CbpSolver::getJointDistributionOf (const VarIdSet& jointVarIds)
|
||||
Params
|
||||
CbpSolver::getJointDistributionOf (const VarIds& jointVarIds)
|
||||
{
|
||||
unsigned msgSize = 1;
|
||||
vector<unsigned> dsizes (jointVarIds.size());
|
||||
VarIds eqVarIds;
|
||||
for (unsigned i = 0; i < jointVarIds.size(); i++) {
|
||||
dsizes[i] = lfg_->getEquivalentVariable (jointVarIds[i])->nrStates();
|
||||
msgSize *= dsizes[i];
|
||||
eqVarIds.push_back (lfg_->getEquivalentVariable (jointVarIds[i])->varId());
|
||||
}
|
||||
unsigned reps = 1;
|
||||
ParamSet jointDist (msgSize, Util::multIdenty());
|
||||
for (int i = jointVarIds.size() - 1 ; i >= 0; i--) {
|
||||
Util::multiply (jointDist, getPosterioriOf (jointVarIds[i]), reps);
|
||||
reps *= dsizes[i];
|
||||
}
|
||||
return jointDist;
|
||||
return FgBpSolver::getJointDistributionOf (eqVarIds);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void
|
||||
CbpSolver::initializeSolver (void)
|
||||
{
|
||||
@ -119,7 +111,6 @@ CbpSolver::createLinks (void)
|
||||
vcs[j]->getRepresentativeVariable(), c));
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -197,10 +188,10 @@ CbpSolver::maxResidualSchedule (void)
|
||||
|
||||
|
||||
|
||||
ParamSet
|
||||
Params
|
||||
CbpSolver::getVar2FactorMsg (const SpLink* link) const
|
||||
{
|
||||
ParamSet msg;
|
||||
Params msg;
|
||||
const FgVarNode* src = link->getVariable();
|
||||
const FgFacNode* dst = link->getFactor();
|
||||
const CbpSolverLink* l = static_cast<const CbpSolverLink*> (link);
|
||||
@ -216,27 +207,26 @@ CbpSolver::getVar2FactorMsg (const SpLink* link) const
|
||||
cout << " " << "init: " << Util::parametersToString (msg) << endl;
|
||||
}
|
||||
const SpLinkSet& links = ninf(src)->getLinks();
|
||||
switch (NSPACE) {
|
||||
case NumberSpace::NORMAL:
|
||||
for (unsigned i = 0; i < links.size(); i++) {
|
||||
if (links[i]->getFactor() != dst) {
|
||||
CbpSolverLink* l = static_cast<CbpSolverLink*> (links[i]);
|
||||
Util::multiply (msg, l->getPoweredMessage());
|
||||
if (DL >= 5) {
|
||||
cout << " msg from " << l->getFactor()->getLabel() << ": " ;
|
||||
cout << Util::parametersToString (l->getPoweredMessage()) << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NumberSpace::LOGARITHM:
|
||||
for (unsigned i = 0; i < links.size(); i++) {
|
||||
if (links[i]->getFactor() != dst) {
|
||||
CbpSolverLink* l = static_cast<CbpSolverLink*> (links[i]);
|
||||
Util::add (msg, l->getPoweredMessage());
|
||||
if (Globals::logDomain) {
|
||||
for (unsigned i = 0; i < links.size(); i++) {
|
||||
if (links[i]->getFactor() != dst) {
|
||||
CbpSolverLink* l = static_cast<CbpSolverLink*> (links[i]);
|
||||
Util::add (msg, l->getPoweredMessage());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (unsigned i = 0; i < links.size(); i++) {
|
||||
if (links[i]->getFactor() != dst) {
|
||||
CbpSolverLink* l = static_cast<CbpSolverLink*> (links[i]);
|
||||
Util::multiply (msg, l->getPoweredMessage());
|
||||
if (DL >= 5) {
|
||||
cout << " msg from " << l->getFactor()->getLabel() << ": " ;
|
||||
cout << Util::parametersToString (l->getPoweredMessage()) << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (DL >= 5) {
|
||||
cout << " result = " << Util::parametersToString (msg) << endl;
|
||||
}
|
||||
|
@ -23,11 +23,11 @@ class CbpSolverLink : public SpLink
|
||||
Util::pow (poweredMsg_, edgeCount_);
|
||||
}
|
||||
|
||||
unsigned getNumberOfEdges (void) const { return edgeCount_; }
|
||||
const ParamSet& getPoweredMessage (void) const { return poweredMsg_; }
|
||||
unsigned getNumberOfEdges (void) const { return edgeCount_; }
|
||||
const Params& getPoweredMessage (void) const { return poweredMsg_; }
|
||||
|
||||
private:
|
||||
ParamSet poweredMsg_;
|
||||
Params poweredMsg_;
|
||||
unsigned edgeCount_;
|
||||
};
|
||||
|
||||
@ -39,15 +39,15 @@ class CbpSolver : public FgBpSolver
|
||||
CbpSolver (FactorGraph& fg) : FgBpSolver (fg) { }
|
||||
~CbpSolver (void);
|
||||
|
||||
ParamSet getPosterioriOf (VarId);
|
||||
ParamSet getJointDistributionOf (const VarIdSet&);
|
||||
Params getPosterioriOf (VarId);
|
||||
Params getJointDistributionOf (const VarIds&);
|
||||
|
||||
private:
|
||||
void initializeSolver (void);
|
||||
void createLinks (void);
|
||||
|
||||
void maxResidualSchedule (void);
|
||||
ParamSet getVar2FactorMsg (const SpLink*) const;
|
||||
Params getVar2FactorMsg (const SpLink*) const;
|
||||
void printLinkInformation (void) const;
|
||||
|
||||
|
||||
|
1169
packages/CLPBN/clpbn/bp/ConstraintTree.cpp
Normal file
1169
packages/CLPBN/clpbn/bp/ConstraintTree.cpp
Normal file
File diff suppressed because it is too large
Load Diff
189
packages/CLPBN/clpbn/bp/ConstraintTree.h
Normal file
189
packages/CLPBN/clpbn/bp/ConstraintTree.h
Normal file
@ -0,0 +1,189 @@
|
||||
#ifndef HORUS_CONSTRAINTTREE_H
|
||||
#define HORUS_CONSTRAINTTREE_H
|
||||
|
||||
#include <cassert>
|
||||
#include <algorithm>
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
#include "TinySet.h"
|
||||
#include "LiftedUtils.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
class CTNode;
|
||||
typedef vector<CTNode*> CTNodes;
|
||||
|
||||
class ConstraintTree;
|
||||
typedef vector<ConstraintTree*> ConstraintTrees;
|
||||
|
||||
|
||||
|
||||
|
||||
class CTNode
|
||||
{
|
||||
public:
|
||||
CTNode (const CTNode& n) : symbol_(n.symbol()), level_(n.level()) { }
|
||||
|
||||
CTNode (Symbol s, unsigned l) : symbol_(s) , 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; }
|
||||
|
||||
CTNodes& childs (void) { return childs_; }
|
||||
|
||||
const CTNodes& childs (void) const { return childs_; }
|
||||
|
||||
unsigned nrChilds (void) const { return childs_.size(); }
|
||||
|
||||
bool isRoot (void) const { return level_ == 0; }
|
||||
|
||||
bool isLeaf (void) const { return childs_.empty(); }
|
||||
|
||||
void addChild (CTNode*, bool = true);
|
||||
void removeChild (CTNode*);
|
||||
SymbolSet childSymbols (void) const;
|
||||
|
||||
private:
|
||||
void updateChildLevels (CTNode*, unsigned);
|
||||
|
||||
Symbol symbol_;
|
||||
CTNodes childs_;
|
||||
unsigned level_;
|
||||
};
|
||||
|
||||
|
||||
|
||||
ostream& operator<< (ostream &out, const CTNode&);
|
||||
|
||||
|
||||
class ConstraintTree
|
||||
{
|
||||
public:
|
||||
ConstraintTree (const LogVars&);
|
||||
ConstraintTree (const LogVars&, const Tuples&);
|
||||
ConstraintTree (const ConstraintTree&);
|
||||
~ConstraintTree (void);
|
||||
|
||||
CTNode* root (void) const { return root_; }
|
||||
|
||||
bool empty (void) const { return root_->childs().empty(); }
|
||||
|
||||
const LogVars& logVars (void) const
|
||||
{
|
||||
assert (LogVarSet (logVars_) == logVarSet_);
|
||||
return logVars_;
|
||||
}
|
||||
|
||||
const LogVarSet& logVarSet (void) const
|
||||
{
|
||||
assert (LogVarSet (logVars_) == logVarSet_);
|
||||
return logVarSet_;
|
||||
}
|
||||
|
||||
unsigned nrLogVars (void) const
|
||||
{
|
||||
return logVars_.size();
|
||||
assert (LogVarSet (logVars_) == logVarSet_);
|
||||
}
|
||||
|
||||
void addTuple (const Tuple&);
|
||||
bool containsTuple (const Tuple&);
|
||||
void moveToTop (const LogVars&);
|
||||
void moveToBottom (const LogVars&);
|
||||
void join (ConstraintTree*, bool = false);
|
||||
unsigned getLevel (LogVar) const;
|
||||
void rename (LogVar, LogVar);
|
||||
void applySubstitution (const Substitution&);
|
||||
void project (const LogVarSet&);
|
||||
void remove (const LogVarSet&);
|
||||
bool isSingleton (LogVar);
|
||||
LogVarSet singletons (void);
|
||||
TupleSet tupleSet (unsigned = 0) const;
|
||||
TupleSet tupleSet (const LogVars&);
|
||||
unsigned size (void) const;
|
||||
unsigned nrSymbols (LogVar);
|
||||
void exportToGraphViz (const char*, bool = false) const;
|
||||
bool isCountNormalized (const LogVarSet&);
|
||||
unsigned getConditionalCount (const LogVarSet&);
|
||||
TinySet<unsigned> getConditionalCounts (const LogVarSet&);
|
||||
bool isCarteesianProduct (const LogVarSet&) const;
|
||||
|
||||
std::pair<ConstraintTree*, ConstraintTree*> split (
|
||||
const Tuple&,
|
||||
unsigned);
|
||||
|
||||
std::pair<ConstraintTree*, ConstraintTree*> split (
|
||||
const ConstraintTree*,
|
||||
unsigned) const;
|
||||
|
||||
ConstraintTrees countNormalize (const LogVarSet&);
|
||||
|
||||
ConstraintTrees jointCountNormalize (
|
||||
ConstraintTree*,
|
||||
ConstraintTree*,
|
||||
LogVar,
|
||||
LogVar,
|
||||
LogVar);
|
||||
|
||||
static bool identical (
|
||||
const ConstraintTree*,
|
||||
const ConstraintTree*,
|
||||
unsigned);
|
||||
|
||||
static bool overlap (
|
||||
const ConstraintTree*,
|
||||
const ConstraintTree*,
|
||||
unsigned);
|
||||
|
||||
LogVars expand (LogVar);
|
||||
ConstraintTrees ground (LogVar);
|
||||
|
||||
private:
|
||||
unsigned countTuples (const CTNode*) const;
|
||||
CTNodes getNodesBelow (CTNode*) const;
|
||||
CTNodes getNodesAtLevel (unsigned) const;
|
||||
void swapLogVar (LogVar);
|
||||
bool join (CTNode*, const Tuple&, unsigned, CTNode*);
|
||||
|
||||
bool indenticalSubtrees (
|
||||
const CTNode*,
|
||||
const CTNode*,
|
||||
bool) const;
|
||||
|
||||
void getTuples (
|
||||
CTNode*,
|
||||
Tuples,
|
||||
unsigned,
|
||||
Tuples&,
|
||||
CTNodes&) const;
|
||||
|
||||
vector<std::pair<CTNode*, unsigned>> countNormalize (
|
||||
const CTNode*,
|
||||
unsigned);
|
||||
|
||||
static void split (
|
||||
CTNode*,
|
||||
CTNode*,
|
||||
CTNodes&,
|
||||
unsigned);
|
||||
|
||||
static bool overlap (const CTNode*, const CTNode*, unsigned);
|
||||
static CTNode* copySubtree (const CTNode*);
|
||||
static void deleteSubtree (CTNode*);
|
||||
|
||||
CTNode* root_;
|
||||
LogVars logVars_;
|
||||
LogVarSet logVarSet_;
|
||||
};
|
||||
|
||||
|
||||
#endif // HORUS_CONSTRAINTTREE_H
|
||||
|
@ -1,38 +0,0 @@
|
||||
#include "CptEntry.h"
|
||||
|
||||
CptEntry::CptEntry (int cptIndex, vector<int> instantiations)
|
||||
{
|
||||
cptIndex_ = cptIndex;
|
||||
instantiations_ = instantiations;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
CptEntry::getCptIndex (void) const
|
||||
{
|
||||
return cptIndex_;
|
||||
}
|
||||
|
||||
|
||||
|
||||
vector<int>
|
||||
CptEntry::getDomainInstantiations (void) const
|
||||
{
|
||||
return instantiations_;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
CptEntry::matchConstraints (const vector<pair<int,int> >& constraints) const
|
||||
{
|
||||
for (unsigned int j = 0; j < constraints.size(); j++) {
|
||||
int index = constraints[j].first;
|
||||
if (instantiations_[index] != constraints[j].second) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -1,43 +0,0 @@
|
||||
#ifndef HORUS_CPTENTRY_H
|
||||
#define HORUS_CPTENTRY_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "Shared.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
class CptEntry
|
||||
{
|
||||
public:
|
||||
CptEntry (unsigned index, const DConf& conf)
|
||||
{
|
||||
index_ = index;
|
||||
conf_ = conf;
|
||||
}
|
||||
|
||||
unsigned getParameterIndex (void) const { return index_; }
|
||||
const DConf& getDomainConfiguration (void) const { return conf_; }
|
||||
|
||||
bool matchConstraints (const DConstraint& constr) const
|
||||
{
|
||||
return conf_[constr.first] == constr.second;
|
||||
}
|
||||
|
||||
bool matchConstraints (const vector<DConstraint>& constrs) const
|
||||
{
|
||||
for (unsigned j = 0; j < constrs.size(); j++) {
|
||||
if (conf_[constrs[j].first] != constrs[j].second) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned index_;
|
||||
DConf conf_;
|
||||
};
|
||||
|
||||
#endif // HORUS_CPTENTRY_H
|
||||
|
@ -3,34 +3,39 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "CptEntry.h"
|
||||
#include "Shared.h"
|
||||
#include "Horus.h"
|
||||
|
||||
//TODO die die die die die
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
struct Distribution
|
||||
{
|
||||
public:
|
||||
Distribution (unsigned id)
|
||||
Distribution (int id)
|
||||
{
|
||||
this->id = id;
|
||||
}
|
||||
|
||||
Distribution (const Params& params, int id = -1)
|
||||
{
|
||||
this->id = id;
|
||||
this->params = params;
|
||||
}
|
||||
|
||||
Distribution (const ParamSet& params, unsigned id = -1)
|
||||
{
|
||||
this->id = id;
|
||||
this->params = params;
|
||||
}
|
||||
|
||||
void updateParameters (const ParamSet& params)
|
||||
void updateParameters (const Params& params)
|
||||
{
|
||||
this->params = params;
|
||||
}
|
||||
|
||||
unsigned id;
|
||||
ParamSet params;
|
||||
vector<CptEntry> entries;
|
||||
bool shared (void)
|
||||
{
|
||||
return id != -1;
|
||||
}
|
||||
|
||||
int id;
|
||||
Params params;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN (Distribution);
|
||||
|
@ -65,7 +65,7 @@ void
|
||||
ElimGraph::addNode (EgNode* n)
|
||||
{
|
||||
nodes_.push_back (n);
|
||||
vid2nodes_.insert (make_pair (n->varId(), n));
|
||||
varMap_.insert (make_pair (n->varId(), n));
|
||||
}
|
||||
|
||||
|
||||
@ -73,8 +73,8 @@ ElimGraph::addNode (EgNode* n)
|
||||
EgNode*
|
||||
ElimGraph::getEgNode (VarId vid) const
|
||||
{
|
||||
unordered_map<VarId,EgNode*>::const_iterator it = vid2nodes_.find (vid);
|
||||
if (it == vid2nodes_.end()) {
|
||||
unordered_map<VarId,EgNode*>::const_iterator it =varMap_.find (vid);
|
||||
if (it ==varMap_.end()) {
|
||||
return 0;
|
||||
} else {
|
||||
return it->second;
|
||||
@ -83,10 +83,10 @@ ElimGraph::getEgNode (VarId vid) const
|
||||
|
||||
|
||||
|
||||
VarIdSet
|
||||
ElimGraph::getEliminatingOrder (const VarIdSet& exclude)
|
||||
VarIds
|
||||
ElimGraph::getEliminatingOrder (const VarIds& exclude)
|
||||
{
|
||||
VarIdSet elimOrder;
|
||||
VarIds elimOrder;
|
||||
marked_.resize (nodes_.size(), false);
|
||||
|
||||
for (unsigned i = 0; i < exclude.size(); i++) {
|
||||
@ -275,7 +275,7 @@ ElimGraph::printGraphicalModel (void) const
|
||||
void
|
||||
ElimGraph::exportToGraphViz (const char* fileName,
|
||||
bool showNeighborless,
|
||||
const VarIdSet& highlightVarIds) const
|
||||
const VarIds& highlightVarIds) const
|
||||
{
|
||||
ofstream out (fileName);
|
||||
if (!out.is_open()) {
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include "unordered_map"
|
||||
|
||||
#include "FactorGraph.h"
|
||||
#include "Shared.h"
|
||||
#include "Horus.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -45,10 +45,10 @@ class ElimGraph
|
||||
}
|
||||
void addNode (EgNode*);
|
||||
EgNode* getEgNode (VarId) const;
|
||||
VarIdSet getEliminatingOrder (const VarIdSet&);
|
||||
VarIds getEliminatingOrder (const VarIds&);
|
||||
void printGraphicalModel (void) const;
|
||||
void exportToGraphViz (const char*, bool = true,
|
||||
const VarIdSet& = VarIdSet()) const;
|
||||
const VarIds& = VarIds()) const;
|
||||
void setIndexes();
|
||||
|
||||
static void setEliminationHeuristic (ElimHeuristic h)
|
||||
@ -68,7 +68,7 @@ class ElimGraph
|
||||
|
||||
vector<EgNode*> nodes_;
|
||||
vector<bool> marked_;
|
||||
unordered_map<VarId,EgNode*> vid2nodes_;
|
||||
unordered_map<VarId,EgNode*> varMap_;
|
||||
static ElimHeuristic elimHeuristic_;
|
||||
};
|
||||
|
||||
|
@ -7,7 +7,8 @@
|
||||
#include <sstream>
|
||||
|
||||
#include "Factor.h"
|
||||
#include "StatesIndexer.h"
|
||||
#include "Indexer.h"
|
||||
#include "Util.h"
|
||||
|
||||
|
||||
Factor::Factor (const Factor& g)
|
||||
@ -21,7 +22,7 @@ Factor::Factor (VarId vid, unsigned nStates)
|
||||
{
|
||||
varids_.push_back (vid);
|
||||
ranges_.push_back (nStates);
|
||||
dist_ = new Distribution (ParamSet (nStates, 1.0));
|
||||
dist_ = new Distribution (Params (nStates, 1.0));
|
||||
}
|
||||
|
||||
|
||||
@ -36,12 +37,12 @@ Factor::Factor (const VarNodes& vars)
|
||||
}
|
||||
// create a uniform distribution
|
||||
double val = 1.0 / nParams;
|
||||
dist_ = new Distribution (ParamSet (nParams, val));
|
||||
dist_ = new Distribution (Params (nParams, val));
|
||||
}
|
||||
|
||||
|
||||
|
||||
Factor::Factor (VarId vid, unsigned nStates, const ParamSet& params)
|
||||
Factor::Factor (VarId vid, unsigned nStates, const Params& params)
|
||||
{
|
||||
varids_.push_back (vid);
|
||||
ranges_.push_back (nStates);
|
||||
@ -61,7 +62,7 @@ Factor::Factor (VarNodes& vars, Distribution* dist)
|
||||
|
||||
|
||||
|
||||
Factor::Factor (const VarNodes& vars, const ParamSet& params)
|
||||
Factor::Factor (const VarNodes& vars, const Params& params)
|
||||
{
|
||||
for (unsigned i = 0; i < vars.size(); i++) {
|
||||
varids_.push_back (vars[i]->varId());
|
||||
@ -72,9 +73,9 @@ Factor::Factor (const VarNodes& vars, const ParamSet& params)
|
||||
|
||||
|
||||
|
||||
Factor::Factor (const VarIdSet& vids,
|
||||
Factor::Factor (const VarIds& vids,
|
||||
const Ranges& ranges,
|
||||
const ParamSet& params)
|
||||
const Params& params)
|
||||
{
|
||||
varids_ = vids;
|
||||
ranges_ = ranges;
|
||||
@ -83,11 +84,20 @@ Factor::Factor (const VarIdSet& vids,
|
||||
|
||||
|
||||
|
||||
Factor::~Factor (void)
|
||||
{
|
||||
if (dist_->shared() == false) {
|
||||
delete dist_;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
Factor::setParameters (const ParamSet& params)
|
||||
Factor::setParameters (const Params& params)
|
||||
{
|
||||
assert (dist_->params.size() == params.size());
|
||||
dist_->updateParameters (params);
|
||||
dist_->params = params;
|
||||
}
|
||||
|
||||
|
||||
@ -97,140 +107,159 @@ Factor::copyFromFactor (const Factor& g)
|
||||
{
|
||||
varids_ = g.getVarIds();
|
||||
ranges_ = g.getRanges();
|
||||
dist_ = new Distribution (g.getDistribution()->params);
|
||||
dist_ = new Distribution (g.getParameters());
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
Factor::multiplyByFactor (const Factor& g, const vector<CptEntry>* entries)
|
||||
Factor::multiply (const Factor& g)
|
||||
{
|
||||
if (varids_.size() == 0) {
|
||||
copyFromFactor (g);
|
||||
return;
|
||||
}
|
||||
|
||||
const VarIdSet& gvarids = g.getVarIds();
|
||||
const Ranges& granges = g.getRanges();
|
||||
const ParamSet& gparams = g.getParameters();
|
||||
const VarIds& g_varids = g.getVarIds();
|
||||
const Ranges& g_ranges = g.getRanges();
|
||||
const Params& g_params = g.getParameters();
|
||||
|
||||
if (varids_ == gvarids) {
|
||||
if (varids_ == g_varids) {
|
||||
// optimization: if the factors contain the same set of variables,
|
||||
// we can do a 1 to 1 operation on the parameters
|
||||
switch (NSPACE) {
|
||||
case NumberSpace::NORMAL:
|
||||
Util::multiply (dist_->params, gparams);
|
||||
break;
|
||||
case NumberSpace::LOGARITHM:
|
||||
Util::add (dist_->params, gparams);
|
||||
if (Globals::logDomain) {
|
||||
Util::add (dist_->params, g_params);
|
||||
} else {
|
||||
Util::multiply (dist_->params, g_params);
|
||||
}
|
||||
} else {
|
||||
bool hasCommonVars = false;
|
||||
bool sharedVars = false;
|
||||
vector<unsigned> gvarpos;
|
||||
for (unsigned i = 0; i < gvarids.size(); i++) {
|
||||
int pos = getPositionOf (gvarids[i]);
|
||||
if (pos == -1) {
|
||||
insertVariable (gvarids[i], granges[i]);
|
||||
for (unsigned i = 0; i < g_varids.size(); i++) {
|
||||
int idx = indexOf (g_varids[i]);
|
||||
if (idx == -1) {
|
||||
insertVariable (g_varids[i], g_ranges[i]);
|
||||
gvarpos.push_back (varids_.size() - 1);
|
||||
} else {
|
||||
hasCommonVars = true;
|
||||
gvarpos.push_back (pos);
|
||||
sharedVars = true;
|
||||
gvarpos.push_back (idx);
|
||||
}
|
||||
}
|
||||
if (hasCommonVars) {
|
||||
vector<unsigned> gvaroffsets (gvarids.size());
|
||||
gvaroffsets[gvarids.size() - 1] = 1;
|
||||
for (int i = gvarids.size() - 2; i >= 0; i--) {
|
||||
gvaroffsets[i] = gvaroffsets[i + 1] * granges[i + 1];
|
||||
}
|
||||
|
||||
if (entries == 0) {
|
||||
entries = &getCptEntries();
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < entries->size(); i++) {
|
||||
unsigned idx = 0;
|
||||
const DConf& conf = (*entries)[i].getDomainConfiguration();
|
||||
for (unsigned j = 0; j < gvarpos.size(); j++) {
|
||||
idx += gvaroffsets[j] * conf[ gvarpos[j] ];
|
||||
}
|
||||
switch (NSPACE) {
|
||||
case NumberSpace::NORMAL:
|
||||
dist_->params[i] *= gparams[idx];
|
||||
break;
|
||||
case NumberSpace::LOGARITHM:
|
||||
dist_->params[i] += gparams[idx];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (sharedVars == false) {
|
||||
// optimization: if the original factors doesn't have common variables,
|
||||
// we don't need to marry the states of the common variables
|
||||
unsigned count = 0;
|
||||
for (unsigned i = 0; i < dist_->params.size(); i++) {
|
||||
switch (NSPACE) {
|
||||
case NumberSpace::NORMAL:
|
||||
dist_->params[i] *= gparams[count];
|
||||
break;
|
||||
case NumberSpace::LOGARITHM:
|
||||
dist_->params[i] += gparams[count];
|
||||
if (Globals::logDomain) {
|
||||
dist_->params[i] += g_params[count];
|
||||
} else {
|
||||
dist_->params[i] *= g_params[count];
|
||||
}
|
||||
count ++;
|
||||
if (count >= gparams.size()) {
|
||||
if (count >= g_params.size()) {
|
||||
count = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
StatesIndexer indexer (ranges_, false);
|
||||
while (indexer.valid()) {
|
||||
unsigned g_li = 0;
|
||||
unsigned prod = 1;
|
||||
for (int j = gvarpos.size() - 1; j >= 0; j--) {
|
||||
g_li += indexer[gvarpos[j]] * prod;
|
||||
prod *= g_ranges[j];
|
||||
}
|
||||
if (Globals::logDomain) {
|
||||
dist_->params[indexer] += g_params[g_li];
|
||||
} else {
|
||||
dist_->params[indexer] *= g_params[g_li];
|
||||
}
|
||||
++ indexer;
|
||||
}
|
||||
}
|
||||
}
|
||||
dist_->entries.clear();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
Factor::insertVariable (VarId vid, unsigned nStates)
|
||||
Factor::insertVariable (VarId varId, unsigned nrStates)
|
||||
{
|
||||
assert (getPositionOf (vid) == -1);
|
||||
ParamSet newPs;
|
||||
newPs.reserve (dist_->params.size() * nStates);
|
||||
for (unsigned i = 0; i < dist_->params.size(); i++) {
|
||||
for (unsigned j = 0; j < nStates; j++) {
|
||||
newPs.push_back (dist_->params[i]);
|
||||
assert (indexOf (varId) == -1);
|
||||
Params oldParams = dist_->params;
|
||||
dist_->params.clear();
|
||||
dist_->params.reserve (oldParams.size() * nrStates);
|
||||
for (unsigned i = 0; i < oldParams.size(); i++) {
|
||||
for (unsigned reps = 0; reps < nrStates; reps++) {
|
||||
dist_->params.push_back (oldParams[i]);
|
||||
}
|
||||
}
|
||||
varids_.push_back (vid);
|
||||
ranges_.push_back (nStates);
|
||||
dist_->updateParameters (newPs);
|
||||
dist_->entries.clear();
|
||||
varids_.push_back (varId);
|
||||
ranges_.push_back (nrStates);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
Factor::removeAllVariablesExcept (VarId vid)
|
||||
Factor::insertVariables (const VarIds& varIds, const Ranges& ranges)
|
||||
{
|
||||
assert (getPositionOf (vid) != -1);
|
||||
Params oldParams = dist_->params;
|
||||
unsigned nrStates = 1;
|
||||
for (unsigned i = 0; i < varIds.size(); i++) {
|
||||
assert (indexOf (varIds[i]) == -1);
|
||||
varids_.push_back (varIds[i]);
|
||||
ranges_.push_back (ranges[i]);
|
||||
nrStates *= ranges[i];
|
||||
}
|
||||
dist_->params.clear();
|
||||
dist_->params.reserve (oldParams.size() * nrStates);
|
||||
for (unsigned i = 0; i < oldParams.size(); i++) {
|
||||
for (unsigned reps = 0; reps < nrStates; reps++) {
|
||||
dist_->params.push_back (oldParams[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
Factor::sumOutAllExcept (VarId vid)
|
||||
{
|
||||
assert (indexOf (vid) != -1);
|
||||
while (varids_.back() != vid) {
|
||||
removeLastVariable();
|
||||
sumOutLastVariable();
|
||||
}
|
||||
while (varids_.front() != vid) {
|
||||
removeFirstVariable();
|
||||
sumOutFirstVariable();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
Factor::removeVariable (VarId vid)
|
||||
Factor::sumOutAllExcept (const VarIds& vids)
|
||||
{
|
||||
int pos = getPositionOf (vid);
|
||||
assert (pos != -1);
|
||||
for (unsigned i = 0; i < varids_.size(); i++) {
|
||||
if (std::find (vids.begin(), vids.end(), varids_[i]) == vids.end()) {
|
||||
sumOut (varids_[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
Factor::sumOut (VarId vid)
|
||||
{
|
||||
int idx = indexOf (vid);
|
||||
assert (idx != -1);
|
||||
|
||||
if (vid == varids_.back()) {
|
||||
removeLastVariable(); // optimization
|
||||
sumOutLastVariable(); // optimization
|
||||
return;
|
||||
}
|
||||
if (vid == varids_.front()) {
|
||||
removeFirstVariable(); // optimization
|
||||
sumOutFirstVariable(); // optimization
|
||||
return;
|
||||
}
|
||||
|
||||
@ -242,36 +271,35 @@ Factor::removeVariable (VarId vid)
|
||||
// on the left of `var', with the states of the remaining vars fixed
|
||||
unsigned leftVarOffset = 1;
|
||||
|
||||
for (int i = varids_.size() - 1; i > pos; i--) {
|
||||
for (int i = varids_.size() - 1; i > idx; i--) {
|
||||
varOffset *= ranges_[i];
|
||||
leftVarOffset *= ranges_[i];
|
||||
}
|
||||
leftVarOffset *= ranges_[pos];
|
||||
leftVarOffset *= ranges_[idx];
|
||||
|
||||
unsigned offset = 0;
|
||||
unsigned count1 = 0;
|
||||
unsigned count2 = 0;
|
||||
unsigned newPsSize = dist_->params.size() / ranges_[pos];
|
||||
unsigned newpsSize = dist_->params.size() / ranges_[idx];
|
||||
|
||||
ParamSet newPs;
|
||||
newPs.reserve (newPsSize);
|
||||
Params newps;
|
||||
newps.reserve (newpsSize);
|
||||
Params& params = dist_->params;
|
||||
|
||||
while (newPs.size() < newPsSize) {
|
||||
while (newps.size() < newpsSize) {
|
||||
double sum = Util::addIdenty();
|
||||
for (unsigned i = 0; i < ranges_[pos]; i++) {
|
||||
switch (NSPACE) {
|
||||
case NumberSpace::NORMAL:
|
||||
sum += dist_->params[offset];
|
||||
break;
|
||||
case NumberSpace::LOGARITHM:
|
||||
Util::logSum (sum, dist_->params[offset]);
|
||||
for (unsigned i = 0; i < ranges_[idx]; i++) {
|
||||
if (Globals::logDomain) {
|
||||
Util::logSum (sum, params[offset]);
|
||||
} else {
|
||||
sum += params[offset];
|
||||
}
|
||||
offset += varOffset;
|
||||
}
|
||||
newPs.push_back (sum);
|
||||
newps.push_back (sum);
|
||||
count1 ++;
|
||||
if (pos == (int)varids_.size() - 1) {
|
||||
offset = count1 * ranges_[pos];
|
||||
if (idx == (int)varids_.size() - 1) {
|
||||
offset = count1 * ranges_[idx];
|
||||
} else {
|
||||
if (((offset - varOffset + 1) % leftVarOffset) == 0) {
|
||||
count1 = 0;
|
||||
@ -280,73 +308,66 @@ Factor::removeVariable (VarId vid)
|
||||
offset = (leftVarOffset * count2) + count1;
|
||||
}
|
||||
}
|
||||
varids_.erase (varids_.begin() + pos);
|
||||
ranges_.erase (ranges_.begin() + pos);
|
||||
dist_->updateParameters (newPs);
|
||||
dist_->entries.clear();
|
||||
varids_.erase (varids_.begin() + idx);
|
||||
ranges_.erase (ranges_.begin() + idx);
|
||||
dist_->params = newps;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
Factor::removeFirstVariable (void)
|
||||
Factor::sumOutFirstVariable (void)
|
||||
{
|
||||
ParamSet& params = dist_->params;
|
||||
Params& params = dist_->params;
|
||||
unsigned nStates = ranges_.front();
|
||||
unsigned sep = params.size() / nStates;
|
||||
switch (NSPACE) {
|
||||
case NumberSpace::NORMAL:
|
||||
for (unsigned i = sep; i < params.size(); i++) {
|
||||
params[i % sep] += params[i];
|
||||
}
|
||||
break;
|
||||
case NumberSpace::LOGARITHM:
|
||||
for (unsigned i = sep; i < params.size(); i++) {
|
||||
Util::logSum (params[i % sep], params[i]);
|
||||
}
|
||||
if (Globals::logDomain) {
|
||||
for (unsigned i = sep; i < params.size(); i++) {
|
||||
Util::logSum (params[i % sep], params[i]);
|
||||
}
|
||||
} else {
|
||||
for (unsigned i = sep; i < params.size(); i++) {
|
||||
params[i % sep] += params[i];
|
||||
}
|
||||
}
|
||||
params.resize (sep);
|
||||
varids_.erase (varids_.begin());
|
||||
ranges_.erase (ranges_.begin());
|
||||
dist_->entries.clear();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
Factor::removeLastVariable (void)
|
||||
Factor::sumOutLastVariable (void)
|
||||
{
|
||||
ParamSet& params = dist_->params;
|
||||
Params& params = dist_->params;
|
||||
unsigned nStates = ranges_.back();
|
||||
unsigned idx1 = 0;
|
||||
unsigned idx2 = 0;
|
||||
switch (NSPACE) {
|
||||
case NumberSpace::NORMAL:
|
||||
while (idx1 < params.size()) {
|
||||
params[idx2] = params[idx1];
|
||||
if (Globals::logDomain) {
|
||||
while (idx1 < params.size()) {
|
||||
params[idx2] = params[idx1];
|
||||
idx1 ++;
|
||||
for (unsigned j = 1; j < nStates; j++) {
|
||||
Util::logSum (params[idx2], params[idx1]);
|
||||
idx1 ++;
|
||||
for (unsigned j = 1; j < nStates; j++) {
|
||||
params[idx2] += params[idx1];
|
||||
idx1 ++;
|
||||
}
|
||||
idx2 ++;
|
||||
}
|
||||
break;
|
||||
case NumberSpace::LOGARITHM:
|
||||
while (idx1 < params.size()) {
|
||||
params[idx2] = params[idx1];
|
||||
idx2 ++;
|
||||
}
|
||||
} else {
|
||||
while (idx1 < params.size()) {
|
||||
params[idx2] = params[idx1];
|
||||
idx1 ++;
|
||||
for (unsigned j = 1; j < nStates; j++) {
|
||||
params[idx2] += params[idx1];
|
||||
idx1 ++;
|
||||
for (unsigned j = 1; j < nStates; j++) {
|
||||
Util::logSum (params[idx2], params[idx1]);
|
||||
idx1 ++;
|
||||
}
|
||||
idx2 ++;
|
||||
}
|
||||
idx2 ++;
|
||||
}
|
||||
}
|
||||
params.resize (idx2);
|
||||
varids_.pop_back();
|
||||
ranges_.pop_back();
|
||||
dist_->entries.clear();
|
||||
}
|
||||
|
||||
|
||||
@ -354,34 +375,31 @@ Factor::removeLastVariable (void)
|
||||
void
|
||||
Factor::orderVariables (void)
|
||||
{
|
||||
VarIdSet sortedVarIds = varids_;
|
||||
VarIds sortedVarIds = varids_;
|
||||
sort (sortedVarIds.begin(), sortedVarIds.end());
|
||||
orderVariables (sortedVarIds);
|
||||
reorderVariables (sortedVarIds);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
Factor::orderVariables (const VarIdSet& newVarIdOrder)
|
||||
Factor::reorderVariables (const VarIds& newVarIds)
|
||||
{
|
||||
assert (newVarIdOrder.size() == varids_.size());
|
||||
if (newVarIdOrder == varids_) {
|
||||
assert (newVarIds.size() == varids_.size());
|
||||
if (newVarIds == varids_) {
|
||||
return;
|
||||
}
|
||||
|
||||
Ranges newRangeOrder;
|
||||
for (unsigned i = 0; i < newVarIdOrder.size(); i++) {
|
||||
unsigned pos = getPositionOf (newVarIdOrder[i]);
|
||||
newRangeOrder.push_back (ranges_[pos]);
|
||||
Ranges newRanges;
|
||||
vector<unsigned> positions;
|
||||
for (unsigned i = 0; i < newVarIds.size(); i++) {
|
||||
unsigned idx = indexOf (newVarIds[i]);
|
||||
newRanges.push_back (ranges_[idx]);
|
||||
positions.push_back (idx);
|
||||
}
|
||||
|
||||
vector<unsigned> positions;
|
||||
for (unsigned i = 0; i < newVarIdOrder.size(); i++) {
|
||||
positions.push_back (getPositionOf (newVarIdOrder[i]));
|
||||
}
|
||||
|
||||
unsigned N = ranges_.size();
|
||||
ParamSet newPs (dist_->params.size());
|
||||
Params newParams (dist_->params.size());
|
||||
for (unsigned i = 0; i < dist_->params.size(); i++) {
|
||||
unsigned li = i;
|
||||
// calculate vector index corresponding to linear index
|
||||
@ -397,35 +415,68 @@ Factor::orderVariables (const VarIdSet& newVarIdOrder)
|
||||
new_li += vi[positions[k]] * prod;
|
||||
prod *= ranges_[positions[k]];
|
||||
}
|
||||
newPs[new_li] = dist_->params[i];
|
||||
newParams[new_li] = dist_->params[i];
|
||||
}
|
||||
varids_ = newVarIdOrder;
|
||||
ranges_ = newRangeOrder;
|
||||
dist_->params = newPs;
|
||||
dist_->entries.clear();
|
||||
varids_ = newVarIds;
|
||||
ranges_ = newRanges;
|
||||
dist_->params = newParams;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
Factor::removeInconsistentEntries (VarId vid, unsigned evidence)
|
||||
Factor::absorveEvidence (VarId vid, unsigned evidence)
|
||||
{
|
||||
int pos = getPositionOf (vid);
|
||||
assert (pos != -1);
|
||||
ParamSet newPs;
|
||||
newPs.reserve (dist_->params.size() / ranges_[pos]);
|
||||
StatesIndexer idx (ranges_);
|
||||
int idx = indexOf (vid);
|
||||
assert (idx != -1);
|
||||
|
||||
Params oldParams = dist_->params;
|
||||
dist_->params.clear();
|
||||
dist_->params.reserve (oldParams.size() / ranges_[idx]);
|
||||
StatesIndexer indexer (ranges_);
|
||||
for (unsigned i = 0; i < evidence; i++) {
|
||||
idx.incrementState (pos);
|
||||
indexer.increment (idx);
|
||||
}
|
||||
while (idx.valid()) {
|
||||
newPs.push_back (dist_->params[idx.getLinearIndex()]);
|
||||
idx.nextSameState (pos);
|
||||
while (indexer.valid()) {
|
||||
dist_->params.push_back (oldParams[indexer]);
|
||||
indexer.incrementExcluding (idx);
|
||||
}
|
||||
varids_.erase (varids_.begin() + pos);
|
||||
ranges_.erase (ranges_.begin() + pos);
|
||||
dist_->updateParameters (newPs);
|
||||
dist_->entries.clear();
|
||||
varids_.erase (varids_.begin() + idx);
|
||||
ranges_.erase (ranges_.begin() + idx);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
Factor::normalize (void)
|
||||
{
|
||||
Util::normalize (dist_->params);
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
Factor::contains (const VarIds& vars) const
|
||||
{
|
||||
for (unsigned i = 0; i < vars.size(); i++) {
|
||||
if (indexOf (vars[i]) == -1) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
Factor::indexOf (VarId vid) const
|
||||
{
|
||||
for (unsigned i = 0; i < varids_.size(); i++) {
|
||||
if (varids_[i] == vid) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@ -446,7 +497,7 @@ Factor::getLabel (void) const
|
||||
|
||||
|
||||
void
|
||||
Factor::printFactor (void) const
|
||||
Factor::print (void) const
|
||||
{
|
||||
VarNodes vars;
|
||||
for (unsigned i = 0; i < varids_.size(); i++) {
|
||||
@ -457,53 +508,10 @@ Factor::printFactor (void) const
|
||||
cout << "f(" << jointStrings[i] << ")" ;
|
||||
cout << " = " << dist_->params[i] << endl;
|
||||
}
|
||||
cout << endl;
|
||||
for (unsigned i = 0; i < vars.size(); i++) {
|
||||
delete vars[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
Factor::getPositionOf (VarId vid) const
|
||||
{
|
||||
for (unsigned i = 0; i < varids_.size(); i++) {
|
||||
if (varids_[i] == vid) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const vector<CptEntry>&
|
||||
Factor::getCptEntries (void) const
|
||||
{
|
||||
if (dist_->entries.size() == 0) {
|
||||
vector<DConf> confs (dist_->params.size());
|
||||
for (unsigned i = 0; i < dist_->params.size(); i++) {
|
||||
confs[i].resize (varids_.size());
|
||||
}
|
||||
unsigned nReps = 1;
|
||||
for (int i = varids_.size() - 1; i >= 0; i--) {
|
||||
unsigned index = 0;
|
||||
while (index < dist_->params.size()) {
|
||||
for (unsigned j = 0; j < ranges_[i]; j++) {
|
||||
for (unsigned r = 0; r < nReps; r++) {
|
||||
confs[index][i] = j;
|
||||
index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
nReps *= ranges_[i];
|
||||
}
|
||||
dist_->entries.clear();
|
||||
dist_->entries.reserve (dist_->params.size());
|
||||
for (unsigned i = 0; i < dist_->params.size(); i++) {
|
||||
dist_->entries.push_back (CptEntry (i, confs[i]));
|
||||
}
|
||||
}
|
||||
return dist_->entries;
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,6 @@
|
||||
#include <vector>
|
||||
|
||||
#include "Distribution.h"
|
||||
#include "CptEntry.h"
|
||||
#include "VarNode.h"
|
||||
|
||||
|
||||
@ -20,47 +19,46 @@ class Factor
|
||||
Factor (const Factor&);
|
||||
Factor (VarId, unsigned);
|
||||
Factor (const VarNodes&);
|
||||
Factor (VarId, unsigned, const ParamSet&);
|
||||
Factor (VarId, unsigned, const Params&);
|
||||
Factor (VarNodes&, Distribution*);
|
||||
Factor (const VarNodes&, const ParamSet&);
|
||||
Factor (const VarIdSet&, const Ranges&, const ParamSet&);
|
||||
Factor (const VarNodes&, const Params&);
|
||||
Factor (const VarIds&, const Ranges&, const Params&);
|
||||
~Factor (void);
|
||||
|
||||
void setParameters (const ParamSet&);
|
||||
void setParameters (const Params&);
|
||||
void copyFromFactor (const Factor& f);
|
||||
void multiplyByFactor (const Factor&, const vector<CptEntry>* = 0);
|
||||
void multiply (const Factor&);
|
||||
void insertVariable (VarId, unsigned);
|
||||
void removeAllVariablesExcept (VarId);
|
||||
void removeVariable (VarId);
|
||||
void removeFirstVariable (void);
|
||||
void removeLastVariable (void);
|
||||
void insertVariables (const VarIds&, const Ranges&);
|
||||
void sumOutAllExcept (VarId);
|
||||
void sumOutAllExcept (const VarIds&);
|
||||
void sumOut (VarId);
|
||||
void sumOutFirstVariable (void);
|
||||
void sumOutLastVariable (void);
|
||||
void orderVariables (void);
|
||||
void orderVariables (const VarIdSet&);
|
||||
void removeInconsistentEntries (VarId, unsigned);
|
||||
void reorderVariables (const VarIds&);
|
||||
void absorveEvidence (VarId, unsigned);
|
||||
void normalize (void);
|
||||
bool contains (const VarIds&) const;
|
||||
int indexOf (VarId) const;
|
||||
string getLabel (void) const;
|
||||
void printFactor (void) const;
|
||||
int getPositionOf (VarId) const;
|
||||
const vector<CptEntry>& getCptEntries (void) const;
|
||||
void print (void) const;
|
||||
|
||||
const VarIdSet& getVarIds (void) const { return varids_; }
|
||||
const VarIds& getVarIds (void) const { return varids_; }
|
||||
const Ranges& getRanges (void) const { return ranges_; }
|
||||
const ParamSet& getParameters (void) const { return dist_->params; }
|
||||
const Params& getParameters (void) const { return dist_->params; }
|
||||
Distribution* getDistribution (void) const { return dist_; }
|
||||
unsigned nrVariables (void) const { return varids_.size(); }
|
||||
unsigned nrParameters() const { return dist_->params.size(); }
|
||||
unsigned nrVariables (void) const { return varids_.size(); }
|
||||
unsigned nrParameters() const { return dist_->params.size(); }
|
||||
|
||||
void setDistribution (Distribution* dist)
|
||||
{
|
||||
dist_ = dist;
|
||||
}
|
||||
void freeDistribution (void)
|
||||
{
|
||||
delete dist_;
|
||||
dist_ = 0;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
VarIdSet varids_;
|
||||
VarIds varids_;
|
||||
Ranges ranges_;
|
||||
Distribution* dist_;
|
||||
};
|
||||
|
@ -9,6 +9,30 @@
|
||||
#include "FactorGraph.h"
|
||||
#include "Factor.h"
|
||||
#include "BayesNet.h"
|
||||
#include "Util.h"
|
||||
|
||||
|
||||
bool FactorGraph::orderFactorVariables = false;
|
||||
|
||||
|
||||
FactorGraph::FactorGraph (const FactorGraph& fg)
|
||||
{
|
||||
const FgVarSet& vars = fg.getVarNodes();
|
||||
for (unsigned i = 0; i < vars.size(); i++) {
|
||||
FgVarNode* varNode = new FgVarNode (vars[i]);
|
||||
addVariable (varNode);
|
||||
}
|
||||
|
||||
const FgFacSet& facs = fg.getFactorNodes();
|
||||
for (unsigned i = 0; i < facs.size(); i++) {
|
||||
FgFacNode* facNode = new FgFacNode (facs[i]);
|
||||
addFactor (facNode);
|
||||
const FgVarSet& neighs = facs[i]->neighbors();
|
||||
for (unsigned j = 0; j < neighs.size(); j++) {
|
||||
addEdge (facNode, varNodes_[neighs[j]->getIndex()]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -30,6 +54,10 @@ FactorGraph::FactorGraph (const BayesNet& bn)
|
||||
}
|
||||
FgFacNode* fn = new FgFacNode (
|
||||
new Factor (neighs, nodes[i]->getDistribution()));
|
||||
if (orderFactorVariables) {
|
||||
sort (neighs.begin(), neighs.end(), CompVarId());
|
||||
fn->factor()->orderVariables();
|
||||
}
|
||||
addFactor (fn);
|
||||
for (unsigned j = 0; j < neighs.size(); j++) {
|
||||
addEdge (fn, static_cast<FgVarNode*> (neighs[j]));
|
||||
@ -110,13 +138,13 @@ FactorGraph::readFromUaiFormat (const char* fileName)
|
||||
cerr << ", given: " << nParams << endl;
|
||||
abort();
|
||||
}
|
||||
ParamSet params (nParams);
|
||||
Params params (nParams);
|
||||
for (unsigned j = 0; j < nParams; j++) {
|
||||
double param;
|
||||
is >> param;
|
||||
params[j] = param;
|
||||
}
|
||||
if (NSPACE == NumberSpace::LOGARITHM) {
|
||||
if (Globals::logDomain) {
|
||||
Util::toLog (params);
|
||||
}
|
||||
facNodes_[i]->factor()->setParameters (params);
|
||||
@ -158,7 +186,7 @@ FactorGraph::readFromLibDaiFormat (const char* fileName)
|
||||
while ((is.peek()) == '#') getline (is, line);
|
||||
|
||||
is >> nVars;
|
||||
VarIdSet vids;
|
||||
VarIds vids;
|
||||
for (unsigned j = 0; j < nVars; j++) {
|
||||
VarId vid;
|
||||
while ((is.peek()) == '#') getline (is, line);
|
||||
@ -185,15 +213,14 @@ FactorGraph::readFromLibDaiFormat (const char* fileName)
|
||||
neighs.push_back (var);
|
||||
nParams *= var->nrStates();
|
||||
}
|
||||
ParamSet params (nParams, 0);
|
||||
Params params (nParams, 0);
|
||||
unsigned nNonzeros;
|
||||
while ((is.peek()) == '#')
|
||||
getline (is, line);
|
||||
while ((is.peek()) == '#') getline (is, line);
|
||||
is >> nNonzeros;
|
||||
|
||||
for (unsigned j = 0; j < nNonzeros; j++) {
|
||||
unsigned index;
|
||||
Param val;
|
||||
double val;
|
||||
while ((is.peek()) == '#') getline (is, line);
|
||||
is >> index;
|
||||
while ((is.peek()) == '#') getline (is, line);
|
||||
@ -201,7 +228,7 @@ FactorGraph::readFromLibDaiFormat (const char* fileName)
|
||||
params[index] = val;
|
||||
}
|
||||
reverse (neighs.begin(), neighs.end());
|
||||
if (NSPACE == NumberSpace::LOGARITHM) {
|
||||
if (Globals::logDomain) {
|
||||
Util::toLog (params);
|
||||
}
|
||||
FgFacNode* fn = new FgFacNode (new Factor (neighs, params));
|
||||
@ -233,7 +260,7 @@ FactorGraph::addVariable (FgVarNode* vn)
|
||||
{
|
||||
varNodes_.push_back (vn);
|
||||
vn->setIndex (varNodes_.size() - 1);
|
||||
indexMap_.insert (make_pair (vn->varId(), varNodes_.size() - 1));
|
||||
varMap_.insert (make_pair (vn->varId(), varNodes_.size() - 1));
|
||||
}
|
||||
|
||||
|
||||
@ -246,6 +273,7 @@ FactorGraph::addFactor (FgFacNode* fn)
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
FactorGraph::addEdge (FgVarNode* vn, FgFacNode* fn)
|
||||
{
|
||||
@ -326,10 +354,10 @@ void
|
||||
FactorGraph::printGraphicalModel (void) const
|
||||
{
|
||||
for (unsigned i = 0; i < varNodes_.size(); i++) {
|
||||
cout << "VarId = " << varNodes_[i]->varId() << endl;
|
||||
cout << "Label = " << varNodes_[i]->label() << endl;
|
||||
cout << "Nr States = " << varNodes_[i]->nrStates() << endl;
|
||||
cout << "Evidence = " << varNodes_[i]->getEvidence() << endl;
|
||||
cout << "VarId = " << varNodes_[i]->varId() << endl;
|
||||
cout << "Label = " << varNodes_[i]->label() << endl;
|
||||
cout << "Nr States = " << varNodes_[i]->nrStates() << endl;
|
||||
cout << "Evidence = " << varNodes_[i]->getEvidence() << endl;
|
||||
cout << "Factors = " ;
|
||||
for (unsigned j = 0; j < varNodes_[i]->neighbors().size(); j++) {
|
||||
cout << varNodes_[i]->neighbors()[j]->getLabel() << " " ;
|
||||
@ -337,7 +365,7 @@ FactorGraph::printGraphicalModel (void) const
|
||||
cout << endl << endl;
|
||||
}
|
||||
for (unsigned i = 0; i < facNodes_.size(); i++) {
|
||||
facNodes_[i]->factor()->printFactor();
|
||||
facNodes_[i]->factor()->print();
|
||||
cout << endl;
|
||||
}
|
||||
}
|
||||
@ -412,7 +440,10 @@ FactorGraph::exportToUaiFormat (const char* fileName) const
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < facNodes_.size(); i++) {
|
||||
const ParamSet& params = facNodes_[i]->getParameters();
|
||||
Params params = facNodes_[i]->getParameters();
|
||||
if (Globals::logDomain) {
|
||||
Util::fromLog (params);
|
||||
}
|
||||
out << endl << params.size() << endl << " " ;
|
||||
for (unsigned j = 0; j < params.size(); j++) {
|
||||
out << params[j] << " " ;
|
||||
@ -446,7 +477,10 @@ FactorGraph::exportToLibDaiFormat (const char* fileName) const
|
||||
out << factorVars[j]->nrStates() << " " ;
|
||||
}
|
||||
out << endl;
|
||||
const ParamSet& params = facNodes_[i]->factor()->getParameters();
|
||||
Params params = facNodes_[i]->factor()->getParameters();
|
||||
if (Globals::logDomain) {
|
||||
Util::fromLog (params);
|
||||
}
|
||||
out << params.size() << endl;
|
||||
for (unsigned j = 0; j < params.size(); j++) {
|
||||
out << j << " " << params[j] << endl;
|
||||
|
@ -4,13 +4,13 @@
|
||||
#include <vector>
|
||||
|
||||
#include "GraphicalModel.h"
|
||||
#include "Shared.h"
|
||||
#include "Distribution.h"
|
||||
#include "Factor.h"
|
||||
#include "Horus.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
class BayesNet;
|
||||
class FgFacNode;
|
||||
|
||||
class FgVarNode : public VarNode
|
||||
@ -18,42 +18,29 @@ class FgVarNode : public VarNode
|
||||
public:
|
||||
FgVarNode (VarId varId, unsigned nrStates) : VarNode (varId, nrStates) { }
|
||||
FgVarNode (const VarNode* v) : VarNode (v) { }
|
||||
void addNeighbor (FgFacNode* fn)
|
||||
{
|
||||
neighs_.push_back (fn);
|
||||
}
|
||||
const vector<FgFacNode*>& neighbors (void) const
|
||||
{
|
||||
return neighs_;
|
||||
}
|
||||
|
||||
void addNeighbor (FgFacNode* fn) { neighs_.push_back (fn); }
|
||||
const FgFacSet& neighbors (void) const { return neighs_; }
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN (FgVarNode);
|
||||
// members
|
||||
vector<FgFacNode*> neighs_;
|
||||
FgFacSet neighs_;
|
||||
};
|
||||
|
||||
|
||||
class FgFacNode
|
||||
{
|
||||
public:
|
||||
FgFacNode (Factor* factor)
|
||||
{
|
||||
factor_ = factor;
|
||||
FgFacNode (const FgFacNode* fn) {
|
||||
factor_ = new Factor (*fn->factor());
|
||||
index_ = -1;
|
||||
}
|
||||
Factor* factor() const
|
||||
{
|
||||
return factor_;
|
||||
}
|
||||
void addNeighbor (FgVarNode* vn)
|
||||
{
|
||||
neighs_.push_back (vn);
|
||||
}
|
||||
const vector<FgVarNode*>& neighbors (void) const
|
||||
{
|
||||
return neighs_;
|
||||
}
|
||||
FgFacNode (Factor* f) : factor_(new Factor(*f)), index_(-1) { }
|
||||
Factor* factor() const { return factor_; }
|
||||
void addNeighbor (FgVarNode* vn) { neighs_.push_back (vn); }
|
||||
const FgVarSet& neighbors (void) const { return neighs_; }
|
||||
|
||||
int getIndex (void) const
|
||||
{
|
||||
assert (index_ != -1);
|
||||
@ -67,7 +54,7 @@ class FgFacNode
|
||||
{
|
||||
return factor_->getDistribution();
|
||||
}
|
||||
const ParamSet& getParameters (void) const
|
||||
const Params& getParameters (void) const
|
||||
{
|
||||
return factor_->getParameters();
|
||||
}
|
||||
@ -80,7 +67,16 @@ class FgFacNode
|
||||
|
||||
Factor* factor_;
|
||||
int index_;
|
||||
vector<FgVarNode*> neighs_;
|
||||
FgVarSet neighs_;
|
||||
};
|
||||
|
||||
|
||||
struct CompVarId
|
||||
{
|
||||
bool operator() (const VarNode* vn1, const VarNode* vn2) const
|
||||
{
|
||||
return vn1->varId() < vn2->varId();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -88,6 +84,7 @@ class FactorGraph : public GraphicalModel
|
||||
{
|
||||
public:
|
||||
FactorGraph (void) {};
|
||||
FactorGraph (const FactorGraph&);
|
||||
FactorGraph (const BayesNet&);
|
||||
~FactorGraph (void);
|
||||
|
||||
@ -112,28 +109,29 @@ class FactorGraph : public GraphicalModel
|
||||
|
||||
FgVarNode* getFgVarNode (VarId vid) const
|
||||
{
|
||||
IndexMap::const_iterator it = indexMap_.find (vid);
|
||||
if (it == indexMap_.end()) {
|
||||
IndexMap::const_iterator it = varMap_.find (vid);
|
||||
if (it == varMap_.end()) {
|
||||
return 0;
|
||||
} else {
|
||||
return varNodes_[it->second];
|
||||
}
|
||||
}
|
||||
|
||||
static bool orderFactorVariables;
|
||||
|
||||
private:
|
||||
//DISALLOW_COPY_AND_ASSIGN (FactorGraph);
|
||||
bool containsCycle (void) const;
|
||||
bool containsCycle (const FgVarNode*, const FgFacNode*,
|
||||
vector<bool>&, vector<bool>&) const;
|
||||
bool containsCycle (const FgFacNode*, const FgVarNode*,
|
||||
vector<bool>&, vector<bool>&) const;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN (FactorGraph);
|
||||
|
||||
FgVarSet varNodes_;
|
||||
FgFacSet facNodes_;
|
||||
|
||||
typedef unordered_map<unsigned, unsigned> IndexMap;
|
||||
IndexMap indexMap_;
|
||||
IndexMap varMap_;
|
||||
};
|
||||
|
||||
#endif // HORUS_FACTORGRAPH_H
|
||||
|
@ -8,7 +8,8 @@
|
||||
#include "FgBpSolver.h"
|
||||
#include "FactorGraph.h"
|
||||
#include "Factor.h"
|
||||
#include "Shared.h"
|
||||
#include "Indexer.h"
|
||||
#include "Horus.h"
|
||||
|
||||
|
||||
FgBpSolver::FgBpSolver (const FactorGraph& fg) : Solver (&fg)
|
||||
@ -40,20 +41,15 @@ FgBpSolver::runSolver (void)
|
||||
if (COLLECT_STATISTICS) {
|
||||
start = clock();
|
||||
}
|
||||
if (false) {
|
||||
//if (!BpOptions::useAlwaysLoopySolver && factorGraph_->isTree()) {
|
||||
runTreeSolver();
|
||||
} else {
|
||||
runLoopySolver();
|
||||
if (DL >= 2) {
|
||||
runLoopySolver();
|
||||
if (DL >= 2) {
|
||||
cout << endl;
|
||||
if (nIters_ < BpOptions::maxIter) {
|
||||
cout << "Sum-Product converged in " ;
|
||||
cout << nIters_ << " iterations" << endl;
|
||||
} else {
|
||||
cout << "The maximum number of iterations was hit, terminating..." ;
|
||||
cout << endl;
|
||||
if (nIters_ < BpOptions::maxIter) {
|
||||
cout << "Sum-Product converged in " ;
|
||||
cout << nIters_ << " iterations" << endl;
|
||||
} else {
|
||||
cout << "The maximum number of iterations was hit, terminating..." ;
|
||||
cout << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
unsigned size = factorGraph_->getVarNodes().size();
|
||||
@ -73,32 +69,29 @@ FgBpSolver::runSolver (void)
|
||||
|
||||
|
||||
|
||||
ParamSet
|
||||
Params
|
||||
FgBpSolver::getPosterioriOf (VarId vid)
|
||||
{
|
||||
assert (factorGraph_->getFgVarNode (vid));
|
||||
FgVarNode* var = factorGraph_->getFgVarNode (vid);
|
||||
ParamSet probs;
|
||||
|
||||
Params probs;
|
||||
if (var->hasEvidence()) {
|
||||
probs.resize (var->nrStates(), Util::noEvidence());
|
||||
probs[var->getEvidence()] = Util::withEvidence();
|
||||
} else {
|
||||
probs.resize (var->nrStates(), Util::multIdenty());
|
||||
const SpLinkSet& links = ninf(var)->getLinks();
|
||||
switch (NSPACE) {
|
||||
case NumberSpace::NORMAL:
|
||||
for (unsigned i = 0; i < links.size(); i++) {
|
||||
Util::multiply (probs, links[i]->getMessage());
|
||||
}
|
||||
Util::normalize (probs);
|
||||
break;
|
||||
case NumberSpace::LOGARITHM:
|
||||
for (unsigned i = 0; i < links.size(); i++) {
|
||||
Util::add (probs, links[i]->getMessage());
|
||||
}
|
||||
Util::normalize (probs);
|
||||
Util::fromLog (probs);
|
||||
if (Globals::logDomain) {
|
||||
for (unsigned i = 0; i < links.size(); i++) {
|
||||
Util::add (probs, links[i]->getMessage());
|
||||
}
|
||||
Util::normalize (probs);
|
||||
Util::fromLog (probs);
|
||||
} else {
|
||||
for (unsigned i = 0; i < links.size(); i++) {
|
||||
Util::multiply (probs, links[i]->getMessage());
|
||||
}
|
||||
Util::normalize (probs);
|
||||
}
|
||||
}
|
||||
return probs;
|
||||
@ -106,66 +99,38 @@ FgBpSolver::getPosterioriOf (VarId vid)
|
||||
|
||||
|
||||
|
||||
ParamSet
|
||||
FgBpSolver::getJointDistributionOf (const VarIdSet& jointVarIds)
|
||||
Params
|
||||
FgBpSolver::getJointDistributionOf (const VarIds& jointVarIds)
|
||||
{
|
||||
unsigned msgSize = 1;
|
||||
vector<unsigned> dsizes (jointVarIds.size());
|
||||
for (unsigned i = 0; i < jointVarIds.size(); i++) {
|
||||
dsizes[i] = factorGraph_->getFgVarNode (jointVarIds[i])->nrStates();
|
||||
msgSize *= dsizes[i];
|
||||
}
|
||||
unsigned reps = 1;
|
||||
ParamSet jointDist (msgSize, Util::multIdenty());
|
||||
for (int i = jointVarIds.size() - 1 ; i >= 0; i--) {
|
||||
Util::multiply (jointDist, getPosterioriOf (jointVarIds[i]), reps);
|
||||
reps *= dsizes[i];
|
||||
}
|
||||
return jointDist;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
FgBpSolver::runTreeSolver (void)
|
||||
{
|
||||
initializeSolver();
|
||||
const FgFacSet& facNodes = factorGraph_->getFactorNodes();
|
||||
bool finish = false;
|
||||
while (!finish) {
|
||||
finish = true;
|
||||
for (unsigned i = 0; i < facNodes.size(); i++) {
|
||||
const SpLinkSet& links = ninf (facNodes[i])->getLinks();
|
||||
for (unsigned j = 0; j < links.size(); j++) {
|
||||
if (!links[j]->messageWasSended()) {
|
||||
if (readyToSendMessage (links[j])) {
|
||||
calculateAndUpdateMessage (links[j], false);
|
||||
}
|
||||
finish = false;
|
||||
}
|
||||
}
|
||||
FgVarNode* vn = factorGraph_->getFgVarNode (jointVarIds[0]);
|
||||
const FgFacSet& factorNodes = vn->neighbors();
|
||||
int idx = -1;
|
||||
for (unsigned i = 0; i < factorNodes.size(); i++) {
|
||||
if (factorNodes[i]->factor()->contains (jointVarIds)) {
|
||||
idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
FgBpSolver::readyToSendMessage (const SpLink* link) const
|
||||
{
|
||||
const FgVarSet& neighbors = link->getFactor()->neighbors();
|
||||
for (unsigned i = 0; i < neighbors.size(); i++) {
|
||||
if (neighbors[i] != link->getVariable()) {
|
||||
const SpLinkSet& links = ninf (neighbors[i])->getLinks();
|
||||
for (unsigned j = 0; j < links.size(); j++) {
|
||||
if (links[j]->getFactor() != link->getFactor() &&
|
||||
!links[j]->messageWasSended()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (idx == -1) {
|
||||
return getJointByConditioning (jointVarIds);
|
||||
} else {
|
||||
Factor r (*factorNodes[idx]->factor());
|
||||
const SpLinkSet& links = ninf(factorNodes[idx])->getLinks();
|
||||
for (unsigned i = 0; i < links.size(); i++) {
|
||||
Factor msg (links[i]->getVariable()->varId(),
|
||||
links[i]->getVariable()->nrStates(),
|
||||
getVar2FactorMsg (links[i]));
|
||||
r.multiply (msg);
|
||||
}
|
||||
r.sumOutAllExcept (jointVarIds);
|
||||
r.reorderVariables (jointVarIds);
|
||||
r.normalize();
|
||||
Params jointDist = r.getParameters();
|
||||
if (Globals::logDomain) {
|
||||
Util::fromLog (jointDist);
|
||||
}
|
||||
return jointDist;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -282,7 +247,7 @@ FgBpSolver::converged (void)
|
||||
}
|
||||
bool converged = true;
|
||||
if (BpOptions::schedule == BpOptions::Schedule::MAX_RESIDUAL) {
|
||||
Param maxResidual = (*(sortedOrder_.begin()))->getResidual();
|
||||
double maxResidual = (*(sortedOrder_.begin()))->getResidual();
|
||||
if (maxResidual > BpOptions::accuracy) {
|
||||
converged = false;
|
||||
} else {
|
||||
@ -374,40 +339,39 @@ FgBpSolver::calculateFactor2VariableMsg (SpLink* link) const
|
||||
msgSize *= links[i]->getVariable()->nrStates();
|
||||
}
|
||||
unsigned repetitions = 1;
|
||||
ParamSet msgProduct (msgSize, Util::multIdenty());
|
||||
switch (NSPACE) {
|
||||
case NumberSpace::NORMAL:
|
||||
for (int i = links.size() - 1; i >= 0; i--) {
|
||||
if (links[i]->getVariable() != dst) {
|
||||
if (DL >= 5) {
|
||||
cout << " message from " << links[i]->getVariable()->label();
|
||||
cout << ": " << endl;
|
||||
}
|
||||
Util::multiply (msgProduct, getVar2FactorMsg (links[i]), repetitions);
|
||||
repetitions *= links[i]->getVariable()->nrStates();
|
||||
} else {
|
||||
unsigned ds = links[i]->getVariable()->nrStates();
|
||||
Util::multiply (msgProduct, ParamSet (ds, 1.0), repetitions);
|
||||
repetitions *= ds;
|
||||
}
|
||||
Params msgProduct (msgSize, Util::multIdenty());
|
||||
if (Globals::logDomain) {
|
||||
for (int i = links.size() - 1; i >= 0; i--) {
|
||||
if (links[i]->getVariable() != dst) {
|
||||
Util::add (msgProduct, getVar2FactorMsg (links[i]), repetitions);
|
||||
repetitions *= links[i]->getVariable()->nrStates();
|
||||
} else {
|
||||
unsigned ds = links[i]->getVariable()->nrStates();
|
||||
Util::add (msgProduct, Params (ds, 1.0), repetitions);
|
||||
repetitions *= ds;
|
||||
}
|
||||
break;
|
||||
case NumberSpace::LOGARITHM:
|
||||
for (int i = links.size() - 1; i >= 0; i--) {
|
||||
if (links[i]->getVariable() != dst) {
|
||||
Util::add (msgProduct, getVar2FactorMsg (links[i]), repetitions);
|
||||
repetitions *= links[i]->getVariable()->nrStates();
|
||||
} else {
|
||||
unsigned ds = links[i]->getVariable()->nrStates();
|
||||
Util::add (msgProduct, ParamSet (ds, 1.0), repetitions);
|
||||
repetitions *= ds;
|
||||
}
|
||||
} else {
|
||||
for (int i = links.size() - 1; i >= 0; i--) {
|
||||
if (links[i]->getVariable() != dst) {
|
||||
if (DL >= 5) {
|
||||
cout << " message from " << links[i]->getVariable()->label();
|
||||
cout << ": " << endl;
|
||||
}
|
||||
Util::multiply (msgProduct, getVar2FactorMsg (links[i]), repetitions);
|
||||
repetitions *= links[i]->getVariable()->nrStates();
|
||||
} else {
|
||||
unsigned ds = links[i]->getVariable()->nrStates();
|
||||
Util::multiply (msgProduct, Params (ds, 1.0), repetitions);
|
||||
repetitions *= ds;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Factor result (src->factor()->getVarIds(),
|
||||
src->factor()->getRanges(),
|
||||
msgProduct);
|
||||
result.multiplyByFactor (*(src->factor()));
|
||||
result.multiply (*(src->factor()));
|
||||
if (DL >= 5) {
|
||||
cout << " message product: " ;
|
||||
cout << Util::parametersToString (msgProduct) << endl;
|
||||
@ -416,13 +380,13 @@ FgBpSolver::calculateFactor2VariableMsg (SpLink* link) const
|
||||
cout << " factor product: " ;
|
||||
cout << Util::parametersToString (result.getParameters()) << endl;
|
||||
}
|
||||
result.removeAllVariablesExcept (dst->varId());
|
||||
result.sumOutAllExcept (dst->varId());
|
||||
if (DL >= 5) {
|
||||
cout << " marginalized: " ;
|
||||
cout << Util::parametersToString (result.getParameters()) << endl;
|
||||
}
|
||||
const ParamSet& resultParams = result.getParameters();
|
||||
ParamSet& message = link->getNextMessage();
|
||||
const Params& resultParams = result.getParameters();
|
||||
Params& message = link->getNextMessage();
|
||||
for (unsigned i = 0; i < resultParams.size(); i++) {
|
||||
message[i] = resultParams[i];
|
||||
}
|
||||
@ -433,17 +397,16 @@ FgBpSolver::calculateFactor2VariableMsg (SpLink* link) const
|
||||
cout << " next msg: " ;
|
||||
cout << Util::parametersToString (message) << endl;
|
||||
}
|
||||
result.freeDistribution();
|
||||
}
|
||||
|
||||
|
||||
|
||||
ParamSet
|
||||
Params
|
||||
FgBpSolver::getVar2FactorMsg (const SpLink* link) const
|
||||
{
|
||||
const FgVarNode* src = link->getVariable();
|
||||
const FgFacNode* dst = link->getFactor();
|
||||
ParamSet msg;
|
||||
Params msg;
|
||||
if (src->hasEvidence()) {
|
||||
msg.resize (src->nrStates(), Util::noEvidence());
|
||||
msg[src->getEvidence()] = Util::withEvidence();
|
||||
@ -457,23 +420,21 @@ FgBpSolver::getVar2FactorMsg (const SpLink* link) const
|
||||
cout << Util::parametersToString (msg);
|
||||
}
|
||||
const SpLinkSet& links = ninf (src)->getLinks();
|
||||
switch (NSPACE) {
|
||||
case NumberSpace::NORMAL:
|
||||
for (unsigned i = 0; i < links.size(); i++) {
|
||||
if (links[i]->getFactor() != dst) {
|
||||
Util::multiply (msg, links[i]->getMessage());
|
||||
if (DL >= 5) {
|
||||
cout << " x " << Util::parametersToString (links[i]->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NumberSpace::LOGARITHM:
|
||||
for (unsigned i = 0; i < links.size(); i++) {
|
||||
if (links[i]->getFactor() != dst) {
|
||||
Util::add (msg, links[i]->getMessage());
|
||||
if (Globals::logDomain) {
|
||||
for (unsigned i = 0; i < links.size(); i++) {
|
||||
if (links[i]->getFactor() != dst) {
|
||||
Util::add (msg, links[i]->getMessage());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (unsigned i = 0; i < links.size(); i++) {
|
||||
if (links[i]->getFactor() != dst) {
|
||||
Util::multiply (msg, links[i]->getMessage());
|
||||
if (DL >= 5) {
|
||||
cout << " x " << Util::parametersToString (links[i]->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (DL >= 5) {
|
||||
cout << " = " << Util::parametersToString (msg);
|
||||
@ -483,6 +444,58 @@ FgBpSolver::getVar2FactorMsg (const SpLink* link) const
|
||||
|
||||
|
||||
|
||||
Params
|
||||
FgBpSolver::getJointByConditioning (const VarIds& jointVarIds) const
|
||||
{
|
||||
FgVarSet jointVars;
|
||||
for (unsigned i = 0; i < jointVarIds.size(); i++) {
|
||||
assert (factorGraph_->getFgVarNode (jointVarIds[i]));
|
||||
jointVars.push_back (factorGraph_->getFgVarNode (jointVarIds[i]));
|
||||
}
|
||||
|
||||
FactorGraph* fg = new FactorGraph (*factorGraph_);
|
||||
FgBpSolver solver (*fg);
|
||||
solver.runSolver();
|
||||
Params prevBeliefs = solver.getPosterioriOf (jointVarIds[0]);
|
||||
|
||||
VarIds observedVids = {jointVars[0]->varId()};
|
||||
|
||||
for (unsigned i = 1; i < jointVarIds.size(); i++) {
|
||||
assert (jointVars[i]->hasEvidence() == false);
|
||||
Params newBeliefs;
|
||||
VarNodes observedVars;
|
||||
for (unsigned j = 0; j < observedVids.size(); j++) {
|
||||
observedVars.push_back (fg->getFgVarNode (observedVids[j]));
|
||||
}
|
||||
StatesIndexer idx (observedVars, false);
|
||||
while (idx.valid()) {
|
||||
for (unsigned j = 0; j < observedVars.size(); j++) {
|
||||
observedVars[j]->setEvidence (idx[j]);
|
||||
}
|
||||
++ idx;
|
||||
FgBpSolver solver (*fg);
|
||||
solver.runSolver();
|
||||
Params beliefs = solver.getPosterioriOf (jointVarIds[i]);
|
||||
for (unsigned k = 0; k < beliefs.size(); k++) {
|
||||
newBeliefs.push_back (beliefs[k]);
|
||||
}
|
||||
}
|
||||
|
||||
int count = -1;
|
||||
for (unsigned j = 0; j < newBeliefs.size(); j++) {
|
||||
if (j % jointVars[i]->nrStates() == 0) {
|
||||
count ++;
|
||||
}
|
||||
newBeliefs[j] *= prevBeliefs[count];
|
||||
}
|
||||
prevBeliefs = newBeliefs;
|
||||
observedVids.push_back (jointVars[i]->varId());
|
||||
}
|
||||
return prevBeliefs;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
FgBpSolver::printLinkInformation (void) const
|
||||
{
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "Solver.h"
|
||||
#include "Factor.h"
|
||||
#include "FactorGraph.h"
|
||||
#include "Util.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -52,8 +53,8 @@ class SpLink
|
||||
|
||||
FgFacNode* getFactor (void) const { return fac_; }
|
||||
FgVarNode* getVariable (void) const { return var_; }
|
||||
const ParamSet& getMessage (void) const { return *currMsg_; }
|
||||
ParamSet& getNextMessage (void) { return *nextMsg_; }
|
||||
const Params& getMessage (void) const { return *currMsg_; }
|
||||
Params& getNextMessage (void) { return *nextMsg_; }
|
||||
bool messageWasSended (void) const { return msgSended_; }
|
||||
double getResidual (void) const { return residual_; }
|
||||
void clearResidual (void) { residual_ = 0.0; }
|
||||
@ -61,10 +62,10 @@ class SpLink
|
||||
protected:
|
||||
FgFacNode* fac_;
|
||||
FgVarNode* var_;
|
||||
ParamSet v1_;
|
||||
ParamSet v2_;
|
||||
ParamSet* currMsg_;
|
||||
ParamSet* nextMsg_;
|
||||
Params v1_;
|
||||
Params v2_;
|
||||
Params* currMsg_;
|
||||
Params* nextMsg_;
|
||||
bool msgSended_;
|
||||
double residual_;
|
||||
};
|
||||
@ -91,15 +92,16 @@ class FgBpSolver : public Solver
|
||||
virtual ~FgBpSolver (void);
|
||||
|
||||
void runSolver (void);
|
||||
virtual ParamSet getPosterioriOf (VarId);
|
||||
virtual ParamSet getJointDistributionOf (const VarIdSet&);
|
||||
virtual Params getPosterioriOf (VarId);
|
||||
virtual Params getJointDistributionOf (const VarIds&);
|
||||
|
||||
protected:
|
||||
virtual void initializeSolver (void);
|
||||
virtual void createLinks (void);
|
||||
virtual void maxResidualSchedule (void);
|
||||
virtual void calculateFactor2VariableMsg (SpLink*) const;
|
||||
virtual ParamSet getVar2FactorMsg (const SpLink*) const;
|
||||
virtual Params getVar2FactorMsg (const SpLink*) const;
|
||||
virtual Params getJointByConditioning (const VarIds&) const;
|
||||
virtual void printLinkInformation (void) const;
|
||||
|
||||
void calculateAndUpdateMessage (SpLink* link, bool calcResidual = true)
|
||||
@ -163,8 +165,6 @@ class FgBpSolver : public Solver
|
||||
SpLinkMap linkMap_;
|
||||
|
||||
private:
|
||||
void runTreeSolver (void);
|
||||
bool readyToSendMessage (const SpLink*) const;
|
||||
void runLoopySolver (void);
|
||||
bool converged (void);
|
||||
|
||||
|
703
packages/CLPBN/clpbn/bp/FoveSolver.cpp
Normal file
703
packages/CLPBN/clpbn/bp/FoveSolver.cpp
Normal file
@ -0,0 +1,703 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <set>
|
||||
|
||||
#include "FoveSolver.h"
|
||||
#include "Histogram.h"
|
||||
#include "Util.h"
|
||||
|
||||
|
||||
vector<LiftedOperator*>
|
||||
LiftedOperator::getValidOps (ParfactorList& pfList, const Grounds& query)
|
||||
{
|
||||
vector<LiftedOperator*> validOps;
|
||||
vector<SumOutOperator*> sumOutOps;
|
||||
vector<CountingOperator*> countOps;
|
||||
vector<GroundOperator*> groundOps;
|
||||
|
||||
sumOutOps = SumOutOperator::getValidOps (pfList, query);
|
||||
countOps = CountingOperator::getValidOps (pfList);
|
||||
groundOps = GroundOperator::getValidOps (pfList);
|
||||
|
||||
validOps.insert (validOps.end(), sumOutOps.begin(), sumOutOps.end());
|
||||
validOps.insert (validOps.end(), countOps.begin(), countOps.end());
|
||||
validOps.insert (validOps.end(), groundOps.begin(), groundOps.end());
|
||||
return validOps;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
LiftedOperator::printValidOps (ParfactorList& pfList, const Grounds& query)
|
||||
{
|
||||
vector<LiftedOperator*> validOps;
|
||||
validOps = LiftedOperator::getValidOps (pfList, query);
|
||||
for (unsigned i = 0; i < validOps.size(); i++) {
|
||||
cout << "-> " << validOps[i]->toString() << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsigned
|
||||
SumOutOperator::getCost (void)
|
||||
{
|
||||
TinySet<unsigned> groupSet;
|
||||
ParfactorList::const_iterator pfIter = pfList_.begin();
|
||||
while (pfIter != pfList_.end()) {
|
||||
if ((*pfIter)->containsGroup (group_)) {
|
||||
vector<unsigned> groups = (*pfIter)->getAllGroups();
|
||||
groupSet |= TinySet<unsigned> (groups);
|
||||
}
|
||||
++ pfIter;
|
||||
}
|
||||
unsigned cost = 1;
|
||||
for (unsigned i = 0; i < groupSet.size(); i++) {
|
||||
pfIter = pfList_.begin();
|
||||
while (pfIter != pfList_.end()) {
|
||||
if ((*pfIter)->containsGroup (groupSet[i])) {
|
||||
int idx = (*pfIter)->indexOfFormulaWithGroup (groupSet[i]);
|
||||
cost *= (*pfIter)->range (idx);
|
||||
break;
|
||||
}
|
||||
++ pfIter;
|
||||
}
|
||||
}
|
||||
return cost;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
SumOutOperator::apply (void)
|
||||
{
|
||||
vector<ParfactorList::iterator> iters
|
||||
= parfactorsWithGroup (pfList_, group_);
|
||||
Parfactor* product = *(iters[0]);
|
||||
pfList_.remove (iters[0]);
|
||||
for (unsigned i = 1; i < iters.size(); i++) {
|
||||
product->multiply (**(iters[i]));
|
||||
delete *(iters[i]);
|
||||
pfList_.remove (iters[i]);
|
||||
}
|
||||
if (product->nrFormulas() == 1) {
|
||||
delete product;
|
||||
return;
|
||||
}
|
||||
int fIdx = product->indexOfFormulaWithGroup (group_);
|
||||
LogVarSet excl = product->exclusiveLogVars (fIdx);
|
||||
if (product->constr()->isCountNormalized (excl)) {
|
||||
product->sumOut (fIdx);
|
||||
pfList_.addShattered (product);
|
||||
} else {
|
||||
Parfactors pfs = FoveSolver::countNormalize (product, excl);
|
||||
for (unsigned i = 0; i < pfs.size(); i++) {
|
||||
pfs[i]->sumOut (fIdx);
|
||||
pfList_.add (pfs[i]);
|
||||
}
|
||||
delete product;
|
||||
pfList_.shatter();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
vector<SumOutOperator*>
|
||||
SumOutOperator::getValidOps (ParfactorList& pfList, const Grounds& query)
|
||||
{
|
||||
vector<SumOutOperator*> validOps;
|
||||
set<unsigned> allGroups;
|
||||
ParfactorList::const_iterator it = pfList.begin();
|
||||
while (it != pfList.end()) {
|
||||
assert (*it);
|
||||
const ProbFormulas& formulas = (*it)->formulas();
|
||||
for (unsigned i = 0; i < formulas.size(); i++) {
|
||||
allGroups.insert (formulas[i].group());
|
||||
}
|
||||
++ it;
|
||||
}
|
||||
set<unsigned>::const_iterator groupIt = allGroups.begin();
|
||||
while (groupIt != allGroups.end()) {
|
||||
if (validOp (*groupIt, pfList, query)) {
|
||||
validOps.push_back (new SumOutOperator (*groupIt, pfList));
|
||||
}
|
||||
++ groupIt;
|
||||
}
|
||||
return validOps;
|
||||
}
|
||||
|
||||
|
||||
|
||||
string
|
||||
SumOutOperator::toString (void)
|
||||
{
|
||||
stringstream ss;
|
||||
vector<ParfactorList::iterator> pfIters;
|
||||
pfIters = parfactorsWithGroup (pfList_, group_);
|
||||
int idx = (*pfIters[0])->indexOfFormulaWithGroup (group_);
|
||||
ProbFormula f = (*pfIters[0])->formula (idx);
|
||||
TupleSet tupleSet = (*pfIters[0])->constr()->tupleSet (f.logVars());
|
||||
ss << "sum out " << f.functor() << "/" << f.arity();
|
||||
ss << "|" << tupleSet << " (group " << group_ << ")";
|
||||
ss << " [cost=" << getCost() << "]" << endl;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
SumOutOperator::validOp (
|
||||
unsigned group,
|
||||
ParfactorList& pfList,
|
||||
const Grounds& query)
|
||||
{
|
||||
vector<ParfactorList::iterator> pfIters;
|
||||
pfIters = parfactorsWithGroup (pfList, group);
|
||||
if (isToEliminate (*pfIters[0], group, query) == false) {
|
||||
return false;
|
||||
}
|
||||
unordered_map<unsigned, unsigned> groupToRange;
|
||||
for (unsigned i = 0; i < pfIters.size(); i++) {
|
||||
int fIdx = (*pfIters[i])->indexOfFormulaWithGroup (group);
|
||||
if ((*pfIters[i])->formulas()[fIdx].contains (
|
||||
(*pfIters[i])->elimLogVars()) == false) {
|
||||
return false;
|
||||
}
|
||||
vector<unsigned> ranges = (*pfIters[i])->ranges();
|
||||
vector<unsigned> groups = (*pfIters[i])->getAllGroups();
|
||||
for (unsigned i = 0; i < groups.size(); i++) {
|
||||
unordered_map<unsigned, unsigned>::iterator it;
|
||||
it = groupToRange.find (groups[i]);
|
||||
if (it == groupToRange.end()) {
|
||||
groupToRange.insert (make_pair (groups[i], ranges[i]));
|
||||
} else {
|
||||
if (it->second != ranges[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
vector<ParfactorList::iterator>
|
||||
SumOutOperator::parfactorsWithGroup (
|
||||
ParfactorList& pfList,
|
||||
unsigned group)
|
||||
{
|
||||
vector<ParfactorList::iterator> iters;
|
||||
ParfactorList::iterator pflIt = pfList.begin();
|
||||
while (pflIt != pfList.end()) {
|
||||
if ((*pflIt)->containsGroup (group)) {
|
||||
iters.push_back (pflIt);
|
||||
}
|
||||
++ pflIt;
|
||||
}
|
||||
return iters;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
SumOutOperator::isToEliminate (
|
||||
Parfactor* g,
|
||||
unsigned group,
|
||||
const Grounds& query)
|
||||
{
|
||||
int fIdx = g->indexOfFormulaWithGroup (group);
|
||||
const ProbFormula& formula = g->formula (fIdx);
|
||||
bool toElim = true;
|
||||
for (unsigned i = 0; i < query.size(); i++) {
|
||||
if (formula.functor() == query[i].functor() &&
|
||||
formula.arity() == query[i].arity()) {
|
||||
g->constr()->moveToTop (formula.logVars());
|
||||
if (g->constr()->containsTuple (query[i].args())) {
|
||||
toElim = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return toElim;
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsigned
|
||||
CountingOperator::getCost (void)
|
||||
{
|
||||
unsigned cost = 0;
|
||||
int fIdx = (*pfIter_)->indexOfFormulaWithLogVar (X_);
|
||||
unsigned range = (*pfIter_)->range (fIdx);
|
||||
unsigned size = (*pfIter_)->size() / range;
|
||||
TinySet<unsigned> counts;
|
||||
counts = (*pfIter_)->constr()->getConditionalCounts (X_);
|
||||
for (unsigned i = 0; i < counts.size(); i++) {
|
||||
cost += size * HistogramSet::nrHistograms (counts[i], range);
|
||||
}
|
||||
return cost;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
CountingOperator::apply (void)
|
||||
{
|
||||
if ((*pfIter_)->constr()->isCountNormalized (X_)) {
|
||||
(*pfIter_)->countConvert (X_);
|
||||
} else {
|
||||
Parfactors pfs = FoveSolver::countNormalize (*pfIter_, X_);
|
||||
for (unsigned i = 0; i < pfs.size(); i++) {
|
||||
unsigned condCount = pfs[i]->constr()->getConditionalCount (X_);
|
||||
bool cartProduct = pfs[i]->constr()->isCarteesianProduct (
|
||||
(*pfIter_)->countedLogVars() | X_);
|
||||
if (condCount > 1 && cartProduct) {
|
||||
pfs[i]->countConvert (X_);
|
||||
}
|
||||
pfList_.add (pfs[i]);
|
||||
}
|
||||
pfList_.deleteAndRemove (pfIter_);
|
||||
pfList_.shatter();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
vector<CountingOperator*>
|
||||
CountingOperator::getValidOps (ParfactorList& pfList)
|
||||
{
|
||||
vector<CountingOperator*> validOps;
|
||||
ParfactorList::iterator it = pfList.begin();
|
||||
while (it != pfList.end()) {
|
||||
LogVarSet candidates = (*it)->uncountedLogVars();
|
||||
for (unsigned i = 0; i < candidates.size(); i++) {
|
||||
if (validOp (*it, candidates[i])) {
|
||||
validOps.push_back (new CountingOperator (
|
||||
it, candidates[i], pfList));
|
||||
}
|
||||
}
|
||||
++ it;
|
||||
}
|
||||
return validOps;
|
||||
}
|
||||
|
||||
|
||||
|
||||
string
|
||||
CountingOperator::toString (void)
|
||||
{
|
||||
stringstream ss;
|
||||
ss << "count convert " << X_ << " in " ;
|
||||
ss << (*pfIter_)->getHeaderString();
|
||||
ss << " [cost=" << getCost() << "]" << endl;
|
||||
Parfactors pfs = FoveSolver::countNormalize (*pfIter_, X_);
|
||||
if ((*pfIter_)->constr()->isCountNormalized (X_) == false) {
|
||||
for (unsigned i = 0; i < pfs.size(); i++) {
|
||||
ss << " º " << pfs[i]->getHeaderString() << endl;
|
||||
}
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
CountingOperator::validOp (Parfactor* g, LogVar X)
|
||||
{
|
||||
if (g->nrFormulas (X) != 1) {
|
||||
return false;
|
||||
}
|
||||
int fIdx = g->indexOfFormulaWithLogVar (X);
|
||||
if (g->formulas()[fIdx].isCounting()) {
|
||||
return false;
|
||||
}
|
||||
bool countNormalized = g->constr()->isCountNormalized (X);
|
||||
if (countNormalized) {
|
||||
unsigned condCount = g->constr()->getConditionalCount (X);
|
||||
bool cartProduct = g->constr()->isCarteesianProduct (
|
||||
g->countedLogVars() | X);
|
||||
if (condCount == 1 || cartProduct == false) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsigned
|
||||
GroundOperator::getCost (void)
|
||||
{
|
||||
unsigned cost = 0;
|
||||
bool isCountingLv = (*pfIter_)->countedLogVars().contains (X_);
|
||||
if (isCountingLv) {
|
||||
int fIdx = (*pfIter_)->indexOfFormulaWithLogVar (X_);
|
||||
unsigned currSize = (*pfIter_)->size();
|
||||
unsigned nrHists = (*pfIter_)->range (fIdx);
|
||||
unsigned range = (*pfIter_)->formula(fIdx).range();
|
||||
unsigned nrSymbols = (*pfIter_)->constr()->getConditionalCount (X_);
|
||||
cost = (currSize / nrHists) * (std::pow (range, nrSymbols));
|
||||
} else {
|
||||
cost = (*pfIter_)->constr()->nrSymbols (X_) * (*pfIter_)->size();
|
||||
}
|
||||
return cost;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
GroundOperator::apply (void)
|
||||
{
|
||||
bool countedLv = (*pfIter_)->countedLogVars().contains (X_);
|
||||
if (countedLv) {
|
||||
(*pfIter_)->fullExpand (X_);
|
||||
(*pfIter_)->setNewGroups();
|
||||
pfList_.shatter();
|
||||
} else {
|
||||
ConstraintTrees cts = (*pfIter_)->constr()->ground (X_);
|
||||
for (unsigned i = 0; i < cts.size(); i++) {
|
||||
Parfactor* newPf = new Parfactor (*pfIter_, cts[i]);
|
||||
pfList_.add (newPf);
|
||||
}
|
||||
pfList_.deleteAndRemove (pfIter_);
|
||||
pfList_.shatter();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
vector<GroundOperator*>
|
||||
GroundOperator::getValidOps (ParfactorList& pfList)
|
||||
{
|
||||
vector<GroundOperator*> validOps;
|
||||
ParfactorList::iterator pfIter = pfList.begin();
|
||||
while (pfIter != pfList.end()) {
|
||||
LogVarSet set = (*pfIter)->logVarSet();
|
||||
for (unsigned i = 0; i < set.size(); i++) {
|
||||
if ((*pfIter)->constr()->isSingleton (set[i]) == false) {
|
||||
validOps.push_back (new GroundOperator (pfIter, set[i], pfList));
|
||||
}
|
||||
}
|
||||
++ pfIter;
|
||||
}
|
||||
return validOps;
|
||||
}
|
||||
|
||||
|
||||
|
||||
string
|
||||
GroundOperator::toString (void)
|
||||
{
|
||||
stringstream ss;
|
||||
((*pfIter_)->countedLogVars().contains (X_))
|
||||
? ss << "full expanding "
|
||||
: ss << "grounding " ;
|
||||
ss << X_ << " in " << (*pfIter_)->getHeaderString();
|
||||
ss << " [cost=" << getCost() << "]" << endl;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
|
||||
|
||||
FoveSolver::FoveSolver (const ParfactorList* pfList)
|
||||
{
|
||||
for (ParfactorList::const_iterator it = pfList->begin();
|
||||
it != pfList->end();
|
||||
it ++) {
|
||||
pfList_.addShattered (new Parfactor (**it));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Params
|
||||
FoveSolver::getPosterioriOf (const Ground& query)
|
||||
{
|
||||
return getJointDistributionOf ({query});
|
||||
}
|
||||
|
||||
|
||||
|
||||
Params
|
||||
FoveSolver::getJointDistributionOf (const Grounds& query)
|
||||
{
|
||||
shatterAgainstQuery (query);
|
||||
runSolver (query);
|
||||
(*pfList_.begin())->normalize();
|
||||
Params params = (*pfList_.begin())->params();
|
||||
if (Globals::logDomain) {
|
||||
Util::fromLog (params);
|
||||
}
|
||||
delete *pfList_.begin();
|
||||
return params;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
FoveSolver::absorveEvidence (
|
||||
ParfactorList& pfList,
|
||||
const ObservedFormulas& obsFormulas)
|
||||
{
|
||||
ParfactorList::iterator it = pfList.begin();
|
||||
while (it != pfList.end()) {
|
||||
bool increment = true;
|
||||
for (unsigned i = 0; i < obsFormulas.size(); i++) {
|
||||
if (absorved (pfList, it, obsFormulas[i])) {
|
||||
it = pfList.deleteAndRemove (it);
|
||||
increment = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (increment) {
|
||||
++ it;
|
||||
}
|
||||
}
|
||||
pfList.shatter();
|
||||
if (obsFormulas.empty() == false) {
|
||||
cout << "*******************************************************" << endl;
|
||||
cout << "AFTER EVIDENCE ABSORVED" << endl;
|
||||
for (unsigned i = 0; i < obsFormulas.size(); i++) {
|
||||
cout << " -> " << *obsFormulas[i] << endl;
|
||||
}
|
||||
cout << "*******************************************************" << endl;
|
||||
}
|
||||
pfList.print();
|
||||
}
|
||||
|
||||
|
||||
|
||||
Parfactors
|
||||
FoveSolver::countNormalize (
|
||||
Parfactor* g,
|
||||
const LogVarSet& set)
|
||||
{
|
||||
if (set.empty()) {
|
||||
assert (false); // TODO
|
||||
return {};
|
||||
}
|
||||
Parfactors normPfs;
|
||||
ConstraintTrees normCts = g->constr()->countNormalize (set);
|
||||
for (unsigned i = 0; i < normCts.size(); i++) {
|
||||
normPfs.push_back (new Parfactor (g, normCts[i]));
|
||||
}
|
||||
return normPfs;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
FoveSolver::runSolver (const Grounds& query)
|
||||
{
|
||||
while (true) {
|
||||
cout << "---------------------------------------------------" << endl;
|
||||
pfList_.print();
|
||||
LiftedOperator::printValidOps (pfList_, query);
|
||||
LiftedOperator* op = getBestOperation (query);
|
||||
if (op == 0) {
|
||||
break;
|
||||
}
|
||||
cout << "best operation: " << op->toString() << endl;
|
||||
op->apply();
|
||||
}
|
||||
if (pfList_.size() > 1) {
|
||||
ParfactorList::iterator pfIter = pfList_.begin();
|
||||
pfIter ++;
|
||||
while (pfIter != pfList_.end()) {
|
||||
(*pfList_.begin())->multiply (**pfIter);
|
||||
++ pfIter;
|
||||
}
|
||||
}
|
||||
(*pfList_.begin())->reorderAccordingGrounds (query);
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
FoveSolver::allEliminated (const Grounds&)
|
||||
{
|
||||
ParfactorList::iterator pfIter = pfList_.begin();
|
||||
while (pfIter != pfList_.end()) {
|
||||
const ProbFormulas formulas = (*pfIter)->formulas();
|
||||
for (unsigned i = 0; i < formulas.size(); i++) {
|
||||
//bool toElim = false;
|
||||
//for (unsigned j = 0; j < queries.size(); j++) {
|
||||
// if ((*pfIter)->containsGround (queries[i]) == false) {
|
||||
// return
|
||||
// }
|
||||
}
|
||||
++ pfIter;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
LiftedOperator*
|
||||
FoveSolver::getBestOperation (const Grounds& query)
|
||||
{
|
||||
unsigned bestCost;
|
||||
LiftedOperator* bestOp = 0;
|
||||
vector<LiftedOperator*> validOps;
|
||||
validOps = LiftedOperator::getValidOps (pfList_, query);
|
||||
for (unsigned i = 0; i < validOps.size(); i++) {
|
||||
unsigned cost = validOps[i]->getCost();
|
||||
if ((bestOp == 0) || (cost < bestCost)) {
|
||||
bestOp = validOps[i];
|
||||
bestCost = cost;
|
||||
}
|
||||
}
|
||||
return bestOp;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
FoveSolver::shatterAgainstQuery (const Grounds& query)
|
||||
{
|
||||
// return;
|
||||
for (unsigned i = 0; i < query.size(); i++) {
|
||||
if (query[i].isAtom()) {
|
||||
continue;
|
||||
}
|
||||
ParfactorList pfListCopy = pfList_;
|
||||
pfList_.clear();
|
||||
for (ParfactorList::iterator it = pfListCopy.begin();
|
||||
it != pfListCopy.end(); ++ it) {
|
||||
Parfactor* pf = *it;
|
||||
if (pf->containsGround (query[i])) {
|
||||
std::pair<ConstraintTree*, ConstraintTree*> split =
|
||||
pf->constr()->split (query[i].args(), query[i].arity());
|
||||
ConstraintTree* commCt = split.first;
|
||||
ConstraintTree* exclCt = split.second;
|
||||
pfList_.add (new Parfactor (pf, commCt));
|
||||
if (exclCt->empty() == false) {
|
||||
pfList_.add (new Parfactor (pf, exclCt));
|
||||
} else {
|
||||
delete exclCt;
|
||||
}
|
||||
delete pf;
|
||||
} else {
|
||||
pfList_.add (pf);
|
||||
}
|
||||
}
|
||||
pfList_.shatter();
|
||||
}
|
||||
cout << endl;
|
||||
cout << "*******************************************************" << endl;
|
||||
cout << "SHATTERED AGAINST THE QUERY" << endl;
|
||||
for (unsigned i = 0; i < query.size(); i++) {
|
||||
cout << " -> " << query[i] << endl;
|
||||
}
|
||||
cout << "*******************************************************" << endl;
|
||||
pfList_.print();
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
FoveSolver::absorved (
|
||||
ParfactorList& pfList,
|
||||
ParfactorList::iterator pfIter,
|
||||
const ObservedFormula* obsFormula)
|
||||
{
|
||||
Parfactors absorvedPfs;
|
||||
Parfactor* g = *pfIter;
|
||||
const ProbFormulas& formulas = g->formulas();
|
||||
for (unsigned i = 0; i < formulas.size(); i++) {
|
||||
if (obsFormula->functor() == formulas[i].functor() &&
|
||||
obsFormula->arity() == formulas[i].arity()) {
|
||||
|
||||
if (obsFormula->isAtom()) {
|
||||
if (formulas.size() > 1) {
|
||||
g->absorveEvidence (i, obsFormula->evidence());
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
g->constr()->moveToTop (formulas[i].logVars());
|
||||
std::pair<ConstraintTree*, ConstraintTree*> res
|
||||
= g->constr()->split (obsFormula->constr(), formulas[i].arity());
|
||||
ConstraintTree* commCt = res.first;
|
||||
ConstraintTree* exclCt = res.second;
|
||||
|
||||
if (commCt->empty()) {
|
||||
delete commCt;
|
||||
delete exclCt;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (exclCt->empty() == false) {
|
||||
pfList.add (new Parfactor (g, exclCt));
|
||||
} else {
|
||||
delete exclCt;
|
||||
}
|
||||
|
||||
if (formulas.size() > 1) {
|
||||
LogVarSet excl = g->exclusiveLogVars (i);
|
||||
Parfactors countNormPfs = countNormalize (g, excl);
|
||||
for (unsigned j = 0; j < countNormPfs.size(); j++) {
|
||||
countNormPfs[j]->absorveEvidence (i, obsFormula->evidence());
|
||||
absorvedPfs.push_back (countNormPfs[j]);
|
||||
}
|
||||
} else {
|
||||
delete commCt;
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
FoveSolver::proper (
|
||||
const ProbFormula& f1,
|
||||
ConstraintTree* c1,
|
||||
const ProbFormula& f2,
|
||||
ConstraintTree* c2)
|
||||
{
|
||||
return disjoint (f1, c1, f2, c2)
|
||||
|| identical (f1, c1, f2, c2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
FoveSolver::identical (
|
||||
const ProbFormula& f1,
|
||||
ConstraintTree* c1,
|
||||
const ProbFormula& f2,
|
||||
ConstraintTree* c2)
|
||||
{
|
||||
if (f1.sameSkeletonAs (f2) == false) {
|
||||
return false;
|
||||
}
|
||||
c1->moveToTop (f1.logVars());
|
||||
c2->moveToTop (f2.logVars());
|
||||
return ConstraintTree::identical (
|
||||
c1, c2, f1.logVars().size());
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
FoveSolver::disjoint (
|
||||
const ProbFormula& f1,
|
||||
ConstraintTree* c1,
|
||||
const ProbFormula& f2,
|
||||
ConstraintTree* c2)
|
||||
{
|
||||
if (f1.sameSkeletonAs (f2) == false) {
|
||||
return true;
|
||||
}
|
||||
c1->moveToTop (f1.logVars());
|
||||
c2->moveToTop (f2.logVars());
|
||||
return ConstraintTree::overlap (
|
||||
c1, c2, f1.arity()) == false;
|
||||
}
|
||||
|
132
packages/CLPBN/clpbn/bp/FoveSolver.h
Normal file
132
packages/CLPBN/clpbn/bp/FoveSolver.h
Normal file
@ -0,0 +1,132 @@
|
||||
#ifndef HORUS_FOVESOLVER_H
|
||||
#define HORUS_FOVESOLVER_H
|
||||
|
||||
|
||||
#include "ParfactorList.h"
|
||||
|
||||
|
||||
class LiftedOperator
|
||||
{
|
||||
public:
|
||||
virtual unsigned getCost (void) = 0;
|
||||
virtual void apply (void) = 0;
|
||||
virtual string toString (void) = 0;
|
||||
static vector<LiftedOperator*> getValidOps (
|
||||
ParfactorList&, const Grounds&);
|
||||
static void printValidOps (ParfactorList&, const Grounds&);
|
||||
};
|
||||
|
||||
|
||||
|
||||
class SumOutOperator : public LiftedOperator
|
||||
{
|
||||
public:
|
||||
SumOutOperator (unsigned group, ParfactorList& pfList)
|
||||
: group_(group), pfList_(pfList) { }
|
||||
unsigned getCost (void);
|
||||
void apply (void);
|
||||
static vector<SumOutOperator*> getValidOps (
|
||||
ParfactorList&, const Grounds&);
|
||||
string toString (void);
|
||||
private:
|
||||
static bool validOp (unsigned, ParfactorList&, const Grounds&);
|
||||
static vector<ParfactorList::iterator> parfactorsWithGroup (
|
||||
ParfactorList& pfList, unsigned group);
|
||||
static bool isToEliminate (Parfactor*, unsigned, const Grounds&);
|
||||
unsigned group_;
|
||||
ParfactorList& pfList_;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class CountingOperator : public LiftedOperator
|
||||
{
|
||||
public:
|
||||
CountingOperator (
|
||||
ParfactorList::iterator pfIter,
|
||||
LogVar X,
|
||||
ParfactorList& pfList)
|
||||
: pfIter_(pfIter), X_(X), pfList_(pfList) { }
|
||||
unsigned getCost (void);
|
||||
void apply (void);
|
||||
static vector<CountingOperator*> getValidOps (ParfactorList&);
|
||||
string toString (void);
|
||||
private:
|
||||
static bool validOp (Parfactor*, LogVar);
|
||||
ParfactorList::iterator pfIter_;
|
||||
LogVar X_;
|
||||
ParfactorList& pfList_;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class GroundOperator : public LiftedOperator
|
||||
{
|
||||
public:
|
||||
GroundOperator (
|
||||
ParfactorList::iterator pfIter,
|
||||
LogVar X,
|
||||
ParfactorList& pfList)
|
||||
: pfIter_(pfIter), X_(X), pfList_(pfList) { }
|
||||
unsigned getCost (void);
|
||||
void apply (void);
|
||||
static vector<GroundOperator*> getValidOps (ParfactorList&);
|
||||
string toString (void);
|
||||
private:
|
||||
ParfactorList::iterator pfIter_;
|
||||
LogVar X_;
|
||||
ParfactorList& pfList_;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class FoveSolver
|
||||
{
|
||||
public:
|
||||
FoveSolver (const ParfactorList*);
|
||||
|
||||
Params getPosterioriOf (const Ground&);
|
||||
Params getJointDistributionOf (const Grounds&);
|
||||
|
||||
static void absorveEvidence (
|
||||
ParfactorList& pfList,
|
||||
const ObservedFormulas& obsFormulas);
|
||||
|
||||
static Parfactors countNormalize (Parfactor*, const LogVarSet&);
|
||||
|
||||
private:
|
||||
void runSolver (const Grounds&);
|
||||
bool allEliminated (const Grounds&);
|
||||
LiftedOperator* getBestOperation (const Grounds&);
|
||||
void shatterAgainstQuery (const Grounds&);
|
||||
|
||||
static bool absorved (
|
||||
ParfactorList& pfList,
|
||||
ParfactorList::iterator pfIter,
|
||||
const ObservedFormula*);
|
||||
|
||||
public:
|
||||
|
||||
static bool proper (
|
||||
const ProbFormula&,
|
||||
ConstraintTree*,
|
||||
const ProbFormula&,
|
||||
ConstraintTree*);
|
||||
|
||||
static bool identical (
|
||||
const ProbFormula&,
|
||||
ConstraintTree*,
|
||||
const ProbFormula&,
|
||||
ConstraintTree*);
|
||||
|
||||
static bool disjoint (
|
||||
const ProbFormula&,
|
||||
ConstraintTree*,
|
||||
const ProbFormula&,
|
||||
ConstraintTree*);
|
||||
|
||||
ParfactorList pfList_;
|
||||
};
|
||||
|
||||
#endif // HORUS_FOVESOLVER_H
|
||||
|
@ -1,11 +1,15 @@
|
||||
#ifndef HORUS_GRAPHICALMODEL_H
|
||||
#define HORUS_GRAPHICALMODEL_H
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include "VarNode.h"
|
||||
#include "Shared.h"
|
||||
#include "Distribution.h"
|
||||
#include "Horus.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
struct VariableInfo
|
||||
{
|
||||
VariableInfo (string l, const States& sts)
|
||||
@ -45,9 +49,18 @@ class GraphicalModel
|
||||
{
|
||||
varsInfo_.clear();
|
||||
}
|
||||
static void addDistribution (unsigned id, Distribution* dist)
|
||||
{
|
||||
distsInfo_[id] = dist;
|
||||
}
|
||||
static void updateDistribution (unsigned id, const Params& params)
|
||||
{
|
||||
distsInfo_[id]->updateParameters (params);
|
||||
}
|
||||
|
||||
private:
|
||||
static unordered_map<VarId,VariableInfo> varsInfo_;
|
||||
static unordered_map<unsigned,Distribution*> distsInfo_;
|
||||
};
|
||||
|
||||
#endif // HORUS_GRAPHICALMODEL_H
|
||||
|
126
packages/CLPBN/clpbn/bp/Histogram.cpp
Normal file
126
packages/CLPBN/clpbn/bp/Histogram.cpp
Normal file
@ -0,0 +1,126 @@
|
||||
#include <cassert>
|
||||
|
||||
#include <algorithm>
|
||||
#include <numeric>
|
||||
|
||||
#include "Histogram.h"
|
||||
#include "Util.h"
|
||||
|
||||
|
||||
HistogramSet::HistogramSet (unsigned size, unsigned range)
|
||||
{
|
||||
size_ = size;
|
||||
hist_.resize (range, 0);
|
||||
hist_[0] = size;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
HistogramSet::nextHistogram (void)
|
||||
{
|
||||
for (int i = hist_.size() - 2; i >= 0; i--) {
|
||||
if (hist_[i] > 0) {
|
||||
hist_[i] --;
|
||||
hist_[i + 1] = maxCount (i + 1);
|
||||
clearAfter (i + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert (std::accumulate (hist_.begin(), hist_.end(), 0) == (int)size_);
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsigned
|
||||
HistogramSet::operator[] (unsigned idx) const
|
||||
{
|
||||
assert (idx < hist_.size());
|
||||
return hist_[idx];
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsigned
|
||||
HistogramSet::nrHistograms (void) const
|
||||
{
|
||||
return Util::nrCombinations (size_ + hist_.size() - 1, hist_.size() - 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
HistogramSet::reset (void)
|
||||
{
|
||||
std::fill (hist_.begin() + 1, hist_.end(), 0);
|
||||
hist_[0] = size_;
|
||||
}
|
||||
|
||||
|
||||
|
||||
vector<Histogram>
|
||||
HistogramSet::getHistograms (unsigned N, unsigned R)
|
||||
{
|
||||
HistogramSet hs (N, R);
|
||||
unsigned H = hs.nrHistograms();
|
||||
vector<Histogram> histograms;
|
||||
histograms.reserve (H);
|
||||
for (unsigned i = 0; i < H; i++) {
|
||||
histograms.push_back (hs.hist_);
|
||||
hs.nextHistogram();
|
||||
}
|
||||
return histograms;
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsigned
|
||||
HistogramSet::nrHistograms (unsigned N, unsigned R)
|
||||
{
|
||||
return Util::nrCombinations (N + R - 1, R - 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsigned
|
||||
HistogramSet::findIndex (
|
||||
const Histogram& hist,
|
||||
const vector<Histogram>& histograms)
|
||||
{
|
||||
vector<Histogram>::const_iterator it = std::lower_bound (
|
||||
histograms.begin(),
|
||||
histograms.end(),
|
||||
hist,
|
||||
std::greater<Histogram>());
|
||||
assert (it != histograms.end() && *it == hist);
|
||||
return std::distance (histograms.begin(), it);
|
||||
}
|
||||
|
||||
|
||||
|
||||
ostream& operator<< (ostream &os, const HistogramSet& hs)
|
||||
{
|
||||
os << "#" << hs.hist_;
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsigned
|
||||
HistogramSet::maxCount (unsigned idx) const
|
||||
{
|
||||
unsigned sum = 0;
|
||||
for (unsigned i = 0; i < idx; i++) {
|
||||
sum += hist_[i];
|
||||
}
|
||||
return size_ - sum;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
HistogramSet::clearAfter (unsigned idx)
|
||||
{
|
||||
std::fill (hist_.begin() + idx + 1, hist_.end(), 0);
|
||||
}
|
||||
|
44
packages/CLPBN/clpbn/bp/Histogram.h
Normal file
44
packages/CLPBN/clpbn/bp/Histogram.h
Normal file
@ -0,0 +1,44 @@
|
||||
#ifndef HORUS_HISTOGRAM_H
|
||||
#define HORUS_HISTOGRAM_H
|
||||
|
||||
#include <vector>
|
||||
#include <ostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
typedef vector<unsigned> Histogram;
|
||||
|
||||
class HistogramSet
|
||||
{
|
||||
public:
|
||||
HistogramSet (unsigned, unsigned);
|
||||
|
||||
void nextHistogram (void);
|
||||
|
||||
unsigned operator[] (unsigned idx) const;
|
||||
|
||||
unsigned nrHistograms (void) const;
|
||||
|
||||
void reset (void);
|
||||
|
||||
static vector<Histogram> getHistograms (unsigned ,unsigned);
|
||||
|
||||
static unsigned nrHistograms (unsigned, unsigned);
|
||||
|
||||
static unsigned findIndex (
|
||||
const Histogram&,
|
||||
const vector<Histogram>&);
|
||||
|
||||
friend std::ostream& operator<< (ostream &os, const HistogramSet& hs);
|
||||
|
||||
private:
|
||||
unsigned maxCount (unsigned) const;
|
||||
|
||||
void clearAfter (unsigned);
|
||||
|
||||
unsigned size_;
|
||||
Histogram hist_;
|
||||
};
|
||||
|
||||
#endif // HORUS_HISTOGRAM_H
|
||||
|
88
packages/CLPBN/clpbn/bp/Horus.h
Normal file
88
packages/CLPBN/clpbn/bp/Horus.h
Normal file
@ -0,0 +1,88 @@
|
||||
#ifndef HORUS_HORUS_H
|
||||
#define HORUS_HORUS_H
|
||||
|
||||
#include <cmath>
|
||||
#include <cassert>
|
||||
#include <limits>
|
||||
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
|
||||
TypeName(const TypeName&); \
|
||||
void operator=(const TypeName&)
|
||||
|
||||
using namespace std;
|
||||
|
||||
class VarNode;
|
||||
class BayesNode;
|
||||
class FgVarNode;
|
||||
class FgFacNode;
|
||||
class Factor;
|
||||
|
||||
typedef vector<double> Params;
|
||||
typedef unsigned VarId;
|
||||
typedef vector<VarId> VarIds;
|
||||
typedef vector<VarNode*> VarNodes;
|
||||
typedef vector<BayesNode*> BnNodeSet;
|
||||
typedef vector<FgVarNode*> FgVarSet;
|
||||
typedef vector<FgFacNode*> FgFacSet;
|
||||
typedef vector<Factor*> FactorSet;
|
||||
typedef vector<string> States;
|
||||
typedef vector<unsigned> Ranges;
|
||||
|
||||
|
||||
namespace Globals {
|
||||
extern bool logDomain;
|
||||
};
|
||||
|
||||
|
||||
// level of debug information
|
||||
static const unsigned DL = 1;
|
||||
|
||||
static const int NO_EVIDENCE = -1;
|
||||
|
||||
// number of digits to show when printing a parameter
|
||||
static const unsigned PRECISION = 5;
|
||||
|
||||
static const bool COLLECT_STATISTICS = false;
|
||||
|
||||
static const bool EXPORT_TO_GRAPHVIZ = false;
|
||||
static const unsigned EXPORT_MINIMAL_SIZE = 100;
|
||||
|
||||
static const double INF = -numeric_limits<double>::infinity();
|
||||
|
||||
|
||||
|
||||
namespace InfAlgorithms {
|
||||
enum InfAlgs
|
||||
{
|
||||
VE, // variable elimination
|
||||
BN_BP, // bayesian network belief propagation
|
||||
FG_BP, // factor graph belief propagation
|
||||
CBP // counting bp solver
|
||||
};
|
||||
extern InfAlgs infAlgorithm;
|
||||
};
|
||||
|
||||
|
||||
namespace BpOptions
|
||||
{
|
||||
enum Schedule {
|
||||
SEQ_FIXED,
|
||||
SEQ_RANDOM,
|
||||
PARALLEL,
|
||||
MAX_RESIDUAL
|
||||
};
|
||||
extern Schedule schedule;
|
||||
extern double accuracy;
|
||||
extern unsigned maxIter;
|
||||
}
|
||||
|
||||
#endif // HORUS_HORUS_H
|
||||
|
@ -10,7 +10,9 @@
|
||||
#include "FgBpSolver.h"
|
||||
#include "CbpSolver.h"
|
||||
|
||||
#include "StatesIndexer.h"
|
||||
//#include "TinySet.h"
|
||||
#include "LiftedUtils.h"
|
||||
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -22,9 +24,38 @@ const string USAGE = "usage: \
|
||||
./hcli FILE [VARIABLE | OBSERVED_VARIABLE=EVIDENCE]..." ;
|
||||
|
||||
|
||||
class Cenas
|
||||
{
|
||||
public:
|
||||
Cenas (int cc)
|
||||
{
|
||||
c = cc;
|
||||
}
|
||||
//operator int (void) const
|
||||
//{
|
||||
// cout << "return int" << endl;
|
||||
// return c;
|
||||
//}
|
||||
operator double (void) const
|
||||
{
|
||||
cout << "return double" << endl;
|
||||
return 0.0;
|
||||
}
|
||||
private:
|
||||
int c;
|
||||
};
|
||||
|
||||
|
||||
int
|
||||
main (int argc, const char* argv[])
|
||||
{
|
||||
LogVar X = 3;
|
||||
LogVarSet Xs = X;
|
||||
cout << "set: " << X << endl;
|
||||
Cenas c1 (1);
|
||||
Cenas c2 (3);
|
||||
cout << (c1 < c2) << endl;
|
||||
return 0;
|
||||
if (!argv[1]) {
|
||||
cerr << "error: no graphical model specified" << endl;
|
||||
cerr << USAGE << endl;
|
||||
@ -121,7 +152,6 @@ processArguments (BayesNet& bn, int argc, const char* argv[])
|
||||
break;
|
||||
case InfAlgorithms::FG_BP:
|
||||
fg = new FactorGraph (bn);
|
||||
fg->printGraphicalModel();
|
||||
solver = new FgBpSolver (*fg);
|
||||
break;
|
||||
case InfAlgorithms::CBP:
|
||||
@ -230,6 +260,9 @@ processArguments (FactorGraph& fg, int argc, const char* argv[])
|
||||
break;
|
||||
case InfAlgorithms::BN_BP:
|
||||
case InfAlgorithms::FG_BP:
|
||||
//cout << "here!" << endl;
|
||||
//fg.printGraphicalModel();
|
||||
//fg.exportToLibDaiFormat ("net.fg");
|
||||
solver = new FgBpSolver (fg);
|
||||
break;
|
||||
case InfAlgorithms::CBP:
|
||||
@ -247,7 +280,7 @@ processArguments (FactorGraph& fg, int argc, const char* argv[])
|
||||
void
|
||||
runSolver (Solver* solver, const VarNodes& queryVars)
|
||||
{
|
||||
VarIdSet vids;
|
||||
VarIds vids;
|
||||
for (unsigned i = 0; i < queryVars.size(); i++) {
|
||||
vids.push_back (queryVars[i]->varId());
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include <cstdlib>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <iostream>
|
||||
@ -13,12 +14,169 @@
|
||||
#include "FgBpSolver.h"
|
||||
#include "CbpSolver.h"
|
||||
#include "ElimGraph.h"
|
||||
#include "FoveSolver.h"
|
||||
#include "ParfactorList.h"
|
||||
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
|
||||
Params readParams (YAP_Term);
|
||||
|
||||
|
||||
int createLiftedNetwork (void)
|
||||
{
|
||||
Parfactors parfactors;
|
||||
YAP_Term parfactorList = YAP_ARG1;
|
||||
while (parfactorList != YAP_TermNil()) {
|
||||
YAP_Term parfactor = YAP_HeadOfTerm (parfactorList);
|
||||
|
||||
// read dist id
|
||||
unsigned distId = YAP_IntOfTerm (YAP_ArgOfTerm (1, parfactor));
|
||||
|
||||
// read the ranges
|
||||
Ranges ranges;
|
||||
YAP_Term rangeList = YAP_ArgOfTerm (3, parfactor);
|
||||
while (rangeList != YAP_TermNil()) {
|
||||
unsigned range = (unsigned) YAP_IntOfTerm (YAP_HeadOfTerm (rangeList));
|
||||
ranges.push_back (range);
|
||||
rangeList = YAP_TailOfTerm (rangeList);
|
||||
}
|
||||
|
||||
// read parametric random vars
|
||||
ProbFormulas formulas;
|
||||
unsigned count = 0;
|
||||
unordered_map<YAP_Term, LogVar> lvMap;
|
||||
YAP_Term pvList = YAP_ArgOfTerm (2, parfactor);
|
||||
while (pvList != YAP_TermNil()) {
|
||||
YAP_Term formulaTerm = YAP_HeadOfTerm (pvList);
|
||||
if (YAP_IsAtomTerm (formulaTerm)) {
|
||||
string name ((char*) YAP_AtomName (YAP_AtomOfTerm (formulaTerm)));
|
||||
Symbol functor = LiftedUtils::getSymbol (name);
|
||||
formulas.push_back (ProbFormula (functor, ranges[count]));
|
||||
} else {
|
||||
LogVars logVars;
|
||||
YAP_Functor yapFunctor = YAP_FunctorOfTerm (formulaTerm);
|
||||
string name ((char*) YAP_AtomName (YAP_NameOfFunctor (yapFunctor)));
|
||||
Symbol functor = LiftedUtils::getSymbol (name);
|
||||
unsigned arity = (unsigned) YAP_ArityOfFunctor (yapFunctor);
|
||||
for (unsigned i = 1; i <= arity; i++) {
|
||||
YAP_Term ti = YAP_ArgOfTerm (i, formulaTerm);
|
||||
unordered_map<YAP_Term, LogVar>::iterator it = lvMap.find (ti);
|
||||
if (it != lvMap.end()) {
|
||||
logVars.push_back (it->second);
|
||||
} else {
|
||||
unsigned newLv = lvMap.size();
|
||||
lvMap[ti] = newLv;
|
||||
logVars.push_back (newLv);
|
||||
}
|
||||
}
|
||||
formulas.push_back (ProbFormula (functor, logVars, ranges[count]));
|
||||
}
|
||||
count ++;
|
||||
pvList = YAP_TailOfTerm (pvList);
|
||||
}
|
||||
|
||||
// read the parameters
|
||||
const Params& params = readParams (YAP_ArgOfTerm (4, parfactor));
|
||||
|
||||
// read the constraint
|
||||
Tuples tuples;
|
||||
if (lvMap.size() >= 1) {
|
||||
YAP_Term tupleList = YAP_ArgOfTerm (5, parfactor);
|
||||
while (tupleList != YAP_TermNil()) {
|
||||
YAP_Term term = YAP_HeadOfTerm (tupleList);
|
||||
assert (YAP_IsApplTerm (term));
|
||||
YAP_Functor yapFunctor = YAP_FunctorOfTerm (term);
|
||||
unsigned arity = (unsigned) YAP_ArityOfFunctor (yapFunctor);
|
||||
assert (lvMap.size() == arity);
|
||||
Tuple tuple (arity);
|
||||
for (unsigned i = 1; i <= arity; i++) {
|
||||
YAP_Term ti = YAP_ArgOfTerm (i, term);
|
||||
if (YAP_IsAtomTerm (ti) == false) {
|
||||
cerr << "error: bad formed constraint" << endl;
|
||||
abort();
|
||||
}
|
||||
string name ((char*) YAP_AtomName (YAP_AtomOfTerm (ti)));
|
||||
tuple[i - 1] = LiftedUtils::getSymbol (name);
|
||||
}
|
||||
tuples.push_back (tuple);
|
||||
tupleList = YAP_TailOfTerm (tupleList);
|
||||
}
|
||||
}
|
||||
parfactors.push_back (new Parfactor (formulas, params, tuples, distId));
|
||||
parfactorList = YAP_TailOfTerm (parfactorList);
|
||||
}
|
||||
|
||||
// LiftedUtils::printSymbolDictionary();
|
||||
cout << "*******************************************************" << endl;
|
||||
cout << "INITIAL PARFACTORS" << endl;
|
||||
cout << "*******************************************************" << endl;
|
||||
for (unsigned i = 0; i < parfactors.size(); i++) {
|
||||
parfactors[i]->print();
|
||||
cout << endl;
|
||||
}
|
||||
ParfactorList* pfList = new ParfactorList();
|
||||
for (unsigned i = 0; i < parfactors.size(); i++) {
|
||||
pfList->add (parfactors[i]);
|
||||
}
|
||||
cout << endl;
|
||||
cout << "*******************************************************" << endl;
|
||||
cout << "SHATTERED PARFACTORS" << endl;
|
||||
cout << "*******************************************************" << endl;
|
||||
pfList->shatter();
|
||||
pfList->print();
|
||||
|
||||
// insert the evidence
|
||||
ObservedFormulas obsFormulas;
|
||||
YAP_Term observedList = YAP_ARG2;
|
||||
while (observedList != YAP_TermNil()) {
|
||||
YAP_Term pair = YAP_HeadOfTerm (observedList);
|
||||
YAP_Term ground = YAP_ArgOfTerm (1, pair);
|
||||
Symbol functor;
|
||||
Symbols args;
|
||||
if (YAP_IsAtomTerm (ground)) {
|
||||
string name ((char*) YAP_AtomName (YAP_AtomOfTerm (ground)));
|
||||
functor = LiftedUtils::getSymbol (name);
|
||||
} else {
|
||||
assert (YAP_IsApplTerm (ground));
|
||||
YAP_Functor yapFunctor = YAP_FunctorOfTerm (ground);
|
||||
string name ((char*) (YAP_AtomName (YAP_NameOfFunctor (yapFunctor))));
|
||||
functor = LiftedUtils::getSymbol (name);
|
||||
unsigned arity = (unsigned) YAP_ArityOfFunctor (yapFunctor);
|
||||
for (unsigned i = 1; i <= arity; i++) {
|
||||
YAP_Term ti = YAP_ArgOfTerm (i, ground);
|
||||
assert (YAP_IsAtomTerm (ti));
|
||||
string arg ((char *) YAP_AtomName (YAP_AtomOfTerm (ti)));
|
||||
args.push_back (LiftedUtils::getSymbol (arg));
|
||||
}
|
||||
}
|
||||
unsigned evidence = (unsigned) YAP_IntOfTerm (YAP_ArgOfTerm (2, pair));
|
||||
bool found = false;
|
||||
for (unsigned i = 0; i < obsFormulas.size(); i++) {
|
||||
if (obsFormulas[i]->functor() == functor &&
|
||||
obsFormulas[i]->arity() == args.size() &&
|
||||
obsFormulas[i]->evidence() == evidence) {
|
||||
obsFormulas[i]->addTuple (args);
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if (found == false) {
|
||||
obsFormulas.push_back (new ObservedFormula (functor, evidence, args));
|
||||
}
|
||||
observedList = YAP_TailOfTerm (observedList);
|
||||
}
|
||||
FoveSolver::absorveEvidence (*pfList, obsFormulas);
|
||||
|
||||
YAP_Int p = (YAP_Int) (pfList);
|
||||
return YAP_Unify (YAP_MkIntTerm (p), YAP_ARG3);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
createNetwork (void)
|
||||
createGroundNetwork (void)
|
||||
{
|
||||
Statistics::incrementPrimaryNetworksCounting();
|
||||
// cout << "creating network number " ;
|
||||
@ -29,15 +187,15 @@ createNetwork (void)
|
||||
BayesNet* bn = new BayesNet();
|
||||
YAP_Term varList = YAP_ARG1;
|
||||
BnNodeSet nodes;
|
||||
vector<VarIdSet> parents;
|
||||
vector<VarIds> parents;
|
||||
while (varList != YAP_TermNil()) {
|
||||
YAP_Term var = YAP_HeadOfTerm (varList);
|
||||
VarId vid = (VarId) YAP_IntOfTerm (YAP_ArgOfTerm (1, var));
|
||||
unsigned dsize = (unsigned) YAP_IntOfTerm (YAP_ArgOfTerm (2, var));
|
||||
int evidence = (int) YAP_IntOfTerm (YAP_ArgOfTerm (3, var));
|
||||
YAP_Term parentL = YAP_ArgOfTerm (4, var);
|
||||
unsigned distId = (unsigned) YAP_IntOfTerm (YAP_ArgOfTerm (5, var));
|
||||
parents.push_back (VarIdSet());
|
||||
VarId vid = (VarId) YAP_IntOfTerm (YAP_ArgOfTerm (1, var));
|
||||
unsigned dsize = (unsigned) YAP_IntOfTerm (YAP_ArgOfTerm (2, var));
|
||||
int evidence = (int) YAP_IntOfTerm (YAP_ArgOfTerm (3, var));
|
||||
YAP_Term parentL = YAP_ArgOfTerm (4, var);
|
||||
unsigned distId = (unsigned) YAP_IntOfTerm (YAP_ArgOfTerm (5, var));
|
||||
parents.push_back (VarIds());
|
||||
while (parentL != YAP_TermNil()) {
|
||||
unsigned parentId = (unsigned) YAP_IntOfTerm (YAP_HeadOfTerm (parentL));
|
||||
parents.back().push_back (parentId);
|
||||
@ -67,6 +225,211 @@ createNetwork (void)
|
||||
|
||||
|
||||
|
||||
int
|
||||
setBayesNetParams (void)
|
||||
{
|
||||
BayesNet* bn = (BayesNet*) YAP_IntOfTerm (YAP_ARG1);
|
||||
YAP_Term distList = YAP_ARG2;
|
||||
while (distList != YAP_TermNil()) {
|
||||
YAP_Term dist = YAP_HeadOfTerm (distList);
|
||||
unsigned distId = (unsigned) YAP_IntOfTerm (YAP_ArgOfTerm (1, dist));
|
||||
const Params params = readParams (YAP_ArgOfTerm (2, dist));
|
||||
bn->getDistribution(distId)->updateParameters (params);
|
||||
distList = YAP_TailOfTerm (distList);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
setParfactorGraphParams (void)
|
||||
{
|
||||
// FIXME
|
||||
// ParfactorGraph* pfg = (ParfactorGraph*) YAP_IntOfTerm (YAP_ARG1);
|
||||
YAP_Term distList = YAP_ARG2;
|
||||
while (distList != YAP_TermNil()) {
|
||||
// YAP_Term dist = YAP_HeadOfTerm (distList);
|
||||
// unsigned distId = (unsigned) YAP_IntOfTerm (YAP_ArgOfTerm (1, dist));
|
||||
// const Params params = readParams (YAP_ArgOfTerm (2, dist));
|
||||
// pfg->getDistribution(distId)->setData (params);
|
||||
distList = YAP_TailOfTerm (distList);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Params
|
||||
readParams (YAP_Term paramL)
|
||||
{
|
||||
Params params;
|
||||
while (paramL!= YAP_TermNil()) {
|
||||
params.push_back ((double) YAP_FloatOfTerm (YAP_HeadOfTerm (paramL)));
|
||||
paramL = YAP_TailOfTerm (paramL);
|
||||
}
|
||||
if (Globals::logDomain) {
|
||||
Util::toLog (params);
|
||||
}
|
||||
return params;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
runLiftedSolver (void)
|
||||
{
|
||||
ParfactorList* pfList = (ParfactorList*) YAP_IntOfTerm (YAP_ARG1);
|
||||
YAP_Term taskList = YAP_ARG2;
|
||||
vector<Params> results;
|
||||
|
||||
while (taskList != YAP_TermNil()) {
|
||||
YAP_Term jointList = YAP_HeadOfTerm (taskList);
|
||||
Grounds queryVars;
|
||||
assert (YAP_IsPairTerm (taskList));
|
||||
assert (YAP_IsPairTerm (jointList));
|
||||
while (jointList != YAP_TermNil()) {
|
||||
YAP_Term ground = YAP_HeadOfTerm (jointList);
|
||||
if (YAP_IsAtomTerm (ground)) {
|
||||
string name ((char*) YAP_AtomName (YAP_AtomOfTerm (ground)));
|
||||
queryVars.push_back (Ground (LiftedUtils::getSymbol (name)));
|
||||
} else {
|
||||
assert (YAP_IsApplTerm (ground));
|
||||
YAP_Functor yapFunctor = YAP_FunctorOfTerm (ground);
|
||||
string name ((char*) (YAP_AtomName (YAP_NameOfFunctor (yapFunctor))));
|
||||
unsigned arity = (unsigned) YAP_ArityOfFunctor (yapFunctor);
|
||||
Symbol functor = LiftedUtils::getSymbol (name);
|
||||
Symbols args;
|
||||
for (unsigned i = 1; i <= arity; i++) {
|
||||
YAP_Term ti = YAP_ArgOfTerm (i, ground);
|
||||
assert (YAP_IsAtomTerm (ti));
|
||||
string arg ((char *) YAP_AtomName (YAP_AtomOfTerm (ti)));
|
||||
args.push_back (LiftedUtils::getSymbol (arg));
|
||||
}
|
||||
queryVars.push_back (Ground (functor, args));
|
||||
}
|
||||
jointList = YAP_TailOfTerm (jointList);
|
||||
}
|
||||
FoveSolver solver (pfList);
|
||||
if (queryVars.size() == 1) {
|
||||
results.push_back (solver.getPosterioriOf (queryVars[0]));
|
||||
} else {
|
||||
assert (false); // TODO joint dist
|
||||
}
|
||||
taskList = YAP_TailOfTerm (taskList);
|
||||
}
|
||||
|
||||
YAP_Term list = YAP_TermNil();
|
||||
for (int i = results.size() - 1; i >= 0; i--) {
|
||||
const Params& beliefs = results[i];
|
||||
YAP_Term queryBeliefsL = YAP_TermNil();
|
||||
for (int j = beliefs.size() - 1; j >= 0; j--) {
|
||||
YAP_Int sl1 = YAP_InitSlot (list);
|
||||
YAP_Term belief = YAP_MkFloatTerm (beliefs[j]);
|
||||
queryBeliefsL = YAP_MkPairTerm (belief, queryBeliefsL);
|
||||
list = YAP_GetFromSlot (sl1);
|
||||
YAP_RecoverSlots (1);
|
||||
}
|
||||
list = YAP_MkPairTerm (queryBeliefsL, list);
|
||||
}
|
||||
|
||||
return YAP_Unify (list, YAP_ARG3);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
runOtherSolvers (void)
|
||||
{
|
||||
BayesNet* bn = (BayesNet*) YAP_IntOfTerm (YAP_ARG1);
|
||||
YAP_Term taskList = YAP_ARG2;
|
||||
vector<VarIds> tasks;
|
||||
std::set<VarId> vids;
|
||||
while (taskList != YAP_TermNil()) {
|
||||
if (YAP_IsPairTerm (YAP_HeadOfTerm (taskList))) {
|
||||
tasks.push_back (VarIds());
|
||||
YAP_Term jointList = YAP_HeadOfTerm (taskList);
|
||||
while (jointList != YAP_TermNil()) {
|
||||
VarId vid = (unsigned) YAP_IntOfTerm (YAP_HeadOfTerm (jointList));
|
||||
assert (bn->getBayesNode (vid));
|
||||
tasks.back().push_back (vid);
|
||||
vids.insert (vid);
|
||||
jointList = YAP_TailOfTerm (jointList);
|
||||
}
|
||||
} else {
|
||||
VarId vid = (unsigned) YAP_IntOfTerm (YAP_HeadOfTerm (taskList));
|
||||
assert (bn->getBayesNode (vid));
|
||||
tasks.push_back (VarIds() = {vid});
|
||||
vids.insert (vid);
|
||||
}
|
||||
taskList = YAP_TailOfTerm (taskList);
|
||||
}
|
||||
|
||||
Solver* bpSolver = 0;
|
||||
GraphicalModel* graphicalModel = 0;
|
||||
CFactorGraph::checkForIdenticalFactors = false;
|
||||
if (InfAlgorithms::infAlgorithm != InfAlgorithms::VE) {
|
||||
BayesNet* mrn = bn->getMinimalRequesiteNetwork (
|
||||
VarIds (vids.begin(), vids.end()));
|
||||
if (InfAlgorithms::infAlgorithm == InfAlgorithms::BN_BP) {
|
||||
graphicalModel = mrn;
|
||||
bpSolver = new BnBpSolver (*static_cast<BayesNet*> (graphicalModel));
|
||||
} else if (InfAlgorithms::infAlgorithm == InfAlgorithms::FG_BP) {
|
||||
graphicalModel = new FactorGraph (*mrn);
|
||||
bpSolver = new FgBpSolver (*static_cast<FactorGraph*> (graphicalModel));
|
||||
delete mrn;
|
||||
} else if (InfAlgorithms::infAlgorithm == InfAlgorithms::CBP) {
|
||||
graphicalModel = new FactorGraph (*mrn);
|
||||
bpSolver = new CbpSolver (*static_cast<FactorGraph*> (graphicalModel));
|
||||
delete mrn;
|
||||
}
|
||||
bpSolver->runSolver();
|
||||
}
|
||||
|
||||
vector<Params> results;
|
||||
results.reserve (tasks.size());
|
||||
for (unsigned i = 0; i < tasks.size(); i++) {
|
||||
//if (i == 1) exit (0);
|
||||
if (InfAlgorithms::infAlgorithm == InfAlgorithms::VE) {
|
||||
BayesNet* mrn = bn->getMinimalRequesiteNetwork (tasks[i]);
|
||||
VarElimSolver* veSolver = new VarElimSolver (*mrn);
|
||||
if (tasks[i].size() == 1) {
|
||||
results.push_back (veSolver->getPosterioriOf (tasks[i][0]));
|
||||
} else {
|
||||
results.push_back (veSolver->getJointDistributionOf (tasks[i]));
|
||||
}
|
||||
delete mrn;
|
||||
delete veSolver;
|
||||
} else {
|
||||
if (tasks[i].size() == 1) {
|
||||
results.push_back (bpSolver->getPosterioriOf (tasks[i][0]));
|
||||
} else {
|
||||
results.push_back (bpSolver->getJointDistributionOf (tasks[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
delete bpSolver;
|
||||
delete graphicalModel;
|
||||
|
||||
YAP_Term list = YAP_TermNil();
|
||||
for (int i = results.size() - 1; i >= 0; i--) {
|
||||
const Params& beliefs = results[i];
|
||||
YAP_Term queryBeliefsL = YAP_TermNil();
|
||||
for (int j = beliefs.size() - 1; j >= 0; j--) {
|
||||
YAP_Int sl1 = YAP_InitSlot (list);
|
||||
YAP_Term belief = YAP_MkFloatTerm (beliefs[j]);
|
||||
queryBeliefsL = YAP_MkPairTerm (belief, queryBeliefsL);
|
||||
list = YAP_GetFromSlot (sl1);
|
||||
YAP_RecoverSlots (1);
|
||||
}
|
||||
list = YAP_MkPairTerm (queryBeliefsL, list);
|
||||
}
|
||||
|
||||
return YAP_Unify (list, YAP_ARG3);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
setExtraVarsInfo (void)
|
||||
{
|
||||
@ -94,124 +457,7 @@ setExtraVarsInfo (void)
|
||||
|
||||
|
||||
int
|
||||
setParameters (void)
|
||||
{
|
||||
BayesNet* bn = (BayesNet*) YAP_IntOfTerm (YAP_ARG1);
|
||||
YAP_Term distList = YAP_ARG2;
|
||||
while (distList != YAP_TermNil()) {
|
||||
YAP_Term dist = YAP_HeadOfTerm (distList);
|
||||
unsigned distId = (unsigned) YAP_IntOfTerm (YAP_ArgOfTerm (1, dist));
|
||||
YAP_Term paramL = YAP_ArgOfTerm (2, dist);
|
||||
ParamSet params;
|
||||
while (paramL!= YAP_TermNil()) {
|
||||
params.push_back ((double) YAP_FloatOfTerm (YAP_HeadOfTerm (paramL)));
|
||||
paramL = YAP_TailOfTerm (paramL);
|
||||
}
|
||||
if (NSPACE == NumberSpace::LOGARITHM) {
|
||||
Util::toLog (params);
|
||||
}
|
||||
bn->getDistribution(distId)->updateParameters (params);
|
||||
distList = YAP_TailOfTerm (distList);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
runSolver (void)
|
||||
{
|
||||
BayesNet* bn = (BayesNet*) YAP_IntOfTerm (YAP_ARG1);
|
||||
YAP_Term taskList = YAP_ARG2;
|
||||
vector<VarIdSet> tasks;
|
||||
std::set<VarId> vids;
|
||||
while (taskList != YAP_TermNil()) {
|
||||
if (YAP_IsPairTerm (YAP_HeadOfTerm (taskList))) {
|
||||
tasks.push_back (VarIdSet());
|
||||
YAP_Term jointList = YAP_HeadOfTerm (taskList);
|
||||
while (jointList != YAP_TermNil()) {
|
||||
VarId vid = (unsigned) YAP_IntOfTerm (YAP_HeadOfTerm (jointList));
|
||||
assert (bn->getBayesNode (vid));
|
||||
tasks.back().push_back (vid);
|
||||
vids.insert (vid);
|
||||
jointList = YAP_TailOfTerm (jointList);
|
||||
}
|
||||
} else {
|
||||
VarId vid = (unsigned) YAP_IntOfTerm (YAP_HeadOfTerm (taskList));
|
||||
assert (bn->getBayesNode (vid));
|
||||
tasks.push_back (VarIdSet() = {vid});
|
||||
vids.insert (vid);
|
||||
}
|
||||
taskList = YAP_TailOfTerm (taskList);
|
||||
}
|
||||
|
||||
Solver* bpSolver = 0;
|
||||
GraphicalModel* graphicalModel = 0;
|
||||
CFactorGraph::disableCheckForIdenticalFactors();
|
||||
if (InfAlgorithms::infAlgorithm != InfAlgorithms::VE) {
|
||||
BayesNet* mrn = bn->getMinimalRequesiteNetwork (
|
||||
VarIdSet (vids.begin(), vids.end()));
|
||||
if (InfAlgorithms::infAlgorithm == InfAlgorithms::BN_BP) {
|
||||
graphicalModel = mrn;
|
||||
bpSolver = new BnBpSolver (*static_cast<BayesNet*> (graphicalModel));
|
||||
} else if (InfAlgorithms::infAlgorithm == InfAlgorithms::FG_BP) {
|
||||
graphicalModel = new FactorGraph (*mrn);
|
||||
bpSolver = new FgBpSolver (*static_cast<FactorGraph*> (graphicalModel));
|
||||
delete mrn;
|
||||
} else if (InfAlgorithms::infAlgorithm == InfAlgorithms::CBP) {
|
||||
graphicalModel = new FactorGraph (*mrn);
|
||||
bpSolver = new CbpSolver (*static_cast<FactorGraph*> (graphicalModel));
|
||||
delete mrn;
|
||||
}
|
||||
bpSolver->runSolver();
|
||||
}
|
||||
|
||||
vector<ParamSet> results;
|
||||
results.reserve (tasks.size());
|
||||
for (unsigned i = 0; i < tasks.size(); i++) {
|
||||
//if (i == 1) exit (0);
|
||||
if (InfAlgorithms::infAlgorithm == InfAlgorithms::VE) {
|
||||
BayesNet* mrn = bn->getMinimalRequesiteNetwork (tasks[i]);
|
||||
VarElimSolver* veSolver = new VarElimSolver (*mrn);
|
||||
if (tasks[i].size() == 1) {
|
||||
results.push_back (veSolver->getPosterioriOf (tasks[i][0]));
|
||||
} else {
|
||||
results.push_back (veSolver->getJointDistributionOf (tasks[i]));
|
||||
}
|
||||
delete mrn;
|
||||
delete veSolver;
|
||||
} else {
|
||||
if (tasks[i].size() == 1) {
|
||||
results.push_back (bpSolver->getPosterioriOf (tasks[i][0]));
|
||||
} else {
|
||||
results.push_back (bpSolver->getJointDistributionOf (tasks[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
delete bpSolver;
|
||||
delete graphicalModel;
|
||||
|
||||
YAP_Term list = YAP_TermNil();
|
||||
for (int i = results.size() - 1; i >= 0; i--) {
|
||||
const ParamSet& beliefs = results[i];
|
||||
YAP_Term queryBeliefsL = YAP_TermNil();
|
||||
for (int j = beliefs.size() - 1; j >= 0; j--) {
|
||||
YAP_Int sl1 = YAP_InitSlot (list);
|
||||
YAP_Term belief = YAP_MkFloatTerm (beliefs[j]);
|
||||
queryBeliefsL = YAP_MkPairTerm (belief, queryBeliefsL);
|
||||
list = YAP_GetFromSlot (sl1);
|
||||
YAP_RecoverSlots (1);
|
||||
}
|
||||
list = YAP_MkPairTerm (queryBeliefsL, list);
|
||||
}
|
||||
|
||||
return YAP_Unify (list, YAP_ARG3);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
setSolverParameter (void)
|
||||
setHorusFlag (void)
|
||||
{
|
||||
string key ((char*) YAP_AtomName (YAP_AtomOfTerm (YAP_ARG1)));
|
||||
if (key == "inf_alg") {
|
||||
@ -263,12 +509,23 @@ setSolverParameter (void)
|
||||
BpOptions::accuracy = (double) YAP_FloatOfTerm (YAP_ARG2);
|
||||
} else if (key == "max_iter") {
|
||||
BpOptions::maxIter = (int) YAP_IntOfTerm (YAP_ARG2);
|
||||
} else if (key == "always_loopy_solver") {
|
||||
} else if (key == "use_logarithms") {
|
||||
string value ((char*) YAP_AtomName (YAP_AtomOfTerm (YAP_ARG2)));
|
||||
if (value == "true") {
|
||||
BpOptions::useAlwaysLoopySolver = true;
|
||||
if ( value == "true") {
|
||||
Globals::logDomain = true;
|
||||
} else if (value == "false") {
|
||||
BpOptions::useAlwaysLoopySolver = false;
|
||||
Globals::logDomain = false;
|
||||
} else {
|
||||
cerr << "warning: invalid value `" << value << "' " ;
|
||||
cerr << "for `" << key << "'" << endl;
|
||||
return FALSE;
|
||||
}
|
||||
} else if (key == "order_factor_variables") {
|
||||
string value ((char*) YAP_AtomName (YAP_AtomOfTerm (YAP_ARG2)));
|
||||
if ( value == "true") {
|
||||
FactorGraph::orderFactorVariables = true;
|
||||
} else if (value == "false") {
|
||||
FactorGraph::orderFactorVariables = false;
|
||||
} else {
|
||||
cerr << "warning: invalid value `" << value << "' " ;
|
||||
cerr << "for `" << key << "'" << endl;
|
||||
@ -283,14 +540,6 @@ setSolverParameter (void)
|
||||
|
||||
|
||||
|
||||
int useLogSpace (void)
|
||||
{
|
||||
NSPACE = NumberSpace::LOGARITHM;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
freeBayesNetwork (void)
|
||||
{
|
||||
@ -303,15 +552,27 @@ freeBayesNetwork (void)
|
||||
|
||||
|
||||
|
||||
int
|
||||
freeParfactorGraph (void)
|
||||
{
|
||||
delete (ParfactorList*) YAP_IntOfTerm (YAP_ARG1);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
extern "C" void
|
||||
init_predicates (void)
|
||||
{
|
||||
YAP_UserCPredicate ("create_network", createNetwork, 2);
|
||||
YAP_UserCPredicate ("set_extra_vars_info", setExtraVarsInfo, 2);
|
||||
YAP_UserCPredicate ("set_parameters", setParameters, 2);
|
||||
YAP_UserCPredicate ("run_solver", runSolver, 3);
|
||||
YAP_UserCPredicate ("set_solver_parameter", setSolverParameter, 2);
|
||||
YAP_UserCPredicate ("use_log_space", useLogSpace, 0);
|
||||
YAP_UserCPredicate ("free_bayesian_network", freeBayesNetwork, 1);
|
||||
YAP_UserCPredicate ("create_lifted_network", createLiftedNetwork, 3);
|
||||
YAP_UserCPredicate ("create_ground_network", createGroundNetwork, 2);
|
||||
YAP_UserCPredicate ("set_parfactor_graph_params", setParfactorGraphParams, 2);
|
||||
YAP_UserCPredicate ("set_bayes_net_params", setBayesNetParams, 2);
|
||||
YAP_UserCPredicate ("run_lifted_solver", runLiftedSolver, 3);
|
||||
YAP_UserCPredicate ("run_other_solvers", runOtherSolvers, 3);
|
||||
YAP_UserCPredicate ("set_extra_vars_info", setExtraVarsInfo, 2);
|
||||
YAP_UserCPredicate ("set_horus_flag", setHorusFlag, 2);
|
||||
YAP_UserCPredicate ("free_bayesian_network", freeBayesNetwork, 1);
|
||||
YAP_UserCPredicate ("free_parfactor_graph", freeParfactorGraph, 1);
|
||||
}
|
||||
|
||||
|
301
packages/CLPBN/clpbn/bp/Indexer.h
Normal file
301
packages/CLPBN/clpbn/bp/Indexer.h
Normal file
@ -0,0 +1,301 @@
|
||||
#ifndef HORUS_STATESINDEXER_H
|
||||
#define HORUS_STATESINDEXER_H
|
||||
|
||||
#include <algorithm>
|
||||
#include <numeric>
|
||||
#include <functional>
|
||||
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
#include "VarNode.h"
|
||||
#include "Util.h"
|
||||
|
||||
|
||||
class StatesIndexer {
|
||||
public:
|
||||
|
||||
StatesIndexer (const Ranges& ranges, bool calcOffsets = true)
|
||||
{
|
||||
size_ = 1;
|
||||
indices_.resize (ranges.size(), 0);
|
||||
ranges_ = ranges;
|
||||
for (unsigned i = 0; i < ranges.size(); i++) {
|
||||
size_ *= ranges[i];
|
||||
}
|
||||
li_ = 0;
|
||||
if (calcOffsets) {
|
||||
calculateOffsets();
|
||||
}
|
||||
}
|
||||
|
||||
StatesIndexer (const VarNodes& vars, bool calcOffsets = true)
|
||||
{
|
||||
size_ = 1;
|
||||
indices_.resize (vars.size(), 0);
|
||||
ranges_.reserve (vars.size());
|
||||
for (unsigned i = 0; i < vars.size(); i++) {
|
||||
ranges_.push_back (vars[i]->nrStates());
|
||||
size_ *= vars[i]->nrStates();
|
||||
}
|
||||
li_ = 0;
|
||||
if (calcOffsets) {
|
||||
calculateOffsets();
|
||||
}
|
||||
}
|
||||
|
||||
void increment (void)
|
||||
{
|
||||
for (int i = ranges_.size() - 1; i >= 0; i--) {
|
||||
indices_[i] ++;
|
||||
if (indices_[i] != ranges_[i]) {
|
||||
break;
|
||||
} else {
|
||||
indices_[i] = 0;
|
||||
}
|
||||
}
|
||||
li_ ++;
|
||||
}
|
||||
|
||||
void increment (unsigned dim)
|
||||
{
|
||||
assert (dim < ranges_.size());
|
||||
assert (ranges_.size() == offsets_.size());
|
||||
assert (indices_[dim] < ranges_[dim]);
|
||||
indices_[dim] ++;
|
||||
li_ += offsets_[dim];
|
||||
}
|
||||
|
||||
void incrementExcluding (unsigned skipDim)
|
||||
{
|
||||
assert (ranges_.size() == offsets_.size());
|
||||
for (int i = ranges_.size() - 1; i >= 0; i--) {
|
||||
if (i != (int)skipDim) {
|
||||
indices_[i] ++;
|
||||
li_ += offsets_[i];
|
||||
if (indices_[i] != ranges_[i]) {
|
||||
return;
|
||||
} else {
|
||||
indices_[i] = 0;
|
||||
li_ -= offsets_[i] * ranges_[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
li_ = size_;
|
||||
}
|
||||
|
||||
unsigned linearIndex (void) const
|
||||
{
|
||||
return li_;
|
||||
}
|
||||
|
||||
const vector<unsigned>& indices (void) const
|
||||
{
|
||||
return indices_;
|
||||
}
|
||||
|
||||
StatesIndexer& operator ++ (void)
|
||||
{
|
||||
increment();
|
||||
return *this;
|
||||
}
|
||||
|
||||
operator unsigned (void) const
|
||||
{
|
||||
return li_;
|
||||
}
|
||||
|
||||
unsigned operator[] (unsigned dim) const
|
||||
{
|
||||
assert (valid());
|
||||
assert (dim < ranges_.size());
|
||||
return indices_[dim];
|
||||
}
|
||||
|
||||
bool valid (void) const
|
||||
{
|
||||
return li_ < size_;
|
||||
}
|
||||
|
||||
void reset (void)
|
||||
{
|
||||
std::fill (indices_.begin(), indices_.end(), 0);
|
||||
li_ = 0;
|
||||
}
|
||||
|
||||
void reset (unsigned dim)
|
||||
{
|
||||
indices_[dim] = 0;
|
||||
li_ -= offsets_[dim] * ranges_[dim];
|
||||
}
|
||||
|
||||
unsigned size (void) const
|
||||
{
|
||||
return size_ ;
|
||||
}
|
||||
|
||||
friend ostream& operator<< (ostream &out, const StatesIndexer& idx)
|
||||
{
|
||||
out << "(" << std::setw (2) << std::setfill('0') << idx.li_ << ") " ;
|
||||
out << idx.indices_;
|
||||
return out;
|
||||
}
|
||||
|
||||
private:
|
||||
void calculateOffsets (void)
|
||||
{
|
||||
unsigned prod = 1;
|
||||
offsets_.resize (ranges_.size());
|
||||
for (int i = ranges_.size() - 1; i >= 0; i--) {
|
||||
offsets_[i] = prod;
|
||||
prod *= ranges_[i];
|
||||
}
|
||||
}
|
||||
|
||||
unsigned li_;
|
||||
unsigned size_;
|
||||
vector<unsigned> indices_;
|
||||
vector<unsigned> ranges_;
|
||||
vector<unsigned> offsets_;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class MapIndexer
|
||||
{
|
||||
public:
|
||||
MapIndexer (const Ranges& ranges, const vector<bool>& mapDims)
|
||||
{
|
||||
assert (ranges.size() == mapDims.size());
|
||||
unsigned prod = 1;
|
||||
offsets_.resize (ranges.size());
|
||||
for (int i = ranges.size() - 1; i >= 0; i--) {
|
||||
if (mapDims[i]) {
|
||||
offsets_[i] = prod;
|
||||
prod *= ranges[i];
|
||||
}
|
||||
}
|
||||
indices_.resize (ranges.size(), 0);
|
||||
ranges_ = ranges;
|
||||
index_ = 0;
|
||||
valid_ = true;
|
||||
}
|
||||
|
||||
MapIndexer (const Ranges& ranges, unsigned ignoreDim)
|
||||
{
|
||||
unsigned prod = 1;
|
||||
offsets_.resize (ranges.size());
|
||||
for (int i = ranges.size() - 1; i >= 0; i--) {
|
||||
if (i != (int)ignoreDim) {
|
||||
offsets_[i] = prod;
|
||||
prod *= ranges[i];
|
||||
}
|
||||
}
|
||||
indices_.resize (ranges.size(), 0);
|
||||
ranges_ = ranges;
|
||||
index_ = 0;
|
||||
valid_ = true;
|
||||
}
|
||||
|
||||
/*
|
||||
MapIndexer (
|
||||
const VarIds& loopVids,
|
||||
const Ranges& loopRanges,
|
||||
const VarIds& mapVids,
|
||||
const Ranges& mapRanges)
|
||||
{
|
||||
unsigned prod = 1;
|
||||
vector<unsigned> offsets (mapRanges.size());
|
||||
for (int i = mapRanges.size() - 1; i >= 0; i--) {
|
||||
offsets[i] = prod;
|
||||
prod *= mapRanges[i];
|
||||
}
|
||||
|
||||
offsets_.reserve (loopVids.size());
|
||||
for (unsigned i = 0; i < loopVids.size(); i++) {
|
||||
VarIds::const_iterator it =
|
||||
std::find (mapVids.begin(), mapVids.end(), loopVids[i]);
|
||||
if (it != mapVids.end()) {
|
||||
offsets_.push_back (offsets[it - mapVids.begin()]);
|
||||
} else {
|
||||
offsets_.push_back (0);
|
||||
}
|
||||
}
|
||||
|
||||
indices_.resize (loopVids.size(), 0);
|
||||
ranges_ = loopRanges;
|
||||
index_ = 0;
|
||||
size_ = prod;
|
||||
}
|
||||
*/
|
||||
|
||||
MapIndexer& operator ++ (void)
|
||||
{
|
||||
assert (valid_);
|
||||
for (int i = ranges_.size() - 1; i >= 0; i--) {
|
||||
indices_[i] ++;
|
||||
index_ += offsets_[i];
|
||||
if (indices_[i] != ranges_[i]) {
|
||||
return *this;
|
||||
} else {
|
||||
indices_[i] = 0;
|
||||
index_ -= offsets_[i] * ranges_[i];
|
||||
}
|
||||
}
|
||||
valid_ = false;
|
||||
return *this;
|
||||
}
|
||||
|
||||
unsigned mappedIndex (void) const
|
||||
{
|
||||
return index_;
|
||||
}
|
||||
|
||||
operator unsigned (void) const
|
||||
{
|
||||
return index_;
|
||||
}
|
||||
|
||||
unsigned operator[] (unsigned dim) const
|
||||
{
|
||||
assert (valid());
|
||||
assert (dim < ranges_.size());
|
||||
return indices_[dim];
|
||||
}
|
||||
|
||||
bool valid (void) const
|
||||
{
|
||||
return valid_;
|
||||
}
|
||||
|
||||
void reset (void)
|
||||
{
|
||||
std::fill (indices_.begin(), indices_.end(), 0);
|
||||
index_ = 0;
|
||||
}
|
||||
|
||||
friend ostream& operator<< (ostream &out, const MapIndexer& idx)
|
||||
{
|
||||
out << "(" << std::setw (2) << std::setfill('0') << idx.index_ << ") " ;
|
||||
out << idx.indices_;
|
||||
return out;
|
||||
}
|
||||
|
||||
private:
|
||||
MapIndexer (const Ranges& ranges) :
|
||||
ranges_(ranges),
|
||||
indices_(ranges.size(), 0),
|
||||
offsets_(ranges.size())
|
||||
{
|
||||
index_ = 0;
|
||||
}
|
||||
unsigned index_;
|
||||
bool valid_;
|
||||
vector<unsigned> ranges_;
|
||||
vector<unsigned> indices_;
|
||||
vector<unsigned> offsets_;
|
||||
};
|
||||
|
||||
|
||||
#endif // HORUS_STATESINDEXER_H
|
||||
|
120
packages/CLPBN/clpbn/bp/LiftedUtils.cpp
Normal file
120
packages/CLPBN/clpbn/bp/LiftedUtils.cpp
Normal file
@ -0,0 +1,120 @@
|
||||
#include <cassert>
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
#include "LiftedUtils.h"
|
||||
#include "ConstraintTree.h"
|
||||
|
||||
|
||||
namespace LiftedUtils {
|
||||
|
||||
|
||||
unordered_map<string, unsigned> symbolDict;
|
||||
|
||||
|
||||
Symbol
|
||||
getSymbol (const string& symbolName)
|
||||
{
|
||||
unordered_map<string, unsigned>::iterator it
|
||||
= symbolDict.find (symbolName);
|
||||
if (it != symbolDict.end()) {
|
||||
return it->second;
|
||||
} else {
|
||||
symbolDict[symbolName] = symbolDict.size() - 1;
|
||||
return symbolDict.size() - 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
printSymbolDictionary (void)
|
||||
{
|
||||
unordered_map<string, unsigned>::const_iterator it
|
||||
= symbolDict.begin();
|
||||
while (it != symbolDict.end()) {
|
||||
cout << it->first << " -> " << it->second << endl;
|
||||
it ++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
ostream& operator<< (ostream &os, const Symbol& s)
|
||||
{
|
||||
unordered_map<string, unsigned>::const_iterator it
|
||||
= LiftedUtils::symbolDict.begin();
|
||||
while (it != LiftedUtils::symbolDict.end() && it->second != s) {
|
||||
it ++;
|
||||
}
|
||||
assert (it != LiftedUtils::symbolDict.end());
|
||||
os << it->first;
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
|
||||
ostream& operator<< (ostream &os, const LogVar& X)
|
||||
{
|
||||
const string labels[] = {
|
||||
"A", "B", "C", "D", "E", "F",
|
||||
"G", "H", "I", "J", "K", "M" };
|
||||
(X >= 12) ? os << "X_" << X.id_ : os << labels[X];
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
|
||||
ostream& operator<< (ostream &os, const Tuple& t)
|
||||
{
|
||||
os << "(" ;
|
||||
for (unsigned i = 0; i < t.size(); i++) {
|
||||
os << ((i != 0) ? "," : "") << t[i];
|
||||
}
|
||||
os << ")" ;
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
|
||||
ostream& operator<< (ostream &os, const Ground& gr)
|
||||
{
|
||||
os << gr.functor();
|
||||
os << "(" ;
|
||||
for (unsigned i = 0; i < gr.args().size(); i++) {
|
||||
if (i != 0) os << ", " ;
|
||||
os << gr.args()[i];
|
||||
}
|
||||
os << ")" ;
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
ObservedFormula::addTuple (const Tuple& t)
|
||||
{
|
||||
if (constr_ == 0) {
|
||||
LogVars lvs (arity_);
|
||||
for (unsigned i = 0; i < arity_; i++) {
|
||||
lvs[i] = i;
|
||||
}
|
||||
constr_ = new ConstraintTree (lvs);
|
||||
}
|
||||
constr_->addTuple (t);
|
||||
}
|
||||
|
||||
|
||||
|
||||
ostream& operator<< (ostream &os, const ObservedFormula of)
|
||||
{
|
||||
os << of.functor_ << "/" << of.arity_;
|
||||
os << "|" << of.constr_->tupleSet();
|
||||
os << " [evidence=" << of.evidence_ << "]";
|
||||
return os;
|
||||
}
|
||||
|
161
packages/CLPBN/clpbn/bp/LiftedUtils.h
Normal file
161
packages/CLPBN/clpbn/bp/LiftedUtils.h
Normal file
@ -0,0 +1,161 @@
|
||||
#ifndef HORUS_LIFTEDUTILS_H
|
||||
#define HORUS_LIFTEDUTILS_H
|
||||
|
||||
#include <limits>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
|
||||
|
||||
#include "TinySet.h"
|
||||
#include "Util.h"
|
||||
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
class Symbol
|
||||
{
|
||||
public:
|
||||
Symbol (void) : id_(numeric_limits<unsigned>::max()) { }
|
||||
Symbol (unsigned id) : id_(id) { }
|
||||
operator unsigned (void) const { return id_; }
|
||||
bool valid (void) const { return id_ != numeric_limits<unsigned>::max(); }
|
||||
static Symbol invalid (void) { return Symbol(); }
|
||||
friend ostream& operator<< (ostream &os, const Symbol& s);
|
||||
private:
|
||||
unsigned id_;
|
||||
};
|
||||
|
||||
|
||||
class LogVar
|
||||
{
|
||||
public:
|
||||
LogVar (void) : id_(numeric_limits<unsigned>::max()) { }
|
||||
LogVar (unsigned id) : id_(id) { }
|
||||
operator unsigned (void) const { return id_; }
|
||||
|
||||
LogVar& operator++ (void)
|
||||
{
|
||||
assert (valid());
|
||||
id_ ++;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool valid (void) const
|
||||
{
|
||||
return id_ != numeric_limits<unsigned>::max();
|
||||
}
|
||||
|
||||
friend ostream& operator<< (ostream &os, const LogVar& X);
|
||||
private:
|
||||
unsigned id_;
|
||||
};
|
||||
|
||||
|
||||
namespace std {
|
||||
template <> struct hash<Symbol> {
|
||||
size_t operator() (const Symbol& s) const {
|
||||
return std::hash<unsigned>() (s);
|
||||
}};
|
||||
|
||||
template <> struct hash<LogVar> {
|
||||
size_t operator() (const LogVar& X) const {
|
||||
return std::hash<unsigned>() (X);
|
||||
}};
|
||||
};
|
||||
|
||||
|
||||
typedef vector<Symbol> Symbols;
|
||||
typedef vector<Symbol> Tuple;
|
||||
typedef vector<Tuple> Tuples;
|
||||
typedef vector<LogVar> LogVars;
|
||||
typedef TinySet<Symbol> SymbolSet;
|
||||
typedef TinySet<LogVar> LogVarSet;
|
||||
typedef TinySet<Tuple> TupleSet;
|
||||
|
||||
|
||||
ostream& operator<< (ostream &os, const Tuple& t);
|
||||
|
||||
|
||||
namespace LiftedUtils {
|
||||
Symbol getSymbol (const string&);
|
||||
void printSymbolDictionary (void);
|
||||
}
|
||||
|
||||
|
||||
|
||||
class Ground
|
||||
{
|
||||
public:
|
||||
Ground (Symbol f) : functor_(f) { }
|
||||
Ground (Symbol f, const Symbols& args) : functor_(f), args_(args) { }
|
||||
|
||||
Symbol functor (void) const { return functor_; }
|
||||
Symbols args (void) const { return args_; }
|
||||
unsigned arity (void) const { return args_.size(); }
|
||||
bool isAtom (void) const { return args_.size() == 0; }
|
||||
friend ostream& operator<< (ostream &os, const Ground& gr);
|
||||
private:
|
||||
Symbol functor_;
|
||||
Symbols args_;
|
||||
};
|
||||
typedef vector<Ground> Grounds;
|
||||
|
||||
|
||||
|
||||
class ConstraintTree;
|
||||
class ObservedFormula
|
||||
{
|
||||
public:
|
||||
ObservedFormula (Symbol f, unsigned a, unsigned ev)
|
||||
: functor_(f), arity_(a), evidence_(ev), constr_(0) { }
|
||||
|
||||
ObservedFormula (Symbol f, unsigned ev, const Tuple& tuple)
|
||||
: functor_(f), arity_(tuple.size()), evidence_(ev), constr_(0)
|
||||
{
|
||||
addTuple (tuple);
|
||||
}
|
||||
|
||||
Symbol functor (void) const { return functor_; }
|
||||
unsigned arity (void) const { return arity_; }
|
||||
unsigned evidence (void) const { return evidence_; }
|
||||
ConstraintTree* constr (void) const { return constr_; }
|
||||
bool isAtom (void) const { return arity_ == 0; }
|
||||
|
||||
void addTuple (const Tuple& t);
|
||||
friend ostream& operator<< (ostream &os, const ObservedFormula opv);
|
||||
private:
|
||||
Symbol functor_;
|
||||
unsigned arity_;
|
||||
unsigned evidence_;
|
||||
ConstraintTree* constr_;
|
||||
};
|
||||
typedef vector<ObservedFormula*> ObservedFormulas;
|
||||
|
||||
|
||||
|
||||
class Substitution
|
||||
{
|
||||
public:
|
||||
void add (LogVar X_old, LogVar X_new)
|
||||
{
|
||||
subs_.insert (make_pair (X_old, X_new));
|
||||
}
|
||||
void rename (LogVar X_old, LogVar X_new)
|
||||
{
|
||||
assert (subs_.find (X_old) != subs_.end());
|
||||
subs_.find (X_old)->second = X_new;
|
||||
}
|
||||
LogVar newNameFor (LogVar X) const
|
||||
{
|
||||
assert (subs_.find (X) != subs_.end());
|
||||
return subs_.find (X)->second;
|
||||
}
|
||||
private:
|
||||
unordered_map<LogVar, LogVar> subs_;
|
||||
};
|
||||
|
||||
|
||||
#endif // HORUS_LIFTEDUTILS_H
|
||||
|
@ -23,10 +23,10 @@ CC=@CC@
|
||||
CXX=@CXX@
|
||||
|
||||
# normal
|
||||
CXXFLAGS= -std=c++0x @SHLIB_CXXFLAGS@ $(YAP_EXTRAS) $(DEFS) -D_YAP_NOT_INSTALLED_=1 -I$(srcdir) -I../../../.. -I$(srcdir)/../../../../include @CPPFLAGS@ -DNDEBUG
|
||||
#CXXFLAGS= -std=c++0x @SHLIB_CXXFLAGS@ $(YAP_EXTRAS) $(DEFS) -D_YAP_NOT_INSTALLED_=1 -I$(srcdir) -I../../../.. -I$(srcdir)/../../../../include @CPPFLAGS@ -DNDEBUG
|
||||
|
||||
# debug
|
||||
#CXXFLAGS= -std=c++0x @SHLIB_CXXFLAGS@ $(YAP_EXTRAS) $(DEFS) -D_YAP_NOT_INSTALLED_=1 -I$(srcdir) -I../../../.. -I$(srcdir)/../../../../include @CPPFLAGS@ -g -O0 -Wextra
|
||||
CXXFLAGS= -std=c++0x @SHLIB_CXXFLAGS@ $(YAP_EXTRAS) $(DEFS) -D_YAP_NOT_INSTALLED_=1 -I$(srcdir) -I../../../.. -I$(srcdir)/../../../../include @CPPFLAGS@ -g -O0 -Wextra
|
||||
|
||||
|
||||
#
|
||||
@ -46,24 +46,32 @@ CWD=$(PWD)
|
||||
|
||||
HEADERS = \
|
||||
$(srcdir)/GraphicalModel.h \
|
||||
$(srcdir)/VarNode.h \
|
||||
$(srcdir)/Distribution.h \
|
||||
$(srcdir)/BayesNet.h \
|
||||
$(srcdir)/BayesNode.h \
|
||||
$(srcdir)/ElimGraph.h \
|
||||
$(srcdir)/CFactorGraph.h \
|
||||
$(srcdir)/CptEntry.h \
|
||||
$(srcdir)/FactorGraph.h \
|
||||
$(srcdir)/Factor.h \
|
||||
$(srcdir)/CFactorGraph.h \
|
||||
$(srcdir)/ConstraintTree.h \
|
||||
$(srcdir)/Solver.h \
|
||||
$(srcdir)/VarElimSolver.h \
|
||||
$(srcdir)/BnBpSolver.h \
|
||||
$(srcdir)/FgBpSolver.h \
|
||||
$(srcdir)/CbpSolver.h \
|
||||
$(srcdir)/Shared.h \
|
||||
$(srcdir)/StatesIndexer.h \
|
||||
$(srcdir)/FoveSolver.h \
|
||||
$(srcdir)/VarNode.h \
|
||||
$(srcdir)/Distribution.h \
|
||||
$(srcdir)/Indexer.h \
|
||||
$(srcdir)/Parfactor.h \
|
||||
$(srcdir)/ProbFormula.h \
|
||||
$(srcdir)/Histogram.h \
|
||||
$(srcdir)/ParfactorList.h \
|
||||
$(srcdir)/LiftedUtils.h \
|
||||
$(srcdir)/TinySet.h \
|
||||
$(srcdir)/Util.h \
|
||||
$(srcdir)/Horus.h \
|
||||
$(srcdir)/xmlParser/xmlParser.h
|
||||
|
||||
|
||||
CPP_SOURCES = \
|
||||
$(srcdir)/BayesNet.cpp \
|
||||
$(srcdir)/BayesNode.cpp \
|
||||
@ -71,12 +79,19 @@ CPP_SOURCES = \
|
||||
$(srcdir)/FactorGraph.cpp \
|
||||
$(srcdir)/Factor.cpp \
|
||||
$(srcdir)/CFactorGraph.cpp \
|
||||
$(srcdir)/ConstraintTree.cpp \
|
||||
$(srcdir)/VarNode.cpp \
|
||||
$(srcdir)/Solver.cpp \
|
||||
$(srcdir)/VarElimSolver.cpp \
|
||||
$(srcdir)/BnBpSolver.cpp \
|
||||
$(srcdir)/FgBpSolver.cpp \
|
||||
$(srcdir)/CbpSolver.cpp \
|
||||
$(srcdir)/FoveSolver.cpp \
|
||||
$(srcdir)/Parfactor.cpp \
|
||||
$(srcdir)/ProbFormula.cpp \
|
||||
$(srcdir)/Histogram.cpp \
|
||||
$(srcdir)/ParfactorList.cpp \
|
||||
$(srcdir)/LiftedUtils.cpp \
|
||||
$(srcdir)/Util.cpp \
|
||||
$(srcdir)/HorusYap.cpp \
|
||||
$(srcdir)/HorusCli.cpp \
|
||||
@ -89,12 +104,19 @@ OBJS = \
|
||||
FactorGraph.o \
|
||||
Factor.o \
|
||||
CFactorGraph.o \
|
||||
ConstraintTree.o \
|
||||
VarNode.o \
|
||||
Solver.o \
|
||||
VarElimSolver.o \
|
||||
BnBpSolver.o \
|
||||
FgBpSolver.o \
|
||||
CbpSolver.o \
|
||||
FoveSolver.o \
|
||||
Parfactor.o \
|
||||
ProbFormula.o \
|
||||
Histogram.o \
|
||||
ParfactorList.o \
|
||||
LiftedUtils.o \
|
||||
Util.o \
|
||||
HorusYap.o
|
||||
|
||||
@ -105,12 +127,19 @@ HCLI_OBJS = \
|
||||
FactorGraph.o \
|
||||
Factor.o \
|
||||
CFactorGraph.o \
|
||||
ConstraintTree.o \
|
||||
VarNode.o \
|
||||
Solver.o \
|
||||
VarElimSolver.o \
|
||||
BnBpSolver.o \
|
||||
FgBpSolver.o \
|
||||
CbpSolver.o \
|
||||
FoveSolver.o \
|
||||
Parfactor.o \
|
||||
ProbFormula.o \
|
||||
Histogram.o \
|
||||
ParfactorList.o \
|
||||
LiftedUtils.o \
|
||||
Util.o \
|
||||
xmlParser/xmlParser.o \
|
||||
HorusCli.o
|
||||
@ -145,6 +174,10 @@ clean:
|
||||
rm -f *.o *~ $(OBJS) $(SOBJS) *.BAK hcli xmlParser/*.o
|
||||
|
||||
|
||||
erase_dots:
|
||||
rm -f *.dot *.png
|
||||
|
||||
|
||||
depend: $(HEADERS) $(CPP_SOURCES)
|
||||
-@if test "$(GCC)" = yes; then\
|
||||
$(CC) -std=c++0x -MM -MG $(CFLAGS) -I$(srcdir) -I$(srcdir)/../../../../include -I$(srcdir)/../../../../H $(CPP_SOURCES) >> Makefile;\
|
||||
|
861
packages/CLPBN/clpbn/bp/Parfactor.cpp
Normal file
861
packages/CLPBN/clpbn/bp/Parfactor.cpp
Normal file
@ -0,0 +1,861 @@
|
||||
|
||||
#include "Parfactor.h"
|
||||
#include "Histogram.h"
|
||||
#include "Indexer.h"
|
||||
#include "Horus.h"
|
||||
|
||||
|
||||
Parfactor::Parfactor (
|
||||
const ProbFormulas& formulas,
|
||||
const Params& params,
|
||||
const Tuples& tuples,
|
||||
unsigned distId)
|
||||
{
|
||||
formulas_ = formulas;
|
||||
params_ = params;
|
||||
distId_ = distId;
|
||||
|
||||
LogVars logVars;
|
||||
for (unsigned i = 0; i < formulas_.size(); i++) {
|
||||
ranges_.push_back (formulas_[i].range());
|
||||
const LogVars& lvs = formulas_[i].logVars();
|
||||
for (unsigned j = 0; j < lvs.size(); j++) {
|
||||
if (std::find (logVars.begin(), logVars.end(), lvs[j]) ==
|
||||
logVars.end()) {
|
||||
logVars.push_back (lvs[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
constr_ = new ConstraintTree (logVars, tuples);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Parfactor::Parfactor (const Parfactor* g, const Tuple& tuple)
|
||||
{
|
||||
formulas_ = g->formulas();
|
||||
params_ = g->params();
|
||||
ranges_ = g->ranges();
|
||||
distId_ = g->distId();
|
||||
constr_ = new ConstraintTree (g->logVars(), {tuple});
|
||||
}
|
||||
|
||||
|
||||
|
||||
Parfactor::Parfactor (const Parfactor* g, ConstraintTree* constr)
|
||||
{
|
||||
formulas_ = g->formulas();
|
||||
params_ = g->params();
|
||||
ranges_ = g->ranges();
|
||||
distId_ = g->distId();
|
||||
constr_ = constr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Parfactor::Parfactor (const Parfactor& g)
|
||||
{
|
||||
formulas_ = g.formulas();
|
||||
params_ = g.params();
|
||||
ranges_ = g.ranges();
|
||||
distId_ = g.distId();
|
||||
constr_ = new ConstraintTree (*g.constr());
|
||||
}
|
||||
|
||||
|
||||
|
||||
Parfactor::~Parfactor (void)
|
||||
{
|
||||
delete constr_;
|
||||
}
|
||||
|
||||
|
||||
|
||||
LogVarSet
|
||||
Parfactor::countedLogVars (void) const
|
||||
{
|
||||
LogVarSet set;
|
||||
for (unsigned i = 0; i < formulas_.size(); i++) {
|
||||
if (formulas_[i].isCounting()) {
|
||||
set.insert (formulas_[i].countedLogVar());
|
||||
}
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
|
||||
|
||||
LogVarSet
|
||||
Parfactor::uncountedLogVars (void) const
|
||||
{
|
||||
return constr_->logVarSet() - countedLogVars();
|
||||
}
|
||||
|
||||
|
||||
|
||||
LogVarSet
|
||||
Parfactor::elimLogVars (void) const
|
||||
{
|
||||
LogVarSet requiredToElim = constr_->logVarSet();
|
||||
requiredToElim -= constr_->singletons();
|
||||
requiredToElim -= countedLogVars();
|
||||
return requiredToElim;
|
||||
}
|
||||
|
||||
|
||||
|
||||
LogVarSet
|
||||
Parfactor::exclusiveLogVars (unsigned fIdx) const
|
||||
{
|
||||
assert (fIdx < formulas_.size());
|
||||
LogVarSet remaining;
|
||||
for (unsigned i = 0; i < formulas_.size(); i++) {
|
||||
if (i != fIdx) {
|
||||
remaining |= formulas_[i].logVarSet();
|
||||
}
|
||||
}
|
||||
return formulas_[fIdx].logVarSet() - remaining;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
Parfactor::setConstraintTree (ConstraintTree* newTree)
|
||||
{
|
||||
delete constr_;
|
||||
constr_ = newTree;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
Parfactor::sumOut (unsigned fIdx)
|
||||
{
|
||||
assert (fIdx < formulas_.size());
|
||||
assert (formulas_[fIdx].contains (elimLogVars()));
|
||||
|
||||
LogVarSet excl = exclusiveLogVars (fIdx);
|
||||
unsigned condCount = constr_->getConditionalCount (excl);
|
||||
Util::pow (params_, condCount);
|
||||
|
||||
vector<unsigned> numAssigns (ranges_[fIdx], 1);
|
||||
if (formulas_[fIdx].isCounting()) {
|
||||
unsigned N = constr_->getConditionalCount (
|
||||
formulas_[fIdx].countedLogVar());
|
||||
unsigned R = formulas_[fIdx].range();
|
||||
unsigned H = ranges_[fIdx];
|
||||
HistogramSet hs (N, R);
|
||||
unsigned N_factorial = Util::factorial (N);
|
||||
for (unsigned h = 0; h < H; h++) {
|
||||
unsigned prod = 1;
|
||||
for (unsigned r = 0; r < R; r++) {
|
||||
prod *= Util::factorial (hs[r]);
|
||||
}
|
||||
numAssigns[h] = N_factorial / prod;
|
||||
hs.nextHistogram();
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
Params copy = params_;
|
||||
params_.clear();
|
||||
params_.resize (copy.size() / ranges_[fIdx], 0.0);
|
||||
|
||||
MapIndexer indexer (ranges_, fIdx);
|
||||
for (unsigned i = 0; i < copy.size(); i++) {
|
||||
unsigned h = indexer[fIdx];
|
||||
// TODO NOT LOG DOMAIN AWARE :(
|
||||
params_[indexer] += numAssigns[h] * copy[i];
|
||||
++ indexer;
|
||||
}
|
||||
formulas_.erase (formulas_.begin() + fIdx);
|
||||
ranges_.erase (ranges_.begin() + fIdx);
|
||||
constr_->remove (excl);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
Parfactor::multiply (Parfactor& g)
|
||||
{
|
||||
alignAndExponentiate (this, &g);
|
||||
bool sharedVars = false;
|
||||
vector<unsigned> g_varpos;
|
||||
const ProbFormulas& g_formulas = g.formulas();
|
||||
const Params& g_params = g.params();
|
||||
const Ranges& g_ranges = g.ranges();
|
||||
|
||||
for (unsigned i = 0; i < g_formulas.size(); i++) {
|
||||
int group = g_formulas[i].group();
|
||||
if (indexOfFormulaWithGroup (group) == -1) {
|
||||
insertDimension (g.ranges()[i]);
|
||||
formulas_.push_back (g_formulas[i]);
|
||||
g_varpos.push_back (formulas_.size() - 1);
|
||||
} else {
|
||||
sharedVars = true;
|
||||
g_varpos.push_back (indexOfFormulaWithGroup (group));
|
||||
}
|
||||
}
|
||||
|
||||
if (sharedVars == false) {
|
||||
unsigned count = 0;
|
||||
for (unsigned i = 0; i < params_.size(); i++) {
|
||||
if (Globals::logDomain) {
|
||||
params_[i] += g_params[count];
|
||||
} else {
|
||||
params_[i] *= g_params[count];
|
||||
}
|
||||
count ++;
|
||||
if (count >= g_params.size()) {
|
||||
count = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
StatesIndexer indexer (ranges_, false);
|
||||
while (indexer.valid()) {
|
||||
unsigned g_li = 0;
|
||||
unsigned prod = 1;
|
||||
for (int j = g_varpos.size() - 1; j >= 0; j--) {
|
||||
g_li += indexer[g_varpos[j]] * prod;
|
||||
prod *= g_ranges[j];
|
||||
}
|
||||
if (Globals::logDomain) {
|
||||
params_[indexer] += g_params[g_li];
|
||||
} else {
|
||||
params_[indexer] *= g_params[g_li];
|
||||
}
|
||||
++ indexer;
|
||||
}
|
||||
}
|
||||
|
||||
constr_->join (g.constr(), true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
Parfactor::countConvert (LogVar X)
|
||||
{
|
||||
int fIdx = indexOfFormulaWithLogVar (X);
|
||||
assert (fIdx != -1);
|
||||
assert (constr_->isCountNormalized (X));
|
||||
assert (constr_->getConditionalCount (X) > 1);
|
||||
assert (constr_->isCarteesianProduct (countedLogVars() | X));
|
||||
|
||||
unsigned N = constr_->getConditionalCount (X);
|
||||
unsigned R = ranges_[fIdx];
|
||||
unsigned H = HistogramSet::nrHistograms (N, R);
|
||||
vector<Histogram> histograms = HistogramSet::getHistograms (N, R);
|
||||
|
||||
StatesIndexer indexer (ranges_);
|
||||
vector<Params> summout (params_.size() / R);
|
||||
unsigned count = 0;
|
||||
while (indexer.valid()) {
|
||||
summout[count].reserve (R);
|
||||
for (unsigned r = 0; r < R; r++) {
|
||||
summout[count].push_back (params_[indexer]);
|
||||
indexer.increment (fIdx);
|
||||
}
|
||||
count ++;
|
||||
indexer.reset (fIdx);
|
||||
indexer.incrementExcluding (fIdx);
|
||||
}
|
||||
|
||||
params_.clear();
|
||||
params_.reserve (summout.size() * H);
|
||||
|
||||
vector<bool> mapDims (ranges_.size(), true);
|
||||
ranges_[fIdx] = H;
|
||||
mapDims[fIdx] = false;
|
||||
MapIndexer mapIndexer (ranges_, mapDims);
|
||||
while (mapIndexer.valid()) {
|
||||
double prod = 1.0;
|
||||
unsigned i = mapIndexer.mappedIndex();
|
||||
unsigned h = mapIndexer[fIdx];
|
||||
for (unsigned r = 0; r < R; r++) {
|
||||
// TODO not log domain aware
|
||||
prod *= Util::pow (summout[i][r], histograms[h][r]);
|
||||
}
|
||||
params_.push_back (prod);
|
||||
++ mapIndexer;
|
||||
}
|
||||
formulas_[fIdx].setCountedLogVar (X);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
Parfactor::expandPotential (
|
||||
LogVar X,
|
||||
LogVar X_new1,
|
||||
LogVar X_new2)
|
||||
{
|
||||
int fIdx = indexOfFormulaWithLogVar (X);
|
||||
assert (fIdx != -1);
|
||||
assert (formulas_[fIdx].isCounting());
|
||||
|
||||
unsigned N1 = constr_->getConditionalCount (X_new1);
|
||||
unsigned N2 = constr_->getConditionalCount (X_new2);
|
||||
unsigned N = N1 + N2;
|
||||
unsigned R = formulas_[fIdx].range();
|
||||
unsigned H1 = HistogramSet::nrHistograms (N1, R);
|
||||
unsigned H2 = HistogramSet::nrHistograms (N2, R);
|
||||
unsigned H = ranges_[fIdx];
|
||||
|
||||
vector<Histogram> histograms = HistogramSet::getHistograms (N, R);
|
||||
vector<Histogram> histograms1 = HistogramSet::getHistograms (N1, R);
|
||||
vector<Histogram> histograms2 = HistogramSet::getHistograms (N2, R);
|
||||
|
||||
vector<unsigned> sumIndexes;
|
||||
sumIndexes.reserve (H1 * H2);
|
||||
for (unsigned i = 0; i < H1; i++) {
|
||||
for (unsigned j = 0; j < H2; j++) {
|
||||
Histogram hist = histograms1[i];
|
||||
std::transform (
|
||||
hist.begin(), hist.end(),
|
||||
histograms2[j].begin(),
|
||||
hist.begin(),
|
||||
plus<int>());
|
||||
sumIndexes.push_back (HistogramSet::findIndex (hist, histograms));
|
||||
}
|
||||
}
|
||||
|
||||
unsigned size = (params_.size() / H) * H1 * H2;
|
||||
Params copy = params_;
|
||||
params_.clear();
|
||||
params_.reserve (size);
|
||||
|
||||
unsigned prod = 1;
|
||||
vector<unsigned> offsets_ (ranges_.size());
|
||||
for (int i = ranges_.size() - 1; i >= 0; i--) {
|
||||
offsets_[i] = prod;
|
||||
prod *= ranges_[i];
|
||||
}
|
||||
|
||||
unsigned index = 0;
|
||||
ranges_[fIdx] = H1 * H2;
|
||||
vector<unsigned> indices (ranges_.size(), 0);
|
||||
for (unsigned k = 0; k < size; k++) {
|
||||
params_.push_back (copy[index]);
|
||||
for (int i = ranges_.size() - 1; i >= 0; i--) {
|
||||
indices[i] ++;
|
||||
if (i == fIdx) {
|
||||
int diff = sumIndexes[indices[i]] - sumIndexes[indices[i] - 1];
|
||||
index += diff * offsets_[i];
|
||||
} else {
|
||||
index += offsets_[i];
|
||||
}
|
||||
if (indices[i] != ranges_[i]) {
|
||||
break;
|
||||
} else {
|
||||
if (i == fIdx) {
|
||||
int diff = sumIndexes[0] - sumIndexes[indices[i]];
|
||||
index += diff * offsets_[i];
|
||||
} else {
|
||||
index -= offsets_[i] * ranges_[i];
|
||||
}
|
||||
indices[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
formulas_.insert (formulas_.begin() + fIdx + 1, formulas_[fIdx]);
|
||||
formulas_[fIdx].rename (X, X_new1);
|
||||
formulas_[fIdx + 1].rename (X, X_new2);
|
||||
ranges_.insert (ranges_.begin() + fIdx + 1, H2);
|
||||
ranges_[fIdx] = H1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
Parfactor::fullExpand (LogVar X)
|
||||
{
|
||||
int fIdx = indexOfFormulaWithLogVar (X);
|
||||
assert (fIdx != -1);
|
||||
assert (formulas_[fIdx].isCounting());
|
||||
|
||||
unsigned N = constr_->getConditionalCount (X);
|
||||
unsigned R = formulas_[fIdx].range();
|
||||
unsigned H = ranges_[fIdx];
|
||||
|
||||
vector<Histogram> originHists = HistogramSet::getHistograms (N, R);
|
||||
vector<Histogram> expandHists = HistogramSet::getHistograms (1, R);
|
||||
|
||||
vector<unsigned> sumIndexes;
|
||||
sumIndexes.reserve (N * R);
|
||||
|
||||
Ranges expandRanges (N, R);
|
||||
StatesIndexer indexer (expandRanges);
|
||||
while (indexer.valid()) {
|
||||
vector<unsigned> hist (R, 0);
|
||||
for (unsigned n = 0; n < N; n++) {
|
||||
std::transform (
|
||||
hist.begin(), hist.end(),
|
||||
expandHists[indexer[n]].begin(),
|
||||
hist.begin(),
|
||||
plus<int>());
|
||||
}
|
||||
sumIndexes.push_back (HistogramSet::findIndex (hist, originHists));
|
||||
++ indexer;
|
||||
}
|
||||
|
||||
unsigned size = (params_.size() / H) * std::pow (R, N);
|
||||
Params copy = params_;
|
||||
params_.clear();
|
||||
params_.reserve (size);
|
||||
|
||||
unsigned prod = 1;
|
||||
vector<unsigned> offsets_ (ranges_.size());
|
||||
for (int i = ranges_.size() - 1; i >= 0; i--) {
|
||||
offsets_[i] = prod;
|
||||
prod *= ranges_[i];
|
||||
}
|
||||
|
||||
unsigned index = 0;
|
||||
ranges_[fIdx] = std::pow (R, N);
|
||||
vector<unsigned> indices (ranges_.size(), 0);
|
||||
for (unsigned k = 0; k < size; k++) {
|
||||
params_.push_back (copy[index]);
|
||||
for (int i = ranges_.size() - 1; i >= 0; i--) {
|
||||
indices[i] ++;
|
||||
if (i == fIdx) {
|
||||
int diff = sumIndexes[indices[i]] - sumIndexes[indices[i] - 1];
|
||||
index += diff * offsets_[i];
|
||||
} else {
|
||||
index += offsets_[i];
|
||||
}
|
||||
if (indices[i] != ranges_[i]) {
|
||||
break;
|
||||
} else {
|
||||
if (i == fIdx) {
|
||||
int diff = sumIndexes[0] - sumIndexes[indices[i]];
|
||||
index += diff * offsets_[i];
|
||||
} else {
|
||||
index -= offsets_[i] * ranges_[i];
|
||||
}
|
||||
indices[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ProbFormula f = formulas_[fIdx];
|
||||
formulas_.erase (formulas_.begin() + fIdx);
|
||||
ranges_.erase (ranges_.begin() + fIdx);
|
||||
LogVars newLvs = constr_->expand (X);
|
||||
assert (newLvs.size() == N);
|
||||
for (unsigned i = 0 ; i < N; i++) {
|
||||
ProbFormula newFormula (f.functor(), f.logVars(), f.range());
|
||||
newFormula.rename (X, newLvs[i]);
|
||||
formulas_.insert (formulas_.begin() + fIdx + i, newFormula);
|
||||
ranges_.insert (ranges_.begin() + fIdx + i, R);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
Parfactor::reorderAccordingGrounds (const Grounds& grounds)
|
||||
{
|
||||
ProbFormulas newFormulas;
|
||||
for (unsigned i = 0; i < grounds.size(); i++) {
|
||||
for (unsigned j = 0; j < formulas_.size(); j++) {
|
||||
if (grounds[i].functor() == formulas_[j].functor() &&
|
||||
grounds[i].arity() == formulas_[j].arity()) {
|
||||
constr_->moveToTop (formulas_[j].logVars());
|
||||
if (constr_->containsTuple (grounds[i].args())) {
|
||||
newFormulas.push_back (formulas_[j]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
assert (newFormulas.size() == i + 1);
|
||||
}
|
||||
reorderFormulas (newFormulas);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
Parfactor::reorderFormulas (const ProbFormulas& newFormulas)
|
||||
{
|
||||
assert (newFormulas.size() == formulas_.size());
|
||||
if (newFormulas == formulas_) {
|
||||
return;
|
||||
}
|
||||
|
||||
Ranges newRanges;
|
||||
vector<unsigned> positions;
|
||||
for (unsigned i = 0; i < newFormulas.size(); i++) {
|
||||
unsigned idx = indexOf (newFormulas[i]);
|
||||
newRanges.push_back (ranges_[idx]);
|
||||
positions.push_back (idx);
|
||||
}
|
||||
|
||||
unsigned N = ranges_.size();
|
||||
Params newParams (params_.size());
|
||||
for (unsigned i = 0; i < params_.size(); i++) {
|
||||
unsigned li = i;
|
||||
// calculate vector index corresponding to linear index
|
||||
vector<unsigned> vi (N);
|
||||
for (int k = N-1; k >= 0; k--) {
|
||||
vi[k] = li % ranges_[k];
|
||||
li /= ranges_[k];
|
||||
}
|
||||
// convert permuted vector index to corresponding linear index
|
||||
unsigned prod = 1;
|
||||
unsigned new_li = 0;
|
||||
for (int k = N - 1; k >= 0; k--) {
|
||||
new_li += vi[positions[k]] * prod;
|
||||
prod *= ranges_[positions[k]];
|
||||
}
|
||||
newParams[new_li] = params_[i];
|
||||
}
|
||||
formulas_ = newFormulas;
|
||||
ranges_ = newRanges;
|
||||
params_ = newParams;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
Parfactor::absorveEvidence (unsigned fIdx, unsigned evidence)
|
||||
{
|
||||
LogVarSet excl = exclusiveLogVars (fIdx);
|
||||
assert (fIdx < formulas_.size());
|
||||
assert (evidence < formulas_[fIdx].range());
|
||||
assert (formulas_[fIdx].isCounting() == false);
|
||||
assert (constr_->isCountNormalized (excl));
|
||||
|
||||
Util::pow (params_, constr_->getConditionalCount (excl));
|
||||
|
||||
Params copy = params_;
|
||||
params_.clear();
|
||||
params_.reserve (copy.size() / formulas_[fIdx].range());
|
||||
|
||||
StatesIndexer indexer (ranges_);
|
||||
for (unsigned i = 0; i < evidence; i++) {
|
||||
indexer.increment (fIdx);
|
||||
}
|
||||
while (indexer.valid()) {
|
||||
params_.push_back (copy[indexer]);
|
||||
indexer.incrementExcluding (fIdx);
|
||||
}
|
||||
formulas_.erase (formulas_.begin() + fIdx);
|
||||
ranges_.erase (ranges_.begin() + fIdx);
|
||||
constr_->remove (excl);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
Parfactor::normalize (void)
|
||||
{
|
||||
Util::normalize (params_);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
Parfactor::setFormulaGroup (const ProbFormula& f, int group)
|
||||
{
|
||||
assert (indexOf (f) != -1);
|
||||
formulas_[indexOf (f)].setGroup (group);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
Parfactor::setNewGroups (void)
|
||||
{
|
||||
for (unsigned i = 0; i < formulas_.size(); i++) {
|
||||
formulas_[i].setGroup (ProbFormula::getNewGroup());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
Parfactor::applySubstitution (const Substitution& theta)
|
||||
{
|
||||
for (unsigned i = 0; i < formulas_.size(); i++) {
|
||||
LogVars& lvs = formulas_[i].logVars();
|
||||
for (unsigned j = 0; j < lvs.size(); j++) {
|
||||
lvs[j] = theta.newNameFor (lvs[j]);
|
||||
}
|
||||
if (formulas_[i].isCounting()) {
|
||||
LogVar clv = formulas_[i].countedLogVar();
|
||||
formulas_[i].setCountedLogVar (theta.newNameFor (clv));
|
||||
}
|
||||
}
|
||||
constr_->applySubstitution (theta);
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
Parfactor::containsGround (const Ground& ground) const
|
||||
{
|
||||
for (unsigned i = 0; i < formulas_.size(); i++) {
|
||||
if (formulas_[i].functor() == ground.functor() &&
|
||||
formulas_[i].arity() == ground.arity()) {
|
||||
constr_->moveToTop (formulas_[i].logVars());
|
||||
if (constr_->containsTuple (ground.args())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
Parfactor::containsGroup (unsigned group) const
|
||||
{
|
||||
for (unsigned i = 0; i < formulas_.size(); i++) {
|
||||
if (formulas_[i].group() == group) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const ProbFormula&
|
||||
Parfactor::formula (unsigned fIdx) const
|
||||
{
|
||||
assert (fIdx < formulas_.size());
|
||||
return formulas_[fIdx];
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsigned
|
||||
Parfactor::range (unsigned fIdx) const
|
||||
{
|
||||
assert (fIdx < ranges_.size());
|
||||
return ranges_[fIdx];
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsigned
|
||||
Parfactor::nrFormulas (LogVar X) const
|
||||
{
|
||||
unsigned count = 0;
|
||||
for (unsigned i = 0; i < formulas_.size(); i++) {
|
||||
if (formulas_[i].contains (X)) {
|
||||
count ++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
Parfactor::indexOf (const ProbFormula& f) const
|
||||
{
|
||||
int idx = -1;
|
||||
for (unsigned i = 0; i < formulas_.size(); i++) {
|
||||
if (f == formulas_[i]) {
|
||||
idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return idx;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
Parfactor::indexOfFormulaWithLogVar (LogVar X) const
|
||||
{
|
||||
int idx = -1;
|
||||
assert (nrFormulas (X) == 1);
|
||||
for (unsigned i = 0; i < formulas_.size(); i++) {
|
||||
if (formulas_[i].contains (X)) {
|
||||
idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return idx;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
Parfactor::indexOfFormulaWithGroup (unsigned group) const
|
||||
{
|
||||
int pos = -1;
|
||||
for (unsigned i = 0; i < formulas_.size(); i++) {
|
||||
if (formulas_[i].group() == group) {
|
||||
pos = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
|
||||
|
||||
vector<unsigned>
|
||||
Parfactor::getAllGroups (void) const
|
||||
{
|
||||
vector<unsigned> groups (formulas_.size());
|
||||
for (unsigned i = 0; i < formulas_.size(); i++) {
|
||||
groups[i] = formulas_[i].group();
|
||||
}
|
||||
return groups;
|
||||
}
|
||||
|
||||
|
||||
|
||||
string
|
||||
Parfactor::getHeaderString (void) const
|
||||
{
|
||||
stringstream ss;
|
||||
ss << "phi(" ;
|
||||
for (unsigned i = 0; i < formulas_.size(); i++) {
|
||||
if (i != 0) ss << "," ;
|
||||
ss << formulas_[i];
|
||||
}
|
||||
ss << ")" ;
|
||||
ConstraintTree copy (*constr_);
|
||||
copy.moveToTop (copy.logVarSet().elements());
|
||||
ss << "|" << copy.tupleSet();
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
Parfactor::print (bool printParams) const
|
||||
{
|
||||
cout << "Formulas: " ;
|
||||
for (unsigned i = 0; i < formulas_.size(); i++) {
|
||||
if (i != 0) cout << ", " ;
|
||||
cout << formulas_[i];
|
||||
}
|
||||
cout << endl;
|
||||
vector<string> groups;
|
||||
for (unsigned i = 0; i < formulas_.size(); i++) {
|
||||
groups.push_back (string ("g") + Util::toString (formulas_[i].group()));
|
||||
}
|
||||
cout << "Groups: " << groups << endl;
|
||||
cout << "LogVars: " << constr_->logVars() << endl;
|
||||
cout << "Ranges: " << ranges_ << endl;
|
||||
if (printParams == false) {
|
||||
cout << "Params: " << params_ << endl;
|
||||
}
|
||||
cout << "Tuples: " << constr_->tupleSet() << endl;
|
||||
if (printParams) {
|
||||
vector<string> jointStrings;
|
||||
StatesIndexer indexer (ranges_);
|
||||
while (indexer.valid()) {
|
||||
stringstream ss;
|
||||
for (unsigned i = 0; i < formulas_.size(); i++) {
|
||||
if (i != 0) ss << ", " ;
|
||||
if (formulas_[i].isCounting()) {
|
||||
unsigned N = constr_->getConditionalCount (formulas_[i].countedLogVar());
|
||||
HistogramSet hs (N, formulas_[i].range());
|
||||
unsigned c = 0;
|
||||
while (c < indexer[i]) {
|
||||
hs.nextHistogram();
|
||||
c ++;
|
||||
}
|
||||
ss << hs;
|
||||
} else {
|
||||
ss << indexer[i];
|
||||
}
|
||||
}
|
||||
jointStrings.push_back (ss.str());
|
||||
++ indexer;
|
||||
}
|
||||
for (unsigned i = 0; i < params_.size(); i++) {
|
||||
cout << "f(" << jointStrings[i] << ")" ;
|
||||
cout << " = " << params_[i] << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
Parfactor::insertDimension (unsigned range)
|
||||
{
|
||||
Params copy = params_;
|
||||
params_.clear();
|
||||
params_.reserve (copy.size() * range);
|
||||
for (unsigned i = 0; i < copy.size(); i++) {
|
||||
for (unsigned reps = 0; reps < range; reps++) {
|
||||
params_.push_back (copy[i]);
|
||||
}
|
||||
}
|
||||
ranges_.push_back (range);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
Parfactor::alignAndExponentiate (Parfactor* g1, Parfactor* g2)
|
||||
{
|
||||
LogVars X_1, X_2;
|
||||
const ProbFormulas& formulas1 = g1->formulas();
|
||||
const ProbFormulas& formulas2 = g2->formulas();
|
||||
for (unsigned i = 0; i < formulas1.size(); i++) {
|
||||
for (unsigned j = 0; j < formulas2.size(); j++) {
|
||||
if (formulas1[i].group() == formulas2[j].group()) {
|
||||
X_1.insert (X_1.end(),
|
||||
formulas1[i].logVars().begin(),
|
||||
formulas1[i].logVars().end());
|
||||
X_2.insert (X_2.end(),
|
||||
formulas2[j].logVars().begin(),
|
||||
formulas2[j].logVars().end());
|
||||
}
|
||||
}
|
||||
}
|
||||
align (g1, X_1, g2, X_2);
|
||||
LogVarSet Y_1 = g1->logVarSet() - LogVarSet (X_1);
|
||||
LogVarSet Y_2 = g2->logVarSet() - LogVarSet (X_2);
|
||||
assert (g1->constr()->isCountNormalized (Y_1));
|
||||
assert (g2->constr()->isCountNormalized (Y_2));
|
||||
unsigned condCount1 = g1->constr()->getConditionalCount (Y_1);
|
||||
unsigned condCount2 = g2->constr()->getConditionalCount (Y_2);
|
||||
Util::pow (g1->params(), 1.0 / condCount2);
|
||||
Util::pow (g2->params(), 1.0 / condCount1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
Parfactor::align (
|
||||
Parfactor* g1, const LogVars& alignLvs1,
|
||||
Parfactor* g2, const LogVars& alignLvs2)
|
||||
{
|
||||
LogVar freeLogVar = 0;
|
||||
Substitution theta1;
|
||||
Substitution theta2;
|
||||
|
||||
const LogVarSet& allLvs1 = g1->logVarSet();
|
||||
for (unsigned i = 0; i < allLvs1.size(); i++) {
|
||||
theta1.add (allLvs1[i], freeLogVar);
|
||||
++ freeLogVar;
|
||||
}
|
||||
|
||||
const LogVarSet& allLvs2 = g2->logVarSet();
|
||||
for (unsigned i = 0; i < allLvs2.size(); i++) {
|
||||
theta2.add (allLvs2[i], freeLogVar);
|
||||
++ freeLogVar;
|
||||
}
|
||||
|
||||
assert (alignLvs1.size() == alignLvs2.size());
|
||||
for (unsigned i = 0; i < alignLvs1.size(); i++) {
|
||||
theta1.rename (alignLvs1[i], theta2.newNameFor (alignLvs2[i]));
|
||||
}
|
||||
g1->applySubstitution (theta1);
|
||||
g2->applySubstitution (theta2);
|
||||
}
|
||||
|
124
packages/CLPBN/clpbn/bp/Parfactor.h
Normal file
124
packages/CLPBN/clpbn/bp/Parfactor.h
Normal file
@ -0,0 +1,124 @@
|
||||
#ifndef HORUS_PARFACTOR_H
|
||||
#define HORUS_PARFACTOR_H
|
||||
|
||||
#include <list>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "ProbFormula.h"
|
||||
#include "ConstraintTree.h"
|
||||
#include "LiftedUtils.h"
|
||||
#include "Horus.h"
|
||||
|
||||
|
||||
class Parfactor
|
||||
{
|
||||
public:
|
||||
Parfactor (
|
||||
const ProbFormulas&,
|
||||
const Params&,
|
||||
const Tuples&,
|
||||
unsigned);
|
||||
Parfactor (const Parfactor*, const Tuple&);
|
||||
Parfactor (const Parfactor*, ConstraintTree*);
|
||||
Parfactor (const Parfactor&);
|
||||
~Parfactor (void);
|
||||
|
||||
ProbFormulas& formulas (void) { return formulas_; }
|
||||
|
||||
const ProbFormulas& formulas (void) const { return formulas_; }
|
||||
|
||||
unsigned nrFormulas (void) const { return formulas_.size(); }
|
||||
|
||||
Params& params (void) { return params_; }
|
||||
|
||||
const Params& params (void) const { return params_; }
|
||||
|
||||
unsigned size (void) const { return params_.size(); }
|
||||
|
||||
const Ranges& ranges (void) const { return ranges_; }
|
||||
|
||||
unsigned distId (void) const { return distId_; }
|
||||
|
||||
ConstraintTree* constr (void) { return constr_; }
|
||||
|
||||
const ConstraintTree* constr (void) const { return constr_; }
|
||||
|
||||
const LogVars& logVars (void) const { return constr_->logVars(); }
|
||||
|
||||
const LogVarSet& logVarSet (void) const { return constr_->logVarSet(); }
|
||||
|
||||
LogVarSet countedLogVars (void) const;
|
||||
|
||||
LogVarSet uncountedLogVars (void) const;
|
||||
|
||||
LogVarSet elimLogVars (void) const;
|
||||
|
||||
LogVarSet exclusiveLogVars (unsigned) const;
|
||||
|
||||
void setConstraintTree (ConstraintTree*);
|
||||
|
||||
void sumOut (unsigned);
|
||||
|
||||
void multiply (Parfactor&);
|
||||
|
||||
void countConvert (LogVar);
|
||||
|
||||
void expandPotential (LogVar, LogVar, LogVar);
|
||||
|
||||
void fullExpand (LogVar);
|
||||
|
||||
void reorderAccordingGrounds (const Grounds&);
|
||||
|
||||
void reorderFormulas (const ProbFormulas&);
|
||||
|
||||
void absorveEvidence (unsigned, unsigned);
|
||||
|
||||
void normalize (void);
|
||||
|
||||
void setFormulaGroup (const ProbFormula&, int);
|
||||
|
||||
void setNewGroups (void);
|
||||
|
||||
void applySubstitution (const Substitution&);
|
||||
|
||||
bool containsGround (const Ground&) const;
|
||||
|
||||
bool containsGroup (unsigned) const;
|
||||
|
||||
const ProbFormula& formula (unsigned) const;
|
||||
|
||||
unsigned range (unsigned) const;
|
||||
|
||||
unsigned nrFormulas (LogVar) const;
|
||||
|
||||
int indexOf (const ProbFormula&) const;
|
||||
|
||||
int indexOfFormulaWithLogVar (LogVar) const;
|
||||
|
||||
int indexOfFormulaWithGroup (unsigned) const;
|
||||
|
||||
vector<unsigned> getAllGroups (void) const;
|
||||
|
||||
void print (bool = false) const;
|
||||
|
||||
string getHeaderString (void) const;
|
||||
|
||||
private:
|
||||
static void alignAndExponentiate (Parfactor*, Parfactor*);
|
||||
static void align (
|
||||
Parfactor*, const LogVars&, Parfactor*, const LogVars&);
|
||||
|
||||
void insertDimension (unsigned);
|
||||
|
||||
ProbFormulas formulas_;
|
||||
Ranges ranges_;
|
||||
Params params_;
|
||||
unsigned distId_;
|
||||
ConstraintTree* constr_;
|
||||
};
|
||||
|
||||
|
||||
typedef vector<Parfactor*> Parfactors;
|
||||
|
||||
#endif // HORUS_PARFACTOR_H
|
||||
|
308
packages/CLPBN/clpbn/bp/ParfactorList.cpp
Normal file
308
packages/CLPBN/clpbn/bp/ParfactorList.cpp
Normal file
@ -0,0 +1,308 @@
|
||||
#include <cassert>
|
||||
|
||||
#include "ParfactorList.h"
|
||||
|
||||
|
||||
ParfactorList::ParfactorList (Parfactors& pfs)
|
||||
{
|
||||
pfList_.insert (pfList_.end(), pfs.begin(), pfs.end());
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
ParfactorList::add (Parfactor* pf)
|
||||
{
|
||||
pf->setNewGroups();
|
||||
pfList_.push_back (pf);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
ParfactorList::add (Parfactors& pfs)
|
||||
{
|
||||
for (unsigned i = 0; i < pfs.size(); i++) {
|
||||
pfs[i]->setNewGroups();
|
||||
pfList_.push_back (pfs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
ParfactorList::addShattered (Parfactor* pf)
|
||||
{
|
||||
pfList_.push_back (pf);
|
||||
}
|
||||
|
||||
|
||||
|
||||
list<Parfactor*>::iterator
|
||||
ParfactorList::remove (list<Parfactor*>::iterator it)
|
||||
{
|
||||
return pfList_.erase (it);
|
||||
}
|
||||
|
||||
|
||||
|
||||
list<Parfactor*>::iterator
|
||||
ParfactorList::deleteAndRemove (list<Parfactor*>::iterator it)
|
||||
{
|
||||
delete *it;
|
||||
return pfList_.erase (it);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
ParfactorList::shatter (void)
|
||||
{
|
||||
list<Parfactor*> tempList;
|
||||
Parfactors newPfs;
|
||||
newPfs.insert (newPfs.end(), pfList_.begin(), pfList_.end());
|
||||
while (newPfs.empty() == false) {
|
||||
tempList.insert (tempList.end(), newPfs.begin(), newPfs.end());
|
||||
newPfs.clear();
|
||||
list<Parfactor*>::iterator iter1 = tempList.begin();
|
||||
while (tempList.size() > 1 && iter1 != -- tempList.end()) {
|
||||
list<Parfactor*>::iterator iter2 = iter1;
|
||||
++ iter2;
|
||||
bool incIter1 = true;
|
||||
while (iter2 != tempList.end()) {
|
||||
assert (iter1 != iter2);
|
||||
std::pair<Parfactors, Parfactors> res = shatter (
|
||||
(*iter1)->formulas(), *iter1, (*iter2)->formulas(), *iter2);
|
||||
bool incIter2 = true;
|
||||
if (res.second.empty() == false) {
|
||||
// cout << "second unshattered" << endl;
|
||||
delete *iter2;
|
||||
iter2 = tempList.erase (iter2);
|
||||
incIter2 = false;
|
||||
newPfs.insert (
|
||||
newPfs.begin(), res.second.begin(), res.second.end());
|
||||
}
|
||||
if (res.first.empty() == false) {
|
||||
// cout << "first unshattered" << endl;
|
||||
delete *iter1;
|
||||
iter1 = tempList.erase (iter1);
|
||||
newPfs.insert (
|
||||
newPfs.begin(), res.first.begin(), res.first.end());
|
||||
incIter1 = false;
|
||||
break;
|
||||
}
|
||||
if (incIter2) {
|
||||
++ iter2;
|
||||
}
|
||||
}
|
||||
if (incIter1) {
|
||||
++ iter1;
|
||||
}
|
||||
}
|
||||
// cout << "|||||||||||||||||||||||||||||||||||||||||||||||||" << endl;
|
||||
// cout << "||||||||||||| SHATTERING ITERATION ||||||||||||||" << endl;
|
||||
// cout << "|||||||||||||||||||||||||||||||||||||||||||||||||" << endl;
|
||||
// printParfactors (newPfs);
|
||||
// cout << "|||||||||||||||||||||||||||||||||||||||||||||||||" << endl;
|
||||
}
|
||||
pfList_.clear();
|
||||
pfList_.insert (pfList_.end(), tempList.begin(), tempList.end());
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
ParfactorList::print (void) const
|
||||
{
|
||||
list<Parfactor*>::const_iterator it;
|
||||
for (it = pfList_.begin(); it != pfList_.end(); ++it) {
|
||||
(*it)->print();
|
||||
cout << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
std::pair<Parfactors, Parfactors>
|
||||
ParfactorList::shatter (
|
||||
ProbFormulas& formulas1,
|
||||
Parfactor* g1,
|
||||
ProbFormulas& formulas2,
|
||||
Parfactor* g2)
|
||||
{
|
||||
assert (g1 != 0 && g2 != 0 && g1 != g2);
|
||||
for (unsigned i = 0; i < formulas1.size(); i++) {
|
||||
for (unsigned j = 0; j < formulas2.size(); j++) {
|
||||
if (formulas1[i].sameSkeletonAs (formulas2[j])) {
|
||||
std::pair<Parfactors, Parfactors> res
|
||||
= shatter (formulas1[i], g1, formulas2[j], g2);
|
||||
if (res.first.empty() == false ||
|
||||
res.second.empty() == false) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return make_pair (Parfactors(), Parfactors());
|
||||
}
|
||||
|
||||
|
||||
|
||||
std::pair<Parfactors, Parfactors>
|
||||
ParfactorList::shatter (
|
||||
ProbFormula& f1,
|
||||
Parfactor* g1,
|
||||
ProbFormula& f2,
|
||||
Parfactor* g2)
|
||||
{
|
||||
// cout << endl;
|
||||
// cout << "-------------------------------------------------" << endl;
|
||||
// cout << "-> SHATTERING (#" << g1 << ", #" << g2 << ")" << endl;
|
||||
// g1->print();
|
||||
// cout << "-> WITH" << endl;
|
||||
// g2->print();
|
||||
// cout << "-> ON: " << f1.toString (g1->constr()) << endl;
|
||||
// cout << "-> ON: " << f2.toString (g2->constr()) << endl;
|
||||
// cout << "-------------------------------------------------" << endl;
|
||||
|
||||
if (f1.isAtom()) {
|
||||
unsigned group = (f1.group() < f2.group()) ? f1.group() : f2.group();
|
||||
f1.setGroup (group);
|
||||
f2.setGroup (group);
|
||||
return { };
|
||||
}
|
||||
assert (g1->constr()->empty() == false);
|
||||
assert (g2->constr()->empty() == false);
|
||||
if (f1.group() == f2.group()) {
|
||||
// assert (identical (f1, g1->constr(), f2, g2->constr()));
|
||||
return { };
|
||||
}
|
||||
|
||||
g1->constr()->moveToTop (f1.logVars());
|
||||
g2->constr()->moveToTop (f2.logVars());
|
||||
|
||||
std::pair<ConstraintTree*,ConstraintTree*> split1 =
|
||||
g1->constr()->split (g2->constr(), f1.arity());
|
||||
ConstraintTree* commCt1 = split1.first;
|
||||
ConstraintTree* exclCt1 = split1.second;
|
||||
|
||||
if (commCt1->empty()) {
|
||||
// disjoint
|
||||
delete commCt1;
|
||||
delete exclCt1;
|
||||
return { };
|
||||
}
|
||||
|
||||
std::pair<ConstraintTree*,ConstraintTree*> split2 =
|
||||
g2->constr()->split (g1->constr(), f2.arity());
|
||||
ConstraintTree* commCt2 = split2.first;
|
||||
ConstraintTree* exclCt2 = split2.second;
|
||||
|
||||
assert (commCt1->tupleSet (f1.arity()) ==
|
||||
commCt2->tupleSet (f2.arity()));
|
||||
|
||||
// stringstream ss1; ss1 << "" << count << "_A.dot" ;
|
||||
// stringstream ss2; ss2 << "" << count << "_B.dot" ;
|
||||
// stringstream ss3; ss3 << "" << count << "_A_comm.dot" ;
|
||||
// stringstream ss4; ss4 << "" << count << "_A_excl.dot" ;
|
||||
// stringstream ss5; ss5 << "" << count << "_B_comm.dot" ;
|
||||
// stringstream ss6; ss6 << "" << count << "_B_excl.dot" ;
|
||||
// ct1->exportToGraphViz (ss1.str().c_str(), true);
|
||||
// ct2->exportToGraphViz (ss2.str().c_str(), true);
|
||||
// commCt1->exportToGraphViz (ss3.str().c_str(), true);
|
||||
// exclCt1->exportToGraphViz (ss4.str().c_str(), true);
|
||||
// commCt2->exportToGraphViz (ss5.str().c_str(), true);
|
||||
// exclCt2->exportToGraphViz (ss6.str().c_str(), true);
|
||||
|
||||
if (exclCt1->empty() && exclCt2->empty()) {
|
||||
unsigned group = (f1.group() < f2.group()) ? f1.group() : f2.group();
|
||||
// identical
|
||||
f1.setGroup (group);
|
||||
f2.setGroup (group);
|
||||
// unifyGroups
|
||||
delete commCt1;
|
||||
delete exclCt1;
|
||||
delete commCt2;
|
||||
delete exclCt2;
|
||||
return { };
|
||||
}
|
||||
|
||||
unsigned group;
|
||||
if (exclCt1->empty()) {
|
||||
group = f1.group();
|
||||
} else if (exclCt2->empty()) {
|
||||
group = f2.group();
|
||||
} else {
|
||||
group = ProbFormula::getNewGroup();
|
||||
}
|
||||
Parfactors res1 = shatter (g1, f1, commCt1, exclCt1, group);
|
||||
Parfactors res2 = shatter (g2, f2, commCt2, exclCt2, group);
|
||||
return make_pair (res1, res2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Parfactors
|
||||
ParfactorList::shatter (
|
||||
Parfactor* g,
|
||||
const ProbFormula& f,
|
||||
ConstraintTree* commCt,
|
||||
ConstraintTree* exclCt,
|
||||
unsigned commGroup)
|
||||
{
|
||||
Parfactors result;
|
||||
if (f.isCounting()) {
|
||||
LogVar X_new1 = g->constr()->logVarSet().back() + 1;
|
||||
LogVar X_new2 = g->constr()->logVarSet().back() + 2;
|
||||
ConstraintTrees cts = g->constr()->jointCountNormalize (
|
||||
commCt, exclCt, f.countedLogVar(), X_new1, X_new2);
|
||||
for (unsigned i = 0; i < cts.size(); i++) {
|
||||
Parfactor* newPf = new Parfactor (g, cts[i]);
|
||||
if (cts[i]->nrLogVars() == g->constr()->nrLogVars() + 1) {
|
||||
newPf->expandPotential (f.countedLogVar(), X_new1, X_new2);
|
||||
assert (g->constr()->getConditionalCount (f.countedLogVar()) ==
|
||||
cts[i]->getConditionalCount (X_new1) +
|
||||
cts[i]->getConditionalCount (X_new2));
|
||||
} else {
|
||||
assert (g->constr()->getConditionalCount (f.countedLogVar()) ==
|
||||
cts[i]->getConditionalCount (f.countedLogVar()));
|
||||
}
|
||||
newPf->setNewGroups();
|
||||
result.push_back (newPf);
|
||||
}
|
||||
} else {
|
||||
if (exclCt->empty()) {
|
||||
delete commCt;
|
||||
delete exclCt;
|
||||
g->setFormulaGroup (f, commGroup);
|
||||
} else {
|
||||
Parfactor* newPf = new Parfactor (g, commCt);
|
||||
newPf->setNewGroups();
|
||||
newPf->setFormulaGroup (f, commGroup);
|
||||
result.push_back (newPf);
|
||||
newPf = new Parfactor (g, exclCt);
|
||||
newPf->setNewGroups();
|
||||
result.push_back (newPf);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
ParfactorList::unifyGroups (unsigned group1, unsigned group2)
|
||||
{
|
||||
unsigned newGroup = ProbFormula::getNewGroup();
|
||||
for (ParfactorList::iterator it = pfList_.begin();
|
||||
it != pfList_.end(); it++) {
|
||||
ProbFormulas& formulas = (*it)->formulas();
|
||||
for (unsigned i = 0; i < formulas.size(); i++) {
|
||||
if (formulas[i].group() == group1 ||
|
||||
formulas[i].group() == group2) {
|
||||
formulas[i].setGroup (newGroup);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
70
packages/CLPBN/clpbn/bp/ParfactorList.h
Normal file
70
packages/CLPBN/clpbn/bp/ParfactorList.h
Normal file
@ -0,0 +1,70 @@
|
||||
#ifndef HORUS_PARFACTORLIST_H
|
||||
#define HORUS_PARFACTORLIST_H
|
||||
|
||||
#include <list>
|
||||
|
||||
#include "Parfactor.h"
|
||||
#include "ProbFormula.h"
|
||||
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
class ParfactorList
|
||||
{
|
||||
public:
|
||||
ParfactorList (void) { }
|
||||
ParfactorList (Parfactors&);
|
||||
list<Parfactor*>& getParfactors (void) { return pfList_; }
|
||||
const list<Parfactor*>& getParfactors (void) const { return pfList_; }
|
||||
|
||||
void add (Parfactor* pf);
|
||||
void add (Parfactors& pfs);
|
||||
void addShattered (Parfactor* pf);
|
||||
list<Parfactor*>::iterator remove (list<Parfactor*>::iterator);
|
||||
list<Parfactor*>::iterator deleteAndRemove (list<Parfactor*>::iterator);
|
||||
|
||||
void clear (void) { pfList_.clear(); }
|
||||
unsigned size (void) const { return pfList_.size(); }
|
||||
|
||||
|
||||
void shatter (void);
|
||||
|
||||
typedef std::list<Parfactor*>::iterator iterator;
|
||||
iterator begin (void) { return pfList_.begin(); }
|
||||
iterator end (void) { return pfList_.end(); }
|
||||
|
||||
typedef std::list<Parfactor*>::const_iterator const_iterator;
|
||||
const_iterator begin (void) const { return pfList_.begin(); }
|
||||
const_iterator end (void) const { return pfList_.end(); }
|
||||
|
||||
void print (void) const;
|
||||
|
||||
private:
|
||||
|
||||
static std::pair<Parfactors, Parfactors> shatter (
|
||||
ProbFormulas&,
|
||||
Parfactor*,
|
||||
ProbFormulas&,
|
||||
Parfactor*);
|
||||
|
||||
static std::pair<Parfactors, Parfactors> shatter (
|
||||
ProbFormula&,
|
||||
Parfactor*,
|
||||
ProbFormula&,
|
||||
Parfactor*);
|
||||
|
||||
static Parfactors shatter (
|
||||
Parfactor*,
|
||||
const ProbFormula&,
|
||||
ConstraintTree*,
|
||||
ConstraintTree*,
|
||||
unsigned);
|
||||
|
||||
void unifyGroups (unsigned group1, unsigned group2);
|
||||
|
||||
list<Parfactor*> pfList_;
|
||||
};
|
||||
|
||||
#endif // HORUS_PARFACTORLIST_H
|
||||
|
115
packages/CLPBN/clpbn/bp/ProbFormula.cpp
Normal file
115
packages/CLPBN/clpbn/bp/ProbFormula.cpp
Normal file
@ -0,0 +1,115 @@
|
||||
#include "ProbFormula.h"
|
||||
|
||||
|
||||
int ProbFormula::freeGroup_ = 0;
|
||||
|
||||
|
||||
|
||||
bool
|
||||
ProbFormula::sameSkeletonAs (const ProbFormula& f) const
|
||||
{
|
||||
return functor_ == f.functor() && logVars_.size() == f.arity();
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
ProbFormula::contains (LogVar lv) const
|
||||
{
|
||||
return std::find (logVars_.begin(), logVars_.end(), lv) !=
|
||||
logVars_.end();
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
ProbFormula::contains (LogVarSet s) const
|
||||
{
|
||||
return LogVarSet (logVars_).contains (s);
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
ProbFormula::isAtom (void) const
|
||||
{
|
||||
return logVars_.size() == 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
ProbFormula::isCounting (void) const
|
||||
{
|
||||
return countedLogVar_.valid();
|
||||
}
|
||||
|
||||
|
||||
|
||||
LogVar
|
||||
ProbFormula::countedLogVar (void) const
|
||||
{
|
||||
assert (isCounting());
|
||||
return countedLogVar_;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
ProbFormula::setCountedLogVar (LogVar lv)
|
||||
{
|
||||
countedLogVar_ = lv;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
ProbFormula::rename (LogVar oldName, LogVar newName)
|
||||
{
|
||||
for (unsigned i = 0; i < logVars_.size(); i++) {
|
||||
if (logVars_[i] == oldName) {
|
||||
logVars_[i] = newName;
|
||||
}
|
||||
}
|
||||
if (isCounting() && countedLogVar_ == oldName) {
|
||||
countedLogVar_ = newName;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
ProbFormula::operator== (const ProbFormula& f) const
|
||||
{
|
||||
return functor_ == f.functor_ && logVars_ == f.logVars_ ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
ostream& operator<< (ostream &os, const ProbFormula& f)
|
||||
{
|
||||
os << f.functor_;
|
||||
if (f.isAtom() == false) {
|
||||
os << "(" ;
|
||||
for (unsigned i = 0; i < f.logVars_.size(); i++) {
|
||||
if (i != 0) os << ",";
|
||||
if (f.isCounting() && f.logVars_[i] == f.countedLogVar_) {
|
||||
os << "#" ;
|
||||
}
|
||||
os << f.logVars_[i];
|
||||
}
|
||||
os << ")" ;
|
||||
}
|
||||
os << "::" << f.range_;
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsigned
|
||||
ProbFormula::getNewGroup (void)
|
||||
{
|
||||
freeGroup_ ++;
|
||||
return freeGroup_;
|
||||
}
|
||||
|
71
packages/CLPBN/clpbn/bp/ProbFormula.h
Normal file
71
packages/CLPBN/clpbn/bp/ProbFormula.h
Normal file
@ -0,0 +1,71 @@
|
||||
#ifndef HORUS_PROBFORMULA_H
|
||||
#define HORUS_PROBFORMULA_H
|
||||
|
||||
#include <limits>
|
||||
|
||||
#include "ConstraintTree.h"
|
||||
#include "LiftedUtils.h"
|
||||
#include "Horus.h"
|
||||
|
||||
|
||||
class ProbFormula
|
||||
{
|
||||
public:
|
||||
ProbFormula (Symbol f, const LogVars& lvs, unsigned range)
|
||||
: functor_(f), logVars_(lvs), range_(range),
|
||||
countedLogVar_() { }
|
||||
|
||||
ProbFormula (Symbol f, unsigned r) : functor_(f), range_(r) { }
|
||||
|
||||
Symbol functor (void) const { return functor_; }
|
||||
|
||||
unsigned arity (void) const { return logVars_.size(); }
|
||||
|
||||
unsigned range (void) const { return range_; }
|
||||
|
||||
LogVars& logVars (void) { return logVars_; }
|
||||
|
||||
const LogVars& logVars (void) const { return logVars_; }
|
||||
|
||||
LogVarSet logVarSet (void) const { return LogVarSet (logVars_); }
|
||||
|
||||
unsigned group (void) const { return groupId_; }
|
||||
|
||||
void setGroup (unsigned g) { groupId_ = g; }
|
||||
|
||||
bool sameSkeletonAs (const ProbFormula&) const;
|
||||
|
||||
bool contains (LogVar) const;
|
||||
|
||||
bool contains (LogVarSet) const;
|
||||
|
||||
bool isAtom (void) const;
|
||||
|
||||
bool isCounting (void) const;
|
||||
|
||||
LogVar countedLogVar (void) const;
|
||||
|
||||
void setCountedLogVar (LogVar);
|
||||
|
||||
void rename (LogVar, LogVar);
|
||||
|
||||
bool operator== (const ProbFormula& f) const;
|
||||
|
||||
friend ostream& operator<< (ostream &out, const ProbFormula& f);
|
||||
|
||||
static unsigned getNewGroup (void);
|
||||
|
||||
private:
|
||||
Symbol functor_;
|
||||
LogVars logVars_;
|
||||
unsigned range_;
|
||||
LogVar countedLogVar_;
|
||||
unsigned groupId_;
|
||||
static int freeGroup_;
|
||||
};
|
||||
|
||||
typedef vector<ProbFormula> ProbFormulas;
|
||||
|
||||
|
||||
#endif // HORUS_PROBFORMULA_H
|
||||
|
@ -1,308 +0,0 @@
|
||||
#ifndef HORUS_SHARED_H
|
||||
#define HORUS_SHARED_H
|
||||
|
||||
#include <cmath>
|
||||
#include <cassert>
|
||||
#include <limits>
|
||||
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
|
||||
TypeName(const TypeName&); \
|
||||
void operator=(const TypeName&)
|
||||
|
||||
using namespace std;
|
||||
|
||||
class VarNode;
|
||||
class BayesNet;
|
||||
class BayesNode;
|
||||
class Factor;
|
||||
class FgVarNode;
|
||||
class FgFacNode;
|
||||
class SpLink;
|
||||
class BpLink;
|
||||
|
||||
typedef double Param;
|
||||
typedef vector<Param> ParamSet;
|
||||
typedef unsigned VarId;
|
||||
typedef vector<VarId> VarIdSet;
|
||||
typedef vector<VarNode*> VarNodes;
|
||||
typedef vector<BayesNode*> BnNodeSet;
|
||||
typedef vector<FgVarNode*> FgVarSet;
|
||||
typedef vector<FgFacNode*> FgFacSet;
|
||||
typedef vector<Factor*> FactorSet;
|
||||
typedef vector<string> States;
|
||||
typedef vector<unsigned> Ranges;
|
||||
typedef vector<unsigned> DConf;
|
||||
typedef pair<unsigned, unsigned> DConstraint;
|
||||
|
||||
|
||||
// level of debug information
|
||||
static const unsigned DL = 0;
|
||||
|
||||
static const int NO_EVIDENCE = -1;
|
||||
|
||||
// number of digits to show when printing a parameter
|
||||
static const unsigned PRECISION = 5;
|
||||
|
||||
static const bool COLLECT_STATISTICS = false;
|
||||
|
||||
static const bool EXPORT_TO_GRAPHVIZ = false;
|
||||
static const unsigned EXPORT_MINIMAL_SIZE = 100;
|
||||
|
||||
static const double INF = -numeric_limits<Param>::infinity();
|
||||
|
||||
|
||||
namespace NumberSpace {
|
||||
enum ns {
|
||||
NORMAL,
|
||||
LOGARITHM
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
extern NumberSpace::ns NSPACE;
|
||||
|
||||
|
||||
namespace InfAlgorithms {
|
||||
enum InfAlgs
|
||||
{
|
||||
VE, // variable elimination
|
||||
BN_BP, // bayesian network belief propagation
|
||||
FG_BP, // factor graph belief propagation
|
||||
CBP // counting bp solver
|
||||
};
|
||||
extern InfAlgs infAlgorithm;
|
||||
};
|
||||
|
||||
|
||||
namespace BpOptions
|
||||
{
|
||||
enum Schedule {
|
||||
SEQ_FIXED,
|
||||
SEQ_RANDOM,
|
||||
PARALLEL,
|
||||
MAX_RESIDUAL
|
||||
};
|
||||
extern Schedule schedule;
|
||||
extern double accuracy;
|
||||
extern unsigned maxIter;
|
||||
extern bool useAlwaysLoopySolver;
|
||||
}
|
||||
|
||||
|
||||
namespace Util
|
||||
{
|
||||
void toLog (ParamSet&);
|
||||
void fromLog (ParamSet&);
|
||||
void normalize (ParamSet&);
|
||||
void logSum (Param&, Param);
|
||||
void multiply (ParamSet&, const ParamSet&);
|
||||
void multiply (ParamSet&, const ParamSet&, unsigned);
|
||||
void add (ParamSet&, const ParamSet&);
|
||||
void add (ParamSet&, const ParamSet&, unsigned);
|
||||
void pow (ParamSet&, unsigned);
|
||||
Param pow (Param, unsigned);
|
||||
double getL1Distance (const ParamSet&, const ParamSet&);
|
||||
double getMaxNorm (const ParamSet&, const ParamSet&);
|
||||
unsigned getNumberOfDigits (int);
|
||||
bool isInteger (const string&);
|
||||
string parametersToString (const ParamSet&, unsigned = PRECISION);
|
||||
BayesNet* generateBayesianNetworkTreeWithLevel (unsigned);
|
||||
vector<DConf> getDomainConfigurations (const VarNodes&);
|
||||
vector<string> getJointStateStrings (const VarNodes&);
|
||||
double tl (Param v);
|
||||
double fl (Param v);
|
||||
double multIdenty();
|
||||
double addIdenty();
|
||||
double withEvidence();
|
||||
double noEvidence();
|
||||
double one();
|
||||
double zero();
|
||||
};
|
||||
|
||||
|
||||
|
||||
inline void
|
||||
Util::logSum (Param& x, Param y)
|
||||
{
|
||||
// x = log (exp (x) + exp (y)); return;
|
||||
assert (isfinite (x) && finite (y));
|
||||
// If one value is much smaller than the other, keep the larger value.
|
||||
if (x < (y - log (1e200))) {
|
||||
x = y;
|
||||
return;
|
||||
}
|
||||
if (y < (x - log (1e200))) {
|
||||
return;
|
||||
}
|
||||
double diff = x - y;
|
||||
assert (isfinite (diff) && finite (x) && finite (y));
|
||||
if (!isfinite (exp (diff))) { // difference is too large
|
||||
x = x > y ? x : y;
|
||||
} else { // otherwise return the sum.
|
||||
x = y + log (static_cast<double>(1.0) + exp (diff));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline void
|
||||
Util::multiply (ParamSet& v1, const ParamSet& v2)
|
||||
{
|
||||
assert (v1.size() == v2.size());
|
||||
for (unsigned i = 0; i < v1.size(); i++) {
|
||||
v1[i] *= v2[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline void
|
||||
Util::multiply (ParamSet& v1, const ParamSet& v2, unsigned repetitions)
|
||||
{
|
||||
for (unsigned count = 0; count < v1.size(); ) {
|
||||
for (unsigned i = 0; i < v2.size(); i++) {
|
||||
for (unsigned r = 0; r < repetitions; r++) {
|
||||
v1[count] *= v2[i];
|
||||
count ++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline void
|
||||
Util::add (ParamSet& v1, const ParamSet& v2)
|
||||
{
|
||||
assert (v1.size() == v2.size());
|
||||
for (unsigned i = 0; i < v1.size(); i++) {
|
||||
v1[i] += v2[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline void
|
||||
Util::add (ParamSet& v1, const ParamSet& v2, unsigned repetitions)
|
||||
{
|
||||
for (unsigned count = 0; count < v1.size(); ) {
|
||||
for (unsigned i = 0; i < v2.size(); i++) {
|
||||
for (unsigned r = 0; r < repetitions; r++) {
|
||||
v1[count] += v2[i];
|
||||
count ++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline double
|
||||
Util::tl (Param v)
|
||||
{
|
||||
return NSPACE == NumberSpace::NORMAL ? v : log(v);
|
||||
}
|
||||
|
||||
inline double
|
||||
Util::fl (Param v)
|
||||
{
|
||||
return NSPACE == NumberSpace::NORMAL ? v : exp(v);
|
||||
}
|
||||
|
||||
inline double
|
||||
Util::multIdenty() {
|
||||
return NSPACE == NumberSpace::NORMAL ? 1.0 : 0.0;
|
||||
}
|
||||
|
||||
inline double
|
||||
Util::addIdenty()
|
||||
{
|
||||
return NSPACE == NumberSpace::NORMAL ? 0.0 : INF;
|
||||
}
|
||||
|
||||
inline double
|
||||
Util::withEvidence()
|
||||
{
|
||||
return NSPACE == NumberSpace::NORMAL ? 1.0 : 0.0;
|
||||
}
|
||||
|
||||
inline double
|
||||
Util::noEvidence() {
|
||||
return NSPACE == NumberSpace::NORMAL ? 0.0 : INF;
|
||||
}
|
||||
|
||||
inline double
|
||||
Util::one()
|
||||
{
|
||||
return NSPACE == NumberSpace::NORMAL ? 1.0 : 0.0;
|
||||
}
|
||||
|
||||
inline double
|
||||
Util::zero() {
|
||||
return NSPACE == NumberSpace::NORMAL ? 0.0 : INF;
|
||||
}
|
||||
|
||||
|
||||
struct NetInfo
|
||||
{
|
||||
NetInfo (unsigned size, bool loopy, unsigned nIters, double time)
|
||||
{
|
||||
this->size = size;
|
||||
this->loopy = loopy;
|
||||
this->nIters = nIters;
|
||||
this->time = time;
|
||||
}
|
||||
unsigned size;
|
||||
bool loopy;
|
||||
unsigned nIters;
|
||||
double time;
|
||||
};
|
||||
|
||||
|
||||
struct CompressInfo
|
||||
{
|
||||
CompressInfo (unsigned a, unsigned b, unsigned c, unsigned d, unsigned e)
|
||||
{
|
||||
nGroundVars = a;
|
||||
nGroundFactors = b;
|
||||
nClusterVars = c;
|
||||
nClusterFactors = d;
|
||||
nWithoutNeighs = e;
|
||||
}
|
||||
unsigned nGroundVars;
|
||||
unsigned nGroundFactors;
|
||||
unsigned nClusterVars;
|
||||
unsigned nClusterFactors;
|
||||
unsigned nWithoutNeighs;
|
||||
};
|
||||
|
||||
|
||||
class Statistics
|
||||
{
|
||||
public:
|
||||
static unsigned getSolvedNetworksCounting (void);
|
||||
static void incrementPrimaryNetworksCounting (void);
|
||||
static unsigned getPrimaryNetworksCounting (void);
|
||||
static void updateStatistics (unsigned, bool, unsigned, double);
|
||||
static void printStatistics (void);
|
||||
static void writeStatisticsToFile (const char*);
|
||||
static void updateCompressingStatistics (
|
||||
unsigned, unsigned, unsigned, unsigned, unsigned);
|
||||
|
||||
private:
|
||||
static string getStatisticString (void);
|
||||
|
||||
static vector<NetInfo> netInfo_;
|
||||
static vector<CompressInfo> compressInfo_;
|
||||
static unsigned primaryNetCount_;
|
||||
};
|
||||
|
||||
#endif // HORUS_SHARED_H
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "Solver.h"
|
||||
#include "Util.h"
|
||||
|
||||
|
||||
void
|
||||
@ -7,7 +8,6 @@ Solver::printAllPosterioris (void)
|
||||
const VarNodes& vars = gm_->getVariableNodes();
|
||||
for (unsigned i = 0; i < vars.size(); i++) {
|
||||
printPosterioriOf (vars[i]->varId());
|
||||
cout << endl;
|
||||
}
|
||||
}
|
||||
|
||||
@ -17,7 +17,7 @@ void
|
||||
Solver::printPosterioriOf (VarId vid)
|
||||
{
|
||||
VarNode* var = gm_->getVariableNode (vid);
|
||||
const ParamSet& posterioriDist = getPosterioriOf (vid);
|
||||
const Params& posterioriDist = getPosterioriOf (vid);
|
||||
const States& states = var->states();
|
||||
for (unsigned i = 0; i < states.size(); i++) {
|
||||
cout << "P(" << var->label() << "=" << states[i] << ") = " ;
|
||||
@ -30,10 +30,10 @@ Solver::printPosterioriOf (VarId vid)
|
||||
|
||||
|
||||
void
|
||||
Solver::printJointDistributionOf (const VarIdSet& vids)
|
||||
Solver::printJointDistributionOf (const VarIds& vids)
|
||||
{
|
||||
VarNodes vars;
|
||||
VarIdSet vidsWithoutEvidence;
|
||||
VarIds vidsWithoutEvidence;
|
||||
for (unsigned i = 0; i < vids.size(); i++) {
|
||||
VarNode* var = gm_->getVariableNode (vids[i]);
|
||||
if (var->hasEvidence() == false) {
|
||||
@ -41,7 +41,7 @@ Solver::printJointDistributionOf (const VarIdSet& vids)
|
||||
vidsWithoutEvidence.push_back (vids[i]);
|
||||
}
|
||||
}
|
||||
const ParamSet& jointDist = getJointDistributionOf (vidsWithoutEvidence);
|
||||
const Params& jointDist = getJointDistributionOf (vidsWithoutEvidence);
|
||||
vector<string> jointStrings = Util::getJointStateStrings (vars);
|
||||
for (unsigned i = 0; i < jointDist.size(); i++) {
|
||||
cout << "P(" << jointStrings[i] << ") = " ;
|
||||
|
@ -17,12 +17,12 @@ class Solver
|
||||
}
|
||||
virtual ~Solver() {} // to ensure that subclass destructor is called
|
||||
virtual void runSolver (void) = 0;
|
||||
virtual ParamSet getPosterioriOf (VarId) = 0;
|
||||
virtual ParamSet getJointDistributionOf (const VarIdSet&) = 0;
|
||||
virtual Params getPosterioriOf (VarId) = 0;
|
||||
virtual Params getJointDistributionOf (const VarIds&) = 0;
|
||||
|
||||
void printAllPosterioris (void);
|
||||
void printPosterioriOf (VarId vid);
|
||||
void printJointDistributionOf (const VarIdSet& vids);
|
||||
void printJointDistributionOf (const VarIds& vids);
|
||||
|
||||
private:
|
||||
const GraphicalModel* gm_;
|
||||
|
@ -1,246 +0,0 @@
|
||||
#ifndef HORUS_STATESINDEXER_H
|
||||
#define HORUS_STATESINDEXER_H
|
||||
|
||||
#include <iomanip>
|
||||
|
||||
class StatesIndexer {
|
||||
public:
|
||||
|
||||
StatesIndexer (const Ranges& ranges)
|
||||
{
|
||||
maxIndex_ = 1;
|
||||
states_.resize (ranges.size(), 0);
|
||||
ranges_ = ranges;
|
||||
for (unsigned i = 0; i < ranges.size(); i++) {
|
||||
maxIndex_ *= ranges[i];
|
||||
}
|
||||
linearIndex_ = 0;
|
||||
}
|
||||
|
||||
|
||||
StatesIndexer (const VarNodes& vars)
|
||||
{
|
||||
maxIndex_ = 1;
|
||||
states_.resize (vars.size(), 0);
|
||||
ranges_.reserve (vars.size());
|
||||
for (unsigned i = 0; i < vars.size(); i++) {
|
||||
ranges_.push_back (vars[i]->nrStates());
|
||||
maxIndex_ *= vars[i]->nrStates();
|
||||
}
|
||||
linearIndex_ = 0;
|
||||
}
|
||||
|
||||
StatesIndexer& operator++ (void) {
|
||||
for (int i = ranges_.size() - 1; i >= 0; i--) {
|
||||
states_[i] ++;
|
||||
if (states_[i] == (int)ranges_[i]) {
|
||||
states_[i] = 0;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
linearIndex_ ++;
|
||||
return *this;
|
||||
}
|
||||
|
||||
StatesIndexer& operator-- (void) {
|
||||
for (int i = ranges_.size() - 1; i >= 0; i--) {
|
||||
states_[i] --;
|
||||
if (states_[i] == -1) {
|
||||
states_[i] = ranges_[i] - 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
linearIndex_ --;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void incrementState (unsigned whichVar)
|
||||
{
|
||||
for (int i = whichVar; i >= 0; i--) {
|
||||
states_[i] ++;
|
||||
if (states_[i] == (int)ranges_[i] && i != 0) {
|
||||
if (i == 0) {
|
||||
linearIndex_ = maxIndex_;
|
||||
} else {
|
||||
states_[i] = 0;
|
||||
}
|
||||
} else {
|
||||
linearIndex_ = getLinearIndexFromStates();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void decrementState (unsigned whichVar)
|
||||
{
|
||||
for (int i = whichVar; i >= 0; i--) {
|
||||
states_[i] --;
|
||||
if (states_[i] == -1) {
|
||||
if (i == 0) {
|
||||
linearIndex_ = -1;
|
||||
} else {
|
||||
states_[i] = ranges_[i] - 1;
|
||||
}
|
||||
} else {
|
||||
linearIndex_ = getLinearIndexFromStates();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void nextSameState (unsigned whichVar)
|
||||
{
|
||||
for (int i = ranges_.size() - 1; i >= 0; i--) {
|
||||
if (i != (int)whichVar) {
|
||||
states_[i] ++;
|
||||
if (states_[i] == (int)ranges_[i]) {
|
||||
if (i == 0 || (i-1 == (int)whichVar && whichVar == 0)) {
|
||||
linearIndex_ = maxIndex_;
|
||||
} else {
|
||||
states_[i] = 0;
|
||||
}
|
||||
} else {
|
||||
linearIndex_ = getLinearIndexFromStates();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void previousSameState (unsigned whichVar)
|
||||
{
|
||||
for (int i = ranges_.size() - 1; i >= 0; i--) {
|
||||
if (i != (int)whichVar) {
|
||||
states_[i] --;
|
||||
if (states_[i] == - 1) {
|
||||
if (i == 0 || (i-1 == (int)whichVar && whichVar == 0)) {
|
||||
linearIndex_ = -1;
|
||||
} else {
|
||||
states_[i] = ranges_[i] - 1;
|
||||
}
|
||||
} else {
|
||||
linearIndex_ = getLinearIndexFromStates();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void moveToBegin (void)
|
||||
{
|
||||
std::fill (states_.begin(), states_.end(), 0);
|
||||
linearIndex_ = 0;
|
||||
}
|
||||
|
||||
void moveToEnd (void)
|
||||
{
|
||||
for (unsigned i = 0; i < states_.size(); i++) {
|
||||
states_[i] = ranges_[i] - 1;
|
||||
}
|
||||
linearIndex_ = maxIndex_ - 1;
|
||||
}
|
||||
|
||||
bool valid (void) const
|
||||
{
|
||||
return linearIndex_ >= 0 && linearIndex_ < (int)maxIndex_;
|
||||
}
|
||||
|
||||
unsigned getLinearIndex (void) const
|
||||
{
|
||||
return linearIndex_;
|
||||
}
|
||||
|
||||
const vector<int>& getStates (void) const
|
||||
{
|
||||
return states_;
|
||||
}
|
||||
|
||||
unsigned operator[] (unsigned whichVar) const
|
||||
{
|
||||
assert (valid());
|
||||
assert (whichVar < states_.size());
|
||||
return states_[whichVar];
|
||||
}
|
||||
|
||||
string toString (void) const
|
||||
{
|
||||
stringstream ss;
|
||||
ss << "linear index=" << setw (3) << linearIndex_ << " " ;
|
||||
ss << "states= [" << states_[0] ;
|
||||
for (unsigned i = 1; i < states_.size(); i++) {
|
||||
ss << ", " << states_[i];
|
||||
}
|
||||
ss << "]" ;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned getLinearIndexFromStates (void)
|
||||
{
|
||||
unsigned prod = 1;
|
||||
unsigned linearIndex = 0;
|
||||
for (int i = states_.size() - 1; i >= 0; i--) {
|
||||
linearIndex += states_[i] * prod;
|
||||
prod *= ranges_[i];
|
||||
}
|
||||
return linearIndex;
|
||||
}
|
||||
|
||||
int linearIndex_;
|
||||
int maxIndex_;
|
||||
vector<int> states_;
|
||||
vector<unsigned> ranges_;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
FgVarNode* v1 = new FgVarNode (0, 4);
|
||||
FgVarNode* v2 = new FgVarNode (1, 3);
|
||||
FgVarNode* v3 = new FgVarNode (2, 2);
|
||||
FgVarSet vars = {v1,v2,v3};
|
||||
ParamSet params = {
|
||||
0.2, 0.44, 0.1, 0.88, 0.22,0.62,0.32, 0.42, 0.11, 0.88, 0.8,0.5,
|
||||
0.22, 0.4, 0.11, 0.8, 0.224,0.6,0.21, 0.44, 0.14, 0.68, 0.41,0.6
|
||||
};
|
||||
Factor f (vars,params);
|
||||
StatesIndexer idx (vars);
|
||||
while (idx.valid())
|
||||
{
|
||||
cout << idx.toString() << " p=" << params[idx.getLinearIndex()] << endl;
|
||||
idx.incrementVariableState (0);
|
||||
idx.nextSameState (1);
|
||||
++idx;
|
||||
}
|
||||
cout << endl;
|
||||
idx.moveToEnd();
|
||||
while (idx.valid())
|
||||
{
|
||||
cout << idx.toString() << " p=" << params[idx.getLinearIndex()] << endl;
|
||||
idx.decrementVariableState (0);
|
||||
idx.previousSameState (1);
|
||||
--idx;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
FgVarNode* x0 = new FgVarNode (0, 2);
|
||||
FgVarNode* x1 = new FgVarNode (1, 2);
|
||||
FgVarNode* x2 = new FgVarNode (2, 2);
|
||||
FgVarNode* x3 = new FgVarNode (2, 2);
|
||||
FgVarNode* x4 = new FgVarNode (2, 2);
|
||||
FgVarSet vars_ = {x0,x1,x2,x3,x4};
|
||||
ParamSet params_ = {
|
||||
0.2, 0.44, 0.1, 0.88, 0.11, 0.88, 0.8, 0.5,
|
||||
0.2, 0.44, 0.1, 0.88, 0.11, 0.88, 0.8, 0.5,
|
||||
0.2, 0.44, 0.1, 0.88, 0.11, 0.88, 0.8, 0.5,
|
||||
0.2, 0.44, 0.1, 0.88, 0.11, 0.88, 0.8, 0.5
|
||||
};
|
||||
Factor ff (vars_,params_);
|
||||
ff.printFactor();
|
||||
*/
|
||||
|
||||
#endif // HORUS_STATESINDEXER_H
|
||||
|
200
packages/CLPBN/clpbn/bp/TinySet.h
Normal file
200
packages/CLPBN/clpbn/bp/TinySet.h
Normal file
@ -0,0 +1,200 @@
|
||||
#ifndef HORUS_TINYSET_H
|
||||
#define HORUS_TINYSET_H
|
||||
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
template <typename T>
|
||||
class TinySet
|
||||
{
|
||||
public:
|
||||
TinySet (void) {}
|
||||
|
||||
TinySet (const T& t)
|
||||
{
|
||||
elements_.push_back (t);
|
||||
}
|
||||
|
||||
TinySet (const vector<T>& elements)
|
||||
{
|
||||
elements_.reserve (elements.size());
|
||||
for (unsigned i = 0; i < elements.size(); i++) {
|
||||
insert (elements[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TinySet (const TinySet<T>& s) : elements_(s.elements_) { }
|
||||
|
||||
void insert (const T& t)
|
||||
{
|
||||
typename vector<T>::iterator it =
|
||||
std::lower_bound (elements_.begin(), elements_.end(), t);
|
||||
if (it == elements_.end() || *it != t) {
|
||||
elements_.insert (it, t);
|
||||
}
|
||||
}
|
||||
|
||||
void remove (const T& t)
|
||||
{
|
||||
typename vector<T>::iterator it =
|
||||
std::lower_bound (elements_.begin(), elements_.end(), t);
|
||||
if (it != elements_.end()) {
|
||||
elements_.erase (it);
|
||||
}
|
||||
}
|
||||
|
||||
/* set union */
|
||||
TinySet operator| (const TinySet& s) const
|
||||
{
|
||||
TinySet res;
|
||||
std::set_union (
|
||||
elements_.begin(),
|
||||
elements_.end(),
|
||||
s.elements_.begin(),
|
||||
s.elements_.end(),
|
||||
std::back_inserter (res.elements_));
|
||||
return res;
|
||||
}
|
||||
|
||||
/* set intersection */
|
||||
TinySet operator& (const TinySet& s) const
|
||||
{
|
||||
TinySet res;
|
||||
std::set_intersection (
|
||||
elements_.begin(),
|
||||
elements_.end(),
|
||||
s.elements_.begin(),
|
||||
s.elements_.end(),
|
||||
std::back_inserter (res.elements_));
|
||||
return res;
|
||||
}
|
||||
|
||||
/* set difference */
|
||||
TinySet operator- (const TinySet& s) const
|
||||
{
|
||||
TinySet res;
|
||||
std::set_difference (
|
||||
elements_.begin(),
|
||||
elements_.end(),
|
||||
s.elements_.begin(),
|
||||
s.elements_.end(),
|
||||
std::back_inserter (res.elements_));
|
||||
return res;
|
||||
}
|
||||
|
||||
TinySet& operator|= (const TinySet& s)
|
||||
{
|
||||
return *this = (*this | s);
|
||||
}
|
||||
|
||||
TinySet& operator&= (const TinySet& s)
|
||||
{
|
||||
return *this = (*this & s);
|
||||
}
|
||||
|
||||
TinySet& operator-= (const TinySet& s)
|
||||
{
|
||||
return *this = (*this - s);
|
||||
}
|
||||
|
||||
bool contains (const T& t) const
|
||||
{
|
||||
return std::binary_search (
|
||||
elements_.begin(), elements_.end(), t);
|
||||
}
|
||||
|
||||
bool contains (const TinySet& s) const
|
||||
{
|
||||
return std::includes (
|
||||
elements_.begin(),
|
||||
elements_.end(),
|
||||
s.elements_.begin(),
|
||||
s.elements_.end());
|
||||
}
|
||||
|
||||
bool in (const TinySet& s) const
|
||||
{
|
||||
return std::includes (
|
||||
s.elements_.begin(),
|
||||
s.elements_.end(),
|
||||
elements_.begin(),
|
||||
elements_.end());
|
||||
}
|
||||
|
||||
bool intersects (const TinySet& s) const
|
||||
{
|
||||
return (*this & s).size() > 0;
|
||||
}
|
||||
|
||||
T operator[] (unsigned i) const
|
||||
{
|
||||
return elements_[i];
|
||||
}
|
||||
|
||||
const vector<T>& elements (void) const
|
||||
{
|
||||
return elements_;
|
||||
}
|
||||
|
||||
T front (void) const
|
||||
{
|
||||
return elements_.front();
|
||||
}
|
||||
|
||||
T back (void) const
|
||||
{
|
||||
return elements_.back();
|
||||
}
|
||||
|
||||
unsigned size (void) const
|
||||
{
|
||||
return elements_.size();
|
||||
}
|
||||
|
||||
bool empty (void) const
|
||||
{
|
||||
return elements_.size() == 0;
|
||||
}
|
||||
|
||||
typedef typename std::vector<T>::const_iterator const_iterator;
|
||||
|
||||
const_iterator begin (void) const
|
||||
{
|
||||
return elements_.begin();
|
||||
}
|
||||
|
||||
const_iterator end (void) const
|
||||
{
|
||||
return elements_.end();
|
||||
}
|
||||
|
||||
friend bool operator== (const TinySet& s1, const TinySet& s2)
|
||||
{
|
||||
return s1.elements_ == s2.elements_;
|
||||
}
|
||||
|
||||
friend bool operator!= (const TinySet& s1, const TinySet& s2)
|
||||
{
|
||||
return s1.elements_ != s2.elements_;
|
||||
}
|
||||
|
||||
friend std::ostream& operator << (std::ostream& out, const TinySet<T>& s)
|
||||
{
|
||||
out << "{" ;
|
||||
for (unsigned i = 0; i < s.size(); i++) {
|
||||
out << ((i != 0) ? "," : "") << s.elements()[i];
|
||||
}
|
||||
out << "}" ;
|
||||
return out;
|
||||
}
|
||||
|
||||
protected:
|
||||
vector<T> elements_;
|
||||
};
|
||||
|
||||
|
||||
#endif // HORUS_TINYSET_H
|
||||
|
@ -1,14 +1,19 @@
|
||||
#include <sstream>
|
||||
|
||||
#include "BayesNet.h"
|
||||
#include "VarNode.h"
|
||||
#include "Shared.h"
|
||||
#include "StatesIndexer.h"
|
||||
#include "Util.h"
|
||||
#include "Indexer.h"
|
||||
#include "GraphicalModel.h"
|
||||
|
||||
|
||||
namespace Globals {
|
||||
bool logDomain = false;
|
||||
};
|
||||
|
||||
|
||||
namespace InfAlgorithms {
|
||||
InfAlgs infAlgorithm = InfAlgorithms::VE;
|
||||
//InfAlgs infAlgorithm = InfAlgorithms::VE;
|
||||
//InfAlgs infAlgorithm = InfAlgorithms::BN_BP;
|
||||
//InfAlgs infAlgorithm = InfAlgorithms::FG_BP;
|
||||
InfAlgs infAlgorithm = InfAlgorithms::FG_BP;
|
||||
//InfAlgs infAlgorithm = InfAlgorithms::CBP;
|
||||
}
|
||||
|
||||
@ -20,12 +25,11 @@ Schedule schedule = BpOptions::Schedule::SEQ_FIXED;
|
||||
//Schedule schedule = BpOptions::Schedule::MAX_RESIDUAL;
|
||||
double accuracy = 0.0001;
|
||||
unsigned maxIter = 1000;
|
||||
bool useAlwaysLoopySolver = true;
|
||||
}
|
||||
|
||||
NumberSpace::ns NSPACE = NumberSpace::NORMAL;
|
||||
|
||||
unordered_map<VarId,VariableInfo> GraphicalModel::varsInfo_;
|
||||
unordered_map<unsigned,Distribution*> GraphicalModel::distsInfo_;
|
||||
|
||||
vector<NetInfo> Statistics::netInfo_;
|
||||
vector<CompressInfo> Statistics::compressInfo_;
|
||||
@ -35,7 +39,7 @@ unsigned Statistics::primaryNetCount_;
|
||||
namespace Util {
|
||||
|
||||
void
|
||||
toLog (ParamSet& v)
|
||||
toLog (Params& v)
|
||||
{
|
||||
for (unsigned i = 0; i < v.size(); i++) {
|
||||
v[i] = log (v[i]);
|
||||
@ -45,7 +49,7 @@ toLog (ParamSet& v)
|
||||
|
||||
|
||||
void
|
||||
fromLog (ParamSet& v)
|
||||
fromLog (Params& v)
|
||||
{
|
||||
for (unsigned i = 0; i < v.size(); i++) {
|
||||
v[i] = exp (v[i]);
|
||||
@ -55,92 +59,113 @@ fromLog (ParamSet& v)
|
||||
|
||||
|
||||
void
|
||||
normalize (ParamSet& v)
|
||||
normalize (Params& v)
|
||||
{
|
||||
double sum;
|
||||
switch (NSPACE) {
|
||||
case NumberSpace::NORMAL:
|
||||
sum = 0.0;
|
||||
for (unsigned i = 0; i < v.size(); i++) {
|
||||
sum += v[i];
|
||||
}
|
||||
assert (sum != 0.0);
|
||||
for (unsigned i = 0; i < v.size(); i++) {
|
||||
v[i] /= sum;
|
||||
}
|
||||
break;
|
||||
case NumberSpace::LOGARITHM:
|
||||
sum = addIdenty();
|
||||
for (unsigned i = 0; i < v.size(); i++) {
|
||||
logSum (sum, v[i]);
|
||||
}
|
||||
assert (sum != -numeric_limits<Param>::infinity());
|
||||
for (unsigned i = 0; i < v.size(); i++) {
|
||||
v[i] -= sum;
|
||||
}
|
||||
if (Globals::logDomain) {
|
||||
sum = addIdenty();
|
||||
for (unsigned i = 0; i < v.size(); i++) {
|
||||
logSum (sum, v[i]);
|
||||
}
|
||||
assert (sum != -numeric_limits<double>::infinity());
|
||||
for (unsigned i = 0; i < v.size(); i++) {
|
||||
v[i] -= sum;
|
||||
}
|
||||
} else {
|
||||
sum = 0.0;
|
||||
for (unsigned i = 0; i < v.size(); i++) {
|
||||
sum += v[i];
|
||||
}
|
||||
assert (sum != 0.0);
|
||||
for (unsigned i = 0; i < v.size(); i++) {
|
||||
v[i] /= sum;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
pow (ParamSet& v, unsigned expoent)
|
||||
pow (Params& v, double expoent)
|
||||
{
|
||||
if (expoent == 1) {
|
||||
return; // optimization
|
||||
}
|
||||
switch (NSPACE) {
|
||||
case NumberSpace::NORMAL:
|
||||
for (unsigned i = 0; i < v.size(); i++) {
|
||||
double value = 1.0;
|
||||
for (unsigned j = 0; j < expoent; j++) {
|
||||
value *= v[i];
|
||||
}
|
||||
v[i] = value;
|
||||
}
|
||||
break;
|
||||
case NumberSpace::LOGARITHM:
|
||||
for (unsigned i = 0; i < v.size(); i++) {
|
||||
v[i] *= expoent;
|
||||
}
|
||||
if (Globals::logDomain) {
|
||||
for (unsigned i = 0; i < v.size(); i++) {
|
||||
v[i] *= expoent;
|
||||
}
|
||||
} else {
|
||||
for (unsigned i = 0; i < v.size(); i++) {
|
||||
v[i] = std::pow (v[i], expoent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Param
|
||||
pow (Param p, unsigned expoent)
|
||||
void
|
||||
pow (Params& v, unsigned expoent)
|
||||
{
|
||||
double value = 1.0;
|
||||
switch (NSPACE) {
|
||||
case NumberSpace::NORMAL:
|
||||
for (unsigned i = 0; i < expoent; i++) {
|
||||
value *= p;
|
||||
}
|
||||
break;
|
||||
case NumberSpace::LOGARITHM:
|
||||
value = p * expoent;
|
||||
if (expoent == 1) {
|
||||
return;
|
||||
}
|
||||
if (Globals::logDomain) {
|
||||
for (unsigned i = 0; i < v.size(); i++) {
|
||||
v[i] *= expoent;
|
||||
}
|
||||
} else {
|
||||
for (unsigned i = 0; i < v.size(); i++) {
|
||||
v[i] = std::pow (v[i], expoent);
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
double
|
||||
getL1Distance (const ParamSet& v1, const ParamSet& v2)
|
||||
pow (double p, unsigned expoent)
|
||||
{
|
||||
return Globals::logDomain ? p * expoent : std::pow (p, expoent);
|
||||
}
|
||||
|
||||
|
||||
|
||||
double
|
||||
factorial (double num)
|
||||
{
|
||||
double result = 1.0;
|
||||
for (int i = 1; i <= num; i++) {
|
||||
result *= i;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsigned
|
||||
nrCombinations (unsigned n, unsigned r)
|
||||
{
|
||||
assert (n >= r);
|
||||
unsigned prod = 1;
|
||||
for (int i = (int)n; i > (int)(n - r); i--) {
|
||||
prod *= i;
|
||||
}
|
||||
return (prod / factorial (r));
|
||||
}
|
||||
|
||||
|
||||
|
||||
double
|
||||
getL1Distance (const Params& v1, const Params& v2)
|
||||
{
|
||||
assert (v1.size() == v2.size());
|
||||
double dist = 0.0;
|
||||
switch (NSPACE) {
|
||||
case NumberSpace::NORMAL:
|
||||
for (unsigned i = 0; i < v1.size(); i++) {
|
||||
dist += abs (v1[i] - v2[i]);
|
||||
}
|
||||
break;
|
||||
case NumberSpace::LOGARITHM:
|
||||
for (unsigned i = 0; i < v1.size(); i++) {
|
||||
dist += abs (exp(v1[i]) - exp(v2[i]));
|
||||
}
|
||||
if (Globals::logDomain) {
|
||||
for (unsigned i = 0; i < v1.size(); i++) {
|
||||
dist += abs (exp(v1[i]) - exp(v2[i]));
|
||||
}
|
||||
} else {
|
||||
for (unsigned i = 0; i < v1.size(); i++) {
|
||||
dist += abs (v1[i] - v2[i]);
|
||||
}
|
||||
}
|
||||
return dist;
|
||||
}
|
||||
@ -148,26 +173,24 @@ getL1Distance (const ParamSet& v1, const ParamSet& v2)
|
||||
|
||||
|
||||
double
|
||||
getMaxNorm (const ParamSet& v1, const ParamSet& v2)
|
||||
getMaxNorm (const Params& v1, const Params& v2)
|
||||
{
|
||||
assert (v1.size() == v2.size());
|
||||
double max = 0.0;
|
||||
switch (NSPACE) {
|
||||
case NumberSpace::NORMAL:
|
||||
for (unsigned i = 0; i < v1.size(); i++) {
|
||||
double diff = abs (v1[i] - v2[i]);
|
||||
if (diff > max) {
|
||||
max = diff;
|
||||
}
|
||||
if (Globals::logDomain) {
|
||||
for (unsigned i = 0; i < v1.size(); i++) {
|
||||
double diff = abs (exp(v1[i]) - exp(v2[i]));
|
||||
if (diff > max) {
|
||||
max = diff;
|
||||
}
|
||||
break;
|
||||
case NumberSpace::LOGARITHM:
|
||||
for (unsigned i = 0; i < v1.size(); i++) {
|
||||
double diff = abs (exp(v1[i]) - exp(v2[i]));
|
||||
if (diff > max) {
|
||||
max = diff;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (unsigned i = 0; i < v1.size(); i++) {
|
||||
double diff = abs (v1[i] - v2[i]);
|
||||
if (diff > max) {
|
||||
max = diff;
|
||||
}
|
||||
}
|
||||
}
|
||||
return max;
|
||||
}
|
||||
@ -200,16 +223,14 @@ isInteger (const string& s)
|
||||
|
||||
|
||||
string
|
||||
parametersToString (const ParamSet& v, unsigned precision)
|
||||
parametersToString (const Params& v, unsigned precision)
|
||||
{
|
||||
stringstream ss;
|
||||
ss.precision (precision);
|
||||
ss << "[" ;
|
||||
for (unsigned i = 0; i < v.size() - 1; i++) {
|
||||
ss << v[i] << ", " ;
|
||||
}
|
||||
if (v.size() != 0) {
|
||||
ss << v[v.size() - 1];
|
||||
for (unsigned i = 0; i < v.size(); i++) {
|
||||
if (i != 0) ss << ", " ;
|
||||
ss << v[i];
|
||||
}
|
||||
ss << "]" ;
|
||||
return ss.str();
|
||||
@ -217,69 +238,6 @@ parametersToString (const ParamSet& v, unsigned precision)
|
||||
|
||||
|
||||
|
||||
BayesNet*
|
||||
generateBayesianNetworkTreeWithLevel (unsigned level)
|
||||
{
|
||||
BayesNet* bn = new BayesNet();
|
||||
Distribution* dist = new Distribution (ParamSet() = {0.1, 0.5, 0.2, 0.7});
|
||||
BayesNode* root = bn->addNode (0, 2, -1, BnNodeSet() = {},
|
||||
new Distribution (ParamSet() = {0.1, 0.5}));
|
||||
BnNodeSet prevLevel = { root };
|
||||
BnNodeSet currLevel;
|
||||
VarId vidCount = 1;
|
||||
for (unsigned l = 1; l < level; l++) {
|
||||
currLevel.clear();
|
||||
for (unsigned i = 0; i < prevLevel.size(); i++) {
|
||||
currLevel.push_back (
|
||||
bn->addNode (vidCount, 2, -1, BnNodeSet() = {prevLevel[i]}, dist));
|
||||
vidCount ++;
|
||||
currLevel.push_back (
|
||||
bn->addNode (vidCount, 2, -1, BnNodeSet() = {prevLevel[i]}, dist));
|
||||
vidCount ++;
|
||||
}
|
||||
prevLevel = currLevel;
|
||||
}
|
||||
for (unsigned i = 0; i < prevLevel.size(); i++) {
|
||||
prevLevel[i]->setEvidence (0);
|
||||
}
|
||||
bn->setIndexes();
|
||||
return bn;
|
||||
}
|
||||
|
||||
|
||||
|
||||
vector<DConf>
|
||||
getDomainConfigurations (const VarNodes& vars)
|
||||
{
|
||||
// TODO this method must die
|
||||
unsigned nConfs = 1;
|
||||
for (unsigned i = 0; i < vars.size(); i++) {
|
||||
nConfs *= vars[i]->nrStates();
|
||||
}
|
||||
|
||||
vector<DConf> confs (nConfs);
|
||||
for (unsigned i = 0; i < nConfs; i++) {
|
||||
confs[i].resize (vars.size());
|
||||
}
|
||||
|
||||
unsigned nReps = 1;
|
||||
for (int i = vars.size() - 1; i >= 0; i--) {
|
||||
unsigned index = 0;
|
||||
while (index < nConfs) {
|
||||
for (unsigned j = 0; j < vars[i]->nrStates(); j++) {
|
||||
for (unsigned r = 0; r < nReps; r++) {
|
||||
confs[index][i] = j;
|
||||
index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
nReps *= vars[i]->nrStates();
|
||||
}
|
||||
return confs;
|
||||
}
|
||||
|
||||
|
||||
|
||||
vector<string>
|
||||
getJointStateStrings (const VarNodes& vars)
|
||||
{
|
||||
@ -298,6 +256,7 @@ getJointStateStrings (const VarNodes& vars)
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -390,11 +349,6 @@ Statistics::getStatisticString (void)
|
||||
}
|
||||
ss1 << "max iterations: " << BpOptions::maxIter << endl;
|
||||
ss1 << "accuracy " << BpOptions::accuracy << endl;
|
||||
if (BpOptions::useAlwaysLoopySolver) {
|
||||
ss1 << "always loopy solver: yes" << endl;
|
||||
} else {
|
||||
ss1 << "always loopy solver: no" << endl;
|
||||
}
|
||||
ss1 << endl << endl;
|
||||
|
||||
ss2 << "---------------------------------------------------" << endl;
|
||||
|
244
packages/CLPBN/clpbn/bp/Util.h
Normal file
244
packages/CLPBN/clpbn/bp/Util.h
Normal file
@ -0,0 +1,244 @@
|
||||
#ifndef HORUS_UTIL_H
|
||||
#define HORUS_UTIL_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "Horus.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace Util {
|
||||
|
||||
void toLog (Params&);
|
||||
void fromLog (Params&);
|
||||
void normalize (Params&);
|
||||
void logSum (double&, double);
|
||||
void multiply (Params&, const Params&);
|
||||
void multiply (Params&, const Params&, unsigned);
|
||||
void add (Params&, const Params&);
|
||||
void add (Params&, const Params&, unsigned);
|
||||
void pow (Params&, double);
|
||||
void pow (Params&, unsigned);
|
||||
double pow (double, unsigned);
|
||||
double factorial (double);
|
||||
unsigned nrCombinations (unsigned, unsigned);
|
||||
double getL1Distance (const Params&, const Params&);
|
||||
double getMaxNorm (const Params&, const Params&);
|
||||
unsigned getNumberOfDigits (int);
|
||||
bool isInteger (const string&);
|
||||
string parametersToString (const Params&, unsigned = PRECISION);
|
||||
vector<string> getJointStateStrings (const VarNodes&);
|
||||
double tl (double);
|
||||
double fl (double);
|
||||
double multIdenty();
|
||||
double addIdenty();
|
||||
double withEvidence();
|
||||
double noEvidence();
|
||||
double one();
|
||||
double zero();
|
||||
|
||||
|
||||
template <class T>
|
||||
std::string toString (const T& t)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << t;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
template <typename T>
|
||||
std::ostream& operator << (std::ostream& os, const vector<T>& v)
|
||||
{
|
||||
os << "[" ;
|
||||
for (unsigned i = 0; i < v.size(); i++) {
|
||||
os << ((i != 0) ? ", " : "") << v[i];
|
||||
}
|
||||
os << "]" ;
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
inline void
|
||||
Util::logSum (double& x, double y)
|
||||
{
|
||||
x = log (exp (x) + exp (y)); return;
|
||||
assert (isfinite (x) && isfinite (y));
|
||||
// If one value is much smaller than the other, keep the larger value.
|
||||
if (x < (y - log (1e200))) {
|
||||
x = y;
|
||||
return;
|
||||
}
|
||||
if (y < (x - log (1e200))) {
|
||||
return;
|
||||
}
|
||||
double diff = x - y;
|
||||
assert (isfinite (diff) && isfinite (x) && isfinite (y));
|
||||
if (!isfinite (exp (diff))) { // difference is too large
|
||||
x = x > y ? x : y;
|
||||
} else { // otherwise return the sum.
|
||||
x = y + log (static_cast<double>(1.0) + exp (diff));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline void
|
||||
Util::multiply (Params& v1, const Params& v2)
|
||||
{
|
||||
assert (v1.size() == v2.size());
|
||||
for (unsigned i = 0; i < v1.size(); i++) {
|
||||
v1[i] *= v2[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline void
|
||||
Util::multiply (Params& v1, const Params& v2, unsigned repetitions)
|
||||
{
|
||||
for (unsigned count = 0; count < v1.size(); ) {
|
||||
for (unsigned i = 0; i < v2.size(); i++) {
|
||||
for (unsigned r = 0; r < repetitions; r++) {
|
||||
v1[count] *= v2[i];
|
||||
count ++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline void
|
||||
Util::add (Params& v1, const Params& v2)
|
||||
{
|
||||
assert (v1.size() == v2.size());
|
||||
for (unsigned i = 0; i < v1.size(); i++) {
|
||||
v1[i] += v2[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline void
|
||||
Util::add (Params& v1, const Params& v2, unsigned repetitions)
|
||||
{
|
||||
for (unsigned count = 0; count < v1.size(); ) {
|
||||
for (unsigned i = 0; i < v2.size(); i++) {
|
||||
for (unsigned r = 0; r < repetitions; r++) {
|
||||
v1[count] += v2[i];
|
||||
count ++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline double
|
||||
Util::tl (double v)
|
||||
{
|
||||
return Globals::logDomain ? log(v) : v;
|
||||
}
|
||||
|
||||
inline double
|
||||
Util::fl (double v)
|
||||
{
|
||||
return Globals::logDomain ? exp(v) : v;
|
||||
}
|
||||
|
||||
inline double
|
||||
Util::multIdenty() {
|
||||
return Globals::logDomain ? 0.0 : 1.0;
|
||||
}
|
||||
|
||||
inline double
|
||||
Util::addIdenty()
|
||||
{
|
||||
return Globals::logDomain ? INF : 0.0;
|
||||
}
|
||||
|
||||
inline double
|
||||
Util::withEvidence()
|
||||
{
|
||||
return Globals::logDomain ? 0.0 : 1.0;
|
||||
}
|
||||
|
||||
inline double
|
||||
Util::noEvidence() {
|
||||
return Globals::logDomain ? INF : 0.0;
|
||||
}
|
||||
|
||||
inline double
|
||||
Util::one()
|
||||
{
|
||||
return Globals::logDomain ? 0.0 : 1.0;
|
||||
}
|
||||
|
||||
inline double
|
||||
Util::zero() {
|
||||
return Globals::logDomain ? INF : 0.0 ;
|
||||
}
|
||||
|
||||
|
||||
struct NetInfo
|
||||
{
|
||||
NetInfo (unsigned size, bool loopy, unsigned nIters, double time)
|
||||
{
|
||||
this->size = size;
|
||||
this->loopy = loopy;
|
||||
this->nIters = nIters;
|
||||
this->time = time;
|
||||
}
|
||||
unsigned size;
|
||||
bool loopy;
|
||||
unsigned nIters;
|
||||
double time;
|
||||
};
|
||||
|
||||
|
||||
struct CompressInfo
|
||||
{
|
||||
CompressInfo (unsigned a, unsigned b, unsigned c, unsigned d, unsigned e)
|
||||
{
|
||||
nGroundVars = a;
|
||||
nGroundFactors = b;
|
||||
nClusterVars = c;
|
||||
nClusterFactors = d;
|
||||
nWithoutNeighs = e;
|
||||
}
|
||||
unsigned nGroundVars;
|
||||
unsigned nGroundFactors;
|
||||
unsigned nClusterVars;
|
||||
unsigned nClusterFactors;
|
||||
unsigned nWithoutNeighs;
|
||||
};
|
||||
|
||||
|
||||
class Statistics
|
||||
{
|
||||
public:
|
||||
static unsigned getSolvedNetworksCounting (void);
|
||||
static void incrementPrimaryNetworksCounting (void);
|
||||
static unsigned getPrimaryNetworksCounting (void);
|
||||
static void updateStatistics (unsigned, bool, unsigned, double);
|
||||
static void printStatistics (void);
|
||||
static void writeStatisticsToFile (const char*);
|
||||
static void updateCompressingStatistics (
|
||||
unsigned, unsigned, unsigned, unsigned, unsigned);
|
||||
|
||||
private:
|
||||
static string getStatisticString (void);
|
||||
|
||||
static vector<NetInfo> netInfo_;
|
||||
static vector<CompressInfo> compressInfo_;
|
||||
static unsigned primaryNetCount_;
|
||||
};
|
||||
|
||||
#endif // HORUS_UTIL_H
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "VarElimSolver.h"
|
||||
#include "ElimGraph.h"
|
||||
#include "Factor.h"
|
||||
#include "Util.h"
|
||||
|
||||
|
||||
VarElimSolver::VarElimSolver (const BayesNet& bn) : Solver (&bn)
|
||||
@ -30,23 +31,23 @@ VarElimSolver::~VarElimSolver (void)
|
||||
|
||||
|
||||
|
||||
ParamSet
|
||||
Params
|
||||
VarElimSolver::getPosterioriOf (VarId vid)
|
||||
{
|
||||
assert (factorGraph_->getFgVarNode (vid));
|
||||
FgVarNode* vn = factorGraph_->getFgVarNode (vid);
|
||||
assert (vn);
|
||||
if (vn->hasEvidence()) {
|
||||
ParamSet params (vn->nrStates(), 0.0);
|
||||
Params params (vn->nrStates(), 0.0);
|
||||
params[vn->getEvidence()] = 1.0;
|
||||
return params;
|
||||
}
|
||||
return getJointDistributionOf (VarIdSet() = {vid});
|
||||
return getJointDistributionOf (VarIds() = {vid});
|
||||
}
|
||||
|
||||
|
||||
|
||||
ParamSet
|
||||
VarElimSolver::getJointDistributionOf (const VarIdSet& vids)
|
||||
Params
|
||||
VarElimSolver::getJointDistributionOf (const VarIds& vids)
|
||||
{
|
||||
factorList_.clear();
|
||||
varFactors_.clear();
|
||||
@ -55,10 +56,11 @@ VarElimSolver::getJointDistributionOf (const VarIdSet& vids)
|
||||
introduceEvidence();
|
||||
chooseEliminationOrder (vids);
|
||||
processFactorList (vids);
|
||||
ParamSet params = factorList_.back()->getParameters();
|
||||
factorList_.back()->freeDistribution();
|
||||
Params params = factorList_.back()->getParameters();
|
||||
if (Globals::logDomain) {
|
||||
Util::fromLog (params);
|
||||
}
|
||||
delete factorList_.back();
|
||||
Util::normalize (params);
|
||||
return params;
|
||||
}
|
||||
|
||||
@ -99,7 +101,7 @@ VarElimSolver::introduceEvidence (void)
|
||||
if (factor->nrVariables() == 1) {
|
||||
factorList_[idxs[j]] = 0;
|
||||
} else {
|
||||
factorList_[idxs[j]]->removeInconsistentEntries (
|
||||
factorList_[idxs[j]]->absorveEvidence (
|
||||
varNodes[i]->varId(), varNodes[i]->getEvidence());
|
||||
}
|
||||
}
|
||||
@ -110,10 +112,10 @@ VarElimSolver::introduceEvidence (void)
|
||||
|
||||
|
||||
void
|
||||
VarElimSolver::chooseEliminationOrder (const VarIdSet& vids)
|
||||
VarElimSolver::chooseEliminationOrder (const VarIds& vids)
|
||||
{
|
||||
if (bayesNet_) {
|
||||
ElimGraph graph = ElimGraph (*bayesNet_);
|
||||
ElimGraph graph (*bayesNet_);
|
||||
elimOrder_ = graph.getEliminatingOrder (vids);
|
||||
} else {
|
||||
const FgVarSet& varNodes = factorGraph_->getVarNodes();
|
||||
@ -130,33 +132,31 @@ VarElimSolver::chooseEliminationOrder (const VarIdSet& vids)
|
||||
|
||||
|
||||
void
|
||||
VarElimSolver::processFactorList (const VarIdSet& vids)
|
||||
VarElimSolver::processFactorList (const VarIds& vids)
|
||||
{
|
||||
for (unsigned i = 0; i < elimOrder_.size(); i++) {
|
||||
// cout << "-----------------------------------------" << endl;
|
||||
// cout << "Eliminating " << elimOrder_[i];
|
||||
// cout << " in the following factors:" << endl;
|
||||
// printActiveFactors();
|
||||
eliminate (elimOrder_[i]);
|
||||
}
|
||||
Factor* thisIsTheEnd = new Factor();
|
||||
|
||||
Factor* finalFactor = new Factor();
|
||||
for (unsigned i = 0; i < factorList_.size(); i++) {
|
||||
if (factorList_[i]) {
|
||||
thisIsTheEnd->multiplyByFactor (*factorList_[i]);
|
||||
factorList_[i]->freeDistribution();
|
||||
finalFactor->multiply (*factorList_[i]);
|
||||
delete factorList_[i];
|
||||
factorList_[i] = 0;
|
||||
}
|
||||
}
|
||||
VarIdSet vidsWithoutEvidence;
|
||||
|
||||
VarIds unobservedVids;
|
||||
for (unsigned i = 0; i < vids.size(); i++) {
|
||||
if (factorGraph_->getFgVarNode (vids[i])->hasEvidence() == false) {
|
||||
vidsWithoutEvidence.push_back (vids[i]);
|
||||
unobservedVids.push_back (vids[i]);
|
||||
}
|
||||
}
|
||||
thisIsTheEnd->orderVariables (vidsWithoutEvidence);
|
||||
factorList_.push_back (thisIsTheEnd);
|
||||
|
||||
finalFactor->reorderVariables (unobservedVids);
|
||||
finalFactor->normalize();
|
||||
factorList_.push_back (finalFactor);
|
||||
}
|
||||
|
||||
|
||||
@ -164,30 +164,25 @@ VarElimSolver::processFactorList (const VarIdSet& vids)
|
||||
void
|
||||
VarElimSolver::eliminate (VarId elimVar)
|
||||
{
|
||||
FgVarNode* vn = factorGraph_->getFgVarNode (elimVar);
|
||||
Factor* result = 0;
|
||||
FgVarNode* vn = factorGraph_->getFgVarNode (elimVar);
|
||||
vector<unsigned>& idxs = varFactors_.find (elimVar)->second;
|
||||
//cout << "eliminating " << setw (5) << elimVar << ":" ;
|
||||
for (unsigned i = 0; i < idxs.size(); i++) {
|
||||
unsigned idx = idxs[i];
|
||||
if (factorList_[idx]) {
|
||||
if (result == 0) {
|
||||
result = new Factor(*factorList_[idx]);
|
||||
//cout << " " << factorList_[idx]->label();
|
||||
} else {
|
||||
result->multiplyByFactor (*factorList_[idx]);
|
||||
//cout << " x " << factorList_[idx]->label();
|
||||
result->multiply (*factorList_[idx]);
|
||||
}
|
||||
factorList_[idx]->freeDistribution();
|
||||
delete factorList_[idx];
|
||||
factorList_[idx] = 0;
|
||||
}
|
||||
}
|
||||
if (result != 0 && result->nrVariables() != 1) {
|
||||
result->removeVariable (vn->varId());
|
||||
result->sumOut (vn->varId());
|
||||
factorList_.push_back (result);
|
||||
// cout << endl <<" factor size=" << result->size() << endl;
|
||||
const VarIdSet& resultVarIds = result->getVarIds();
|
||||
const VarIds& resultVarIds = result->getVarIds();
|
||||
for (unsigned i = 0; i < resultVarIds.size(); i++) {
|
||||
vector<unsigned>& idxs =
|
||||
varFactors_.find (resultVarIds[i])->second;
|
||||
@ -203,7 +198,7 @@ VarElimSolver::printActiveFactors (void)
|
||||
{
|
||||
for (unsigned i = 0; i < factorList_.size(); i++) {
|
||||
if (factorList_[i] != 0) {
|
||||
factorList_[i]->printFactor();
|
||||
factorList_[i]->print();
|
||||
cout << endl;
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,7 @@
|
||||
#include "Solver.h"
|
||||
#include "FactorGraph.h"
|
||||
#include "BayesNet.h"
|
||||
#include "Shared.h"
|
||||
#include "Horus.h"
|
||||
|
||||
|
||||
using namespace std;
|
||||
@ -18,22 +18,22 @@ class VarElimSolver : public Solver
|
||||
VarElimSolver (const BayesNet&);
|
||||
VarElimSolver (const FactorGraph&);
|
||||
~VarElimSolver (void);
|
||||
void runSolver (void) { }
|
||||
ParamSet getPosterioriOf (VarId);
|
||||
ParamSet getJointDistributionOf (const VarIdSet&);
|
||||
void runSolver (void) { }
|
||||
Params getPosterioriOf (VarId);
|
||||
Params getJointDistributionOf (const VarIds&);
|
||||
|
||||
private:
|
||||
void createFactorList (void);
|
||||
void introduceEvidence (void);
|
||||
void chooseEliminationOrder (const VarIdSet&);
|
||||
void processFactorList (const VarIdSet&);
|
||||
void chooseEliminationOrder (const VarIds&);
|
||||
void processFactorList (const VarIds&);
|
||||
void eliminate (VarId);
|
||||
void printActiveFactors (void);
|
||||
|
||||
const BayesNet* bayesNet_;
|
||||
const FactorGraph* factorGraph_;
|
||||
vector<Factor*> factorList_;
|
||||
VarIdSet elimOrder_;
|
||||
const BayesNet* bayesNet_;
|
||||
const FactorGraph* factorGraph_;
|
||||
vector<Factor*> factorList_;
|
||||
VarIds elimOrder_;
|
||||
unordered_map<VarId, vector<unsigned>> varFactors_;
|
||||
};
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
#ifndef HORUS_VARNODE_H
|
||||
#define HORUS_VARNODE_H
|
||||
|
||||
#include "Shared.h"
|
||||
#include "Horus.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -30,12 +30,14 @@ class VarNode
|
||||
|
||||
bool operator== (const VarNode& var) const
|
||||
{
|
||||
cout << "equal operator called" << endl;
|
||||
assert (!(varId_ == var.varId() && nrStates_ != var.nrStates()));
|
||||
return varId_ == var.varId();
|
||||
}
|
||||
|
||||
bool operator!= (const VarNode& var) const
|
||||
{
|
||||
cout << "diff operator called" << endl;
|
||||
assert (!(varId_ == var.varId() && nrStates_ != var.nrStates()));
|
||||
return varId_ != var.varId();
|
||||
}
|
||||
|
@ -1,34 +0,0 @@
|
||||
|
||||
:- use_module(library(clpbn)).
|
||||
|
||||
:- set_clpbn_flag(solver, bp).
|
||||
|
||||
%
|
||||
% R
|
||||
% / | \
|
||||
% / | \
|
||||
% A B C
|
||||
%
|
||||
|
||||
|
||||
r(R) :-
|
||||
{ R = r with p([t, f], [0.35, 0.65]) }.
|
||||
|
||||
a(A) :-
|
||||
r(R),
|
||||
child_dist(R,Dist),
|
||||
{ A = a with Dist }.
|
||||
|
||||
b(B) :-
|
||||
r(R),
|
||||
child_dist(R,Dist),
|
||||
{ B = b with Dist }.
|
||||
|
||||
c(C) :-
|
||||
r(R),
|
||||
child_dist(R,Dist),
|
||||
{ C = c with Dist }.
|
||||
|
||||
|
||||
child_dist(R, p([t, f], [0.3, 0.4, 0.25, 0.05], [R])).
|
||||
|
@ -1,76 +0,0 @@
|
||||
<?xml version="1.0" encoding="US-ASCII"?>
|
||||
|
||||
<BIF VERSION="0.3">
|
||||
<NETWORK>
|
||||
<NAME>Bayes-Ball: The Rational Pastime Network, Figure 4, a)</NAME>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>1</NAME>
|
||||
<OUTCOME></OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>2</NAME>
|
||||
<OUTCOME></OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>3</NAME>
|
||||
<OUTCOME></OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>4</NAME>
|
||||
<OUTCOME></OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>5</NAME>
|
||||
<OUTCOME></OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>6</NAME>
|
||||
<OUTCOME></OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>1</FOR>
|
||||
<TABLE>1</TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>2</FOR>
|
||||
<GIVEN>1</GIVEN>
|
||||
<GIVEN>3</GIVEN>
|
||||
<TABLE>1</TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>3</FOR>
|
||||
<TABLE>1</TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>4</FOR>
|
||||
<GIVEN>1</GIVEN>
|
||||
<GIVEN>5</GIVEN>
|
||||
<TABLE>1</TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>5</FOR>
|
||||
<GIVEN>2</GIVEN>
|
||||
<GIVEN>6</GIVEN>
|
||||
<TABLE>1</TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>6</FOR>
|
||||
<GIVEN>3</GIVEN>
|
||||
<TABLE>1</TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
</NETWORK>
|
||||
</BIF>
|
||||
|
@ -1,74 +0,0 @@
|
||||
<?xml version="1.0" encoding="US-ASCII"?>
|
||||
|
||||
<BIF VERSION="0.3">
|
||||
<NETWORK>
|
||||
<NAME>Bayes-Ball: The Rational Pastime Network, Figure 4, c)</NAME>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>1</NAME>
|
||||
<OUTCOME></OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>2</NAME>
|
||||
<OUTCOME></OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>3</NAME>
|
||||
<OUTCOME></OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>4</NAME>
|
||||
<OUTCOME></OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>5</NAME>
|
||||
<OUTCOME></OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>6</NAME>
|
||||
<OUTCOME></OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>1</FOR>
|
||||
<TABLE>1</TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>2</FOR>
|
||||
<GIVEN>1</GIVEN>
|
||||
<GIVEN>3</GIVEN>
|
||||
<TABLE>1</TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>3</FOR>
|
||||
<TABLE>1</TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>4</FOR>
|
||||
<GIVEN>5</GIVEN>
|
||||
<TABLE>1</TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>5</FOR>
|
||||
<GIVEN>2</GIVEN>
|
||||
<GIVEN>6</GIVEN>
|
||||
<TABLE>1</TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>6</FOR>
|
||||
<TABLE>1</TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
</NETWORK>
|
||||
</BIF>
|
||||
|
@ -1,53 +0,0 @@
|
||||
<?xml version="1.0" encoding="US-ASCII"?>
|
||||
|
||||
<!--
|
||||
|
||||
A B
|
||||
\ /
|
||||
\ /
|
||||
C
|
||||
|
||||
-->
|
||||
|
||||
<BIF VERSION="0.3">
|
||||
<NETWORK>
|
||||
<NAME>Neapolitan</NAME>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>A</NAME>
|
||||
<OUTCOME>a1</OUTCOME>
|
||||
<OUTCOME>a2</OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>B</NAME>
|
||||
<OUTCOME>b1</OUTCOME>
|
||||
<OUTCOME>b2</OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>C</NAME>
|
||||
<OUTCOME>c1</OUTCOME>
|
||||
<OUTCOME>c2</OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>A</FOR>
|
||||
<TABLE> .695 .305 </TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>B</FOR>
|
||||
<TABLE> .25 .75 </TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>C</FOR>
|
||||
<GIVEN>A</GIVEN>
|
||||
<GIVEN>B</GIVEN>
|
||||
<TABLE> .2 .8 .45 .55 .32 .68 .7 .3 </TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
</NETWORK>
|
||||
</BIF>
|
||||
|
47
packages/CLPBN/clpbn/bp/examples/burglary-alarm.fg
Normal file
47
packages/CLPBN/clpbn/bp/examples/burglary-alarm.fg
Normal file
@ -0,0 +1,47 @@
|
||||
5
|
||||
|
||||
1
|
||||
0
|
||||
2
|
||||
2
|
||||
0 0.001
|
||||
1 0.999
|
||||
|
||||
1
|
||||
1
|
||||
2
|
||||
2
|
||||
0 0.002
|
||||
1 0.998
|
||||
|
||||
3
|
||||
1 0 2
|
||||
2 2 2
|
||||
8
|
||||
0 0.95
|
||||
1 0.94
|
||||
2 0.29
|
||||
3 0.001
|
||||
4 0.05
|
||||
5 0.06
|
||||
6 0.71
|
||||
7 0.999
|
||||
|
||||
2
|
||||
2 3
|
||||
2 2
|
||||
4
|
||||
0 0.9
|
||||
1 0.05
|
||||
2 0.1
|
||||
3 0.95
|
||||
|
||||
2
|
||||
2 4
|
||||
2 2
|
||||
4
|
||||
0 0.7
|
||||
1 0.01
|
||||
2 0.3
|
||||
3 0.99
|
||||
|
@ -1,58 +0,0 @@
|
||||
<?xml version="1.0" encoding="US-ASCII"?>
|
||||
|
||||
<!--
|
||||
|
||||
A
|
||||
|
|
||||
|
|
||||
-
|
||||
B
|
||||
|
|
||||
|
|
||||
-
|
||||
C
|
||||
|
||||
-->
|
||||
|
||||
<BIF VERSION="0.3">
|
||||
<NETWORK>
|
||||
<NAME>Simple Chain</NAME>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>A</NAME>
|
||||
<OUTCOME>a1</OUTCOME>
|
||||
<OUTCOME>a2</OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>B</NAME>
|
||||
<OUTCOME>b1</OUTCOME>
|
||||
<OUTCOME>b2</OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>C</NAME>
|
||||
<OUTCOME>c1</OUTCOME>
|
||||
<OUTCOME>c2</OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>A</FOR>
|
||||
<TABLE>0.3 0.7</TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>B</FOR>
|
||||
<GIVEN>A</GIVEN>
|
||||
<TABLE>0.4 0.6 0.2 0.8</TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>C</FOR>
|
||||
<GIVEN>B</GIVEN>
|
||||
<TABLE>0.9 0.1 0.25 0.75</TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
</NETWORK>
|
||||
</BIF>
|
||||
|
78022
packages/CLPBN/clpbn/bp/examples/city1000.fg
Normal file
78022
packages/CLPBN/clpbn/bp/examples/city1000.fg
Normal file
File diff suppressed because it is too large
Load Diff
780022
packages/CLPBN/clpbn/bp/examples/city10000.fg
Normal file
780022
packages/CLPBN/clpbn/bp/examples/city10000.fg
Normal file
File diff suppressed because it is too large
Load Diff
390022
packages/CLPBN/clpbn/bp/examples/city5000.fg
Normal file
390022
packages/CLPBN/clpbn/bp/examples/city5000.fg
Normal file
File diff suppressed because it is too large
Load Diff
18
packages/CLPBN/clpbn/bp/examples/competing_workshops.yap
Normal file
18
packages/CLPBN/clpbn/bp/examples/competing_workshops.yap
Normal file
@ -0,0 +1,18 @@
|
||||
|
||||
:- use_module(library(pfl)).
|
||||
|
||||
%:- set_clpbn_flag(solver,ve).
|
||||
%:- set_clpbn_flag(solver,bp), clpbn_bp:set_horus_flag(inf_alg,ve).
|
||||
:- set_clpbn_flag(solver,fove).
|
||||
|
||||
c(x1,y1).
|
||||
%c(x1,y1).
|
||||
%c(x2,y2).
|
||||
|
||||
bayes hot(Y)::[t,f] ; [0.2, 0.4] ; [c(_,Y)].
|
||||
|
||||
bayes attends(X)::[t,f] , hot(Y) ; [0.1, 0.2, 0.3, 0.4] ; [c(X,Y)].
|
||||
|
||||
bayes series::[t,f] , attends(X) ; [0.5, 0.6, 0.7, 0.8] ; [c(X,_)].
|
||||
|
||||
|
@ -1,54 +0,0 @@
|
||||
<?xml version="1.0" encoding="US-ASCII"?>
|
||||
|
||||
<!--
|
||||
|
||||
A B
|
||||
\ /
|
||||
\ /
|
||||
-
|
||||
C
|
||||
|
||||
-->
|
||||
|
||||
<BIF VERSION="0.3">
|
||||
<NETWORK>
|
||||
<NAME>Simple Convergence</NAME>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>A</NAME>
|
||||
<OUTCOME>a1</OUTCOME>
|
||||
<OUTCOME>a2</OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>B</NAME>
|
||||
<OUTCOME>b1</OUTCOME>
|
||||
<OUTCOME>b2</OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>C</NAME>
|
||||
<OUTCOME>c1</OUTCOME>
|
||||
<OUTCOME>c2</OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>A</FOR>
|
||||
<TABLE>.695 .305</TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>B</FOR>
|
||||
<TABLE>0.25 0.75</TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>C</FOR>
|
||||
<GIVEN>A</GIVEN>
|
||||
<GIVEN>B</GIVEN>
|
||||
<TABLE>0.2 0.8 0.45 0.55 0.32 0.68 0.7 0.3</TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
</NETWORK>
|
||||
</BIF>
|
||||
|
@ -1,51 +0,0 @@
|
||||
<?xml version="1.0" encoding="US-ASCII"?>
|
||||
|
||||
<!--
|
||||
|
||||
A
|
||||
/ \
|
||||
/ \
|
||||
- -
|
||||
B C
|
||||
|
||||
-->
|
||||
|
||||
<BIF VERSION="0.3">
|
||||
<NETWORK>
|
||||
<NAME>Simple Divergence</NAME>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>A</NAME>
|
||||
<OUTCOME></OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>B</NAME>
|
||||
<OUTCOME></OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>C</NAME>
|
||||
<OUTCOME></OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>A</FOR>
|
||||
<TABLE>1</TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>B</FOR>
|
||||
<GIVEN>A</GIVEN>
|
||||
<TABLE>1</TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>C</FOR>
|
||||
<GIVEN>A</GIVEN>
|
||||
<TABLE>1</TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
</NETWORK>
|
||||
</BIF>
|
||||
|
50
packages/CLPBN/clpbn/bp/examples/fail1.yap
Normal file
50
packages/CLPBN/clpbn/bp/examples/fail1.yap
Normal file
@ -0,0 +1,50 @@
|
||||
|
||||
:- use_module(library(pfl)).
|
||||
|
||||
:- set_clpbn_flag(solver,fove).
|
||||
|
||||
|
||||
c(x1,y1,z1).
|
||||
c(x1,y1,z2).
|
||||
c(x1,y1,z3).
|
||||
c(x1,y1,z4).
|
||||
c(x1,y1,z5).
|
||||
c(x1,y1,z6).
|
||||
c(x1,y1,z7).
|
||||
|
||||
c(x1,y2,z1).
|
||||
c(x1,y2,z2).
|
||||
c(x1,y2,z3).
|
||||
c(x1,y2,z4).
|
||||
c(x1,y2,z5).
|
||||
c(x1,y2,z6).
|
||||
c(x1,y2,z7).
|
||||
|
||||
c(x2,y1,z1).
|
||||
c(x2,y1,z2).
|
||||
c(x2,y1,z3).
|
||||
c(x2,y1,z4).
|
||||
c(x2,y1,z5).
|
||||
c(x2,y1,z6).
|
||||
c(x2,y1,z7).
|
||||
|
||||
c(x2,y2,z1).
|
||||
c(x2,y2,z2).
|
||||
c(x2,y2,z3).
|
||||
c(x2,y2,z4).
|
||||
c(x2,y2,z5).
|
||||
c(x2,y2,z6).
|
||||
c(x2,y2,z7).
|
||||
|
||||
|
||||
bayes p(X,Y,Z)::[t,f] , q(Y), s(Z) ; cpt ; [c(X,Y,Z)].
|
||||
|
||||
bayes q(Y)::[t,f] ; [0.50, 0.40] ; [c(_,Y,_)].
|
||||
|
||||
bayes s(Z)::[t,f] ; [0.33, 0.46] ; [c(_,_,Z)].
|
||||
|
||||
cpt([0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8]).
|
||||
|
||||
|
||||
?- p(x1,y1,z1,X), s(z1,t), s(z3,f).
|
||||
|
15
packages/CLPBN/clpbn/bp/examples/fail2.yap
Normal file
15
packages/CLPBN/clpbn/bp/examples/fail2.yap
Normal file
@ -0,0 +1,15 @@
|
||||
|
||||
:- use_module(library(pfl)).
|
||||
|
||||
:- set_clpbn_flag(solver,fove).
|
||||
|
||||
|
||||
t(ann).
|
||||
t(dave).
|
||||
|
||||
bayes p(X)::[t,f] ; [0.1, 0.3] ; [t(X)].
|
||||
|
||||
|
||||
?- p(ann,X), p(ann,f).
|
||||
|
||||
|
18
packages/CLPBN/clpbn/bp/examples/fail3.yap
Normal file
18
packages/CLPBN/clpbn/bp/examples/fail3.yap
Normal file
@ -0,0 +1,18 @@
|
||||
|
||||
:- use_module(library(pfl)).
|
||||
|
||||
:- set_clpbn_flag(solver,fove).
|
||||
|
||||
|
||||
t(ann).
|
||||
t(dave).
|
||||
|
||||
bayes p(X)::[t,f] ; [0.1, 0.3] ; [t(X)].
|
||||
|
||||
|
||||
p(ann,t).
|
||||
|
||||
|
||||
?- p(dave,X).
|
||||
|
||||
|
@ -1,106 +0,0 @@
|
||||
<?XML VERSION="1.0"?>
|
||||
|
||||
|
||||
<!--
|
||||
Bayesian network in BIF (BayesNet Interchange Format)
|
||||
Produced by JavaBayes (http://www.cs.cmu.edu/~javabayes/
|
||||
Output created Fri Nov 14 13:14:15 GMT+00:00 1997
|
||||
-->
|
||||
|
||||
|
||||
|
||||
<!-- DTD for the BIF format -->
|
||||
<!DOCTYPE BIF [
|
||||
<!ELEMENT PROPERTY (#PCDATA)>
|
||||
<!ELEMENT TYPE (#PCDATA)>
|
||||
<!ELEMENT VALUE (#PCDATA)>
|
||||
<!ELEMENT NAME (#PCDATA)>
|
||||
<!ELEMENT NETWORK
|
||||
( NAME, ( PROPERTY | VARIABLE | PROBABILITY )* )>
|
||||
<!ELEMENT VARIABLE ( NAME, TYPE, ( VALUE | PROPERTY )* ) >
|
||||
<!ELEMENT PROBABILITY
|
||||
( FOR | GIVEN | TABLE | ENTRY | DEFAULT | PROPERTY )* >
|
||||
<!ELEMENT TABLE (#PCDATA)>
|
||||
<!ELEMENT DEFAULT (TABLE)>
|
||||
<!ELEMENT ENTRY ( VALUE* , TABLE )>
|
||||
]>
|
||||
|
||||
|
||||
<BIF>
|
||||
<NETWORK>
|
||||
<NAME>John-Mary-Call</NAME>
|
||||
|
||||
<!-- Variables -->
|
||||
<VARIABLE>
|
||||
<NAME>Burglary</NAME>
|
||||
<TYPE>discrete</TYPE>
|
||||
<VALUE>False</VALUE>
|
||||
<VALUE>True</VALUE>
|
||||
<PROPERTY>position = (145, 114)</PROPERTY>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE>
|
||||
<NAME>Earthquake</NAME>
|
||||
<TYPE>discrete</TYPE>
|
||||
<VALUE>False</VALUE>
|
||||
<VALUE>True</VALUE>
|
||||
<PROPERTY>position = (351, 110)</PROPERTY>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE>
|
||||
<NAME>Alarm</NAME>
|
||||
<TYPE>discrete</TYPE>
|
||||
<VALUE>False</VALUE>
|
||||
<VALUE>True</VALUE>
|
||||
<PROPERTY>position = (253, 224)</PROPERTY>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE>
|
||||
<NAME>JohnCalls</NAME>
|
||||
<TYPE>discrete</TYPE>
|
||||
<VALUE>False</VALUE>
|
||||
<VALUE>True</VALUE>
|
||||
<PROPERTY>position = (156, 343)</PROPERTY>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE>
|
||||
<NAME>MaryCalls</NAME>
|
||||
<TYPE>discrete</TYPE>
|
||||
<VALUE>False</VALUE>
|
||||
<VALUE>True</VALUE>
|
||||
<PROPERTY>position = (344, 341)</PROPERTY>
|
||||
</VARIABLE>
|
||||
|
||||
|
||||
<!-- Probability distributions -->
|
||||
<PROBABILITY>
|
||||
<FOR>Burglary</FOR>
|
||||
<TABLE>0.999 0.0010 </TABLE>
|
||||
</PROBABILITY>
|
||||
|
||||
<PROBABILITY>
|
||||
<FOR>Earthquake</FOR>
|
||||
<TABLE>0.998 0.0020 </TABLE>
|
||||
</PROBABILITY>
|
||||
|
||||
<PROBABILITY>
|
||||
<FOR>Alarm</FOR>
|
||||
<GIVEN>Burglary</GIVEN>
|
||||
<GIVEN>Earthquake</GIVEN>
|
||||
<TABLE>0.999 0.71 0.06 0.05 0.0010 0.29 0.94 0.95 </TABLE>
|
||||
</PROBABILITY>
|
||||
|
||||
<PROBABILITY>
|
||||
<FOR>JohnCalls</FOR>
|
||||
<GIVEN>Alarm</GIVEN>
|
||||
<TABLE>0.95 0.1 0.05 0.9 </TABLE>
|
||||
</PROBABILITY>
|
||||
|
||||
<PROBABILITY>
|
||||
<FOR>MaryCalls</FOR>
|
||||
<GIVEN>Alarm</GIVEN>
|
||||
<TABLE>0.99 0.3 0.01 0.7 </TABLE>
|
||||
</PROBABILITY>
|
||||
|
||||
|
||||
</BIF>
|
@ -1,67 +0,0 @@
|
||||
<?xml version="1.0" encoding="US-ASCII"?>
|
||||
|
||||
<!--
|
||||
|
||||
P1 P2 P3
|
||||
\ | /
|
||||
\ | /
|
||||
-
|
||||
C
|
||||
|
||||
-->
|
||||
|
||||
<BIF VERSION="0.3">
|
||||
<NETWORK>
|
||||
|
||||
<NAME>Simple Convergence</NAME>
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>P1</NAME>
|
||||
<OUTCOME>p1</OUTCOME>
|
||||
<OUTCOME>p2</OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>P2</NAME>
|
||||
<OUTCOME>p1</OUTCOME>
|
||||
<OUTCOME>p2</OUTCOME>
|
||||
<OUTCOME>p3</OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>P3</NAME>
|
||||
<OUTCOME>p1</OUTCOME>
|
||||
<OUTCOME>p2</OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>C</NAME>
|
||||
<OUTCOME>c1</OUTCOME>
|
||||
<OUTCOME>c2</OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>P1</FOR>
|
||||
<TABLE>.695 .305</TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>P2</FOR>
|
||||
<TABLE>0.2 0.3 0.5</TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>P3</FOR>
|
||||
<TABLE>0.25 0.75</TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>C</FOR>
|
||||
<GIVEN>P1</GIVEN>
|
||||
<GIVEN>P2</GIVEN>
|
||||
<GIVEN>P3</GIVEN>
|
||||
<TABLE>0.2 0.8 0.45 0.55 0.32 0.68 0.7 0.3 0.3 0.7 0.55 0.45 0.22 0.78 0.25 0.75 0.11 0.89 0.34 0.66 0.1 0.9 0.6 0.4</TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
</NETWORK>
|
||||
</BIF>
|
||||
|
@ -1,81 +0,0 @@
|
||||
<?xml version="1.0" encoding="US-ASCII"?>
|
||||
|
||||
<!--
|
||||
|
||||
A E
|
||||
/ \ /
|
||||
/ \ /
|
||||
B C
|
||||
\ /
|
||||
\ /
|
||||
D
|
||||
|
||||
-->
|
||||
|
||||
<BIF VERSION="0.3">
|
||||
<NETWORK>
|
||||
<NAME>Loop</NAME>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>A</NAME>
|
||||
<OUTCOME>a1</OUTCOME>
|
||||
<OUTCOME>a2</OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>B</NAME>
|
||||
<OUTCOME>b1</OUTCOME>
|
||||
<OUTCOME>b2</OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>C</NAME>
|
||||
<OUTCOME>c1</OUTCOME>
|
||||
<OUTCOME>c2</OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>D</NAME>
|
||||
<OUTCOME>d1</OUTCOME>
|
||||
<OUTCOME>d2</OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>E</NAME>
|
||||
<OUTCOME>e1</OUTCOME>
|
||||
<OUTCOME>e2</OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>A</FOR>
|
||||
<TABLE> .01 .09 </TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>B</FOR>
|
||||
<GIVEN>A</GIVEN>
|
||||
<TABLE> .03 .97 .6 .4 </TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>C</FOR>
|
||||
<GIVEN>A</GIVEN>
|
||||
<GIVEN>E</GIVEN>
|
||||
<TABLE> .24 .76 .12 .88 .2 .4. 5. .6 </TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>D</FOR>
|
||||
<GIVEN>B</GIVEN>
|
||||
<GIVEN>C</GIVEN>
|
||||
<TABLE> .2 .8 .7 .3 .45 .55 .22 .78 </TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>E</FOR>
|
||||
<TABLE> .5 .6</TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
</NETWORK>
|
||||
</BIF>
|
||||
|
@ -1,55 +0,0 @@
|
||||
|
||||
:- use_module(library(clpbn)).
|
||||
|
||||
:- set_clpbn_flag(solver, bp).
|
||||
|
||||
%
|
||||
% B F
|
||||
% \ /
|
||||
% \ /
|
||||
% A
|
||||
%
|
||||
|
||||
b(B) :-
|
||||
b_table(BDist),
|
||||
{ B = b with p([b1, b2], BDist) }.
|
||||
|
||||
f(F) :-
|
||||
f_table(FDist),
|
||||
{ F = f with p([f1, f2], FDist) }.
|
||||
|
||||
a(A) :-
|
||||
b(B),
|
||||
f(F),
|
||||
a_table(ADist),
|
||||
{ A = a with p([a1, a2], ADist, [B, F]) }.
|
||||
|
||||
d(D) :-
|
||||
a(A),
|
||||
f(F),
|
||||
d_table(DDist),
|
||||
{ D = d with p([d1, d2, d3, d4], DDist, [A, F]) }.
|
||||
|
||||
|
||||
b_table([0.005, 0.995]).
|
||||
|
||||
f_table([0.03, 0.97]).
|
||||
|
||||
a_table([0.992, 0.99, 0.2, 0.003,
|
||||
0.008, 0.01, 0.8, 0.997]).
|
||||
|
||||
d_table([1.0, 0.0, 0.0, 0.0,
|
||||
0.0, 1.0, 0.0, 0.0,
|
||||
0.0, 0.0, 1.0, 0.0,
|
||||
0.0, 0.0, 0.0, 1.0]).
|
||||
|
||||
%d_table([0.997, 0.001, 0.001, 0.001,
|
||||
% 0.001, 0.997, 0.001, 0.001,
|
||||
% 0.001, 0.001, 0.997, 0.001,
|
||||
% 0.001, 0.001, 0.001, 0.997]).
|
||||
|
||||
%d_table([0.15, 0.1, 0.7, 0.5,
|
||||
% 0.25, 0.3, 0.2, 0.25,
|
||||
% 0.3, 0.15, 0.35, 0.2,
|
||||
% 0.3, 0.4, 0.2, 0.1]).
|
||||
|
@ -1,17 +0,0 @@
|
||||
MARKOV
|
||||
3
|
||||
2 2 2
|
||||
3
|
||||
1 0
|
||||
1 1
|
||||
3 2 0 1
|
||||
|
||||
2
|
||||
0.005 0.995
|
||||
|
||||
2
|
||||
0.03 0.97
|
||||
|
||||
8
|
||||
0.992 0.99 0.2 0.003
|
||||
0.008 0.01 0.8 0.997
|
@ -1,53 +0,0 @@
|
||||
<?xml version="1.0" encoding="US-ASCII"?>
|
||||
|
||||
<!--
|
||||
|
||||
B F
|
||||
\ /
|
||||
\ /
|
||||
A
|
||||
|
||||
-->
|
||||
|
||||
<BIF VERSION="0.3">
|
||||
<NETWORK>
|
||||
<NAME>Neapolitan</NAME>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>B</NAME>
|
||||
<OUTCOME>b1</OUTCOME>
|
||||
<OUTCOME>b2</OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>F</NAME>
|
||||
<OUTCOME>f1</OUTCOME>
|
||||
<OUTCOME>f2</OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>A</NAME>
|
||||
<OUTCOME>a1</OUTCOME>
|
||||
<OUTCOME>a2</OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>B</FOR>
|
||||
<TABLE> .005 .995 </TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>F</FOR>
|
||||
<TABLE> .03 .97 </TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>A</FOR>
|
||||
<GIVEN>B</GIVEN>
|
||||
<GIVEN>F</GIVEN>
|
||||
<TABLE> .992 .008 .99 .01 .2 .8 .003 .997 </TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
</NETWORK>
|
||||
</BIF>
|
||||
|
@ -1,36 +0,0 @@
|
||||
|
||||
:- use_module(library(clpbn)).
|
||||
|
||||
:- set_clpbn_flag(solver, bp).
|
||||
%:- set_clpbn_flag(solver, jt).
|
||||
|
||||
%
|
||||
% B F
|
||||
% \ /
|
||||
% \ /
|
||||
% A
|
||||
%
|
||||
|
||||
|
||||
b(B) :-
|
||||
b_table(BDist),
|
||||
{ B = b with p([b1, b2], BDist) }.
|
||||
|
||||
f(F) :-
|
||||
f_table(FDist),
|
||||
{ F = f with p([f1, f2], FDist) }.
|
||||
|
||||
a(A) :-
|
||||
b(B),
|
||||
f(F),
|
||||
a_table(ADist),
|
||||
{ A = a with p([a1, a2], ADist, [B, F]) }.
|
||||
|
||||
|
||||
b_table([0.005, 0.995]).
|
||||
|
||||
f_table([0.03, 0.97]).
|
||||
|
||||
a_table([0.992, 0.99, 0.2, 0.003,
|
||||
0.008, 0.01, 0.8, 0.997]).
|
||||
|
@ -1,128 +0,0 @@
|
||||
<?xml version="1.0" encoding="US-ASCII"?>
|
||||
|
||||
<!--
|
||||
|
||||
A B C
|
||||
\ | /
|
||||
\ | /
|
||||
D
|
||||
/ | \
|
||||
/ | \
|
||||
E F G
|
||||
|
||||
-->
|
||||
|
||||
<BIF VERSION="0.3">
|
||||
<NETWORK>
|
||||
<NAME>Node with several parents and childs</NAME>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>A</NAME>
|
||||
<OUTCOME>a1</OUTCOME>
|
||||
<OUTCOME>a2</OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>B</NAME>
|
||||
<OUTCOME>b1</OUTCOME>
|
||||
<OUTCOME>b2</OUTCOME>
|
||||
<OUTCOME>b3</OUTCOME>
|
||||
<OUTCOME>b4</OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>C</NAME>
|
||||
<OUTCOME>c1</OUTCOME>
|
||||
<OUTCOME>c2</OUTCOME>
|
||||
<OUTCOME>c3</OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>D</NAME>
|
||||
<OUTCOME>d1</OUTCOME>
|
||||
<OUTCOME>d2</OUTCOME>
|
||||
<OUTCOME>d3</OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>E</NAME>
|
||||
<OUTCOME>e1</OUTCOME>
|
||||
<OUTCOME>e2</OUTCOME>
|
||||
<OUTCOME>e3</OUTCOME>
|
||||
<OUTCOME>e4</OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>F</NAME>
|
||||
<OUTCOME>f1</OUTCOME>
|
||||
<OUTCOME>f2</OUTCOME>
|
||||
<OUTCOME>f3</OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>G</NAME>
|
||||
<OUTCOME>g1</OUTCOME>
|
||||
<OUTCOME>g2</OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>A</FOR>
|
||||
<TABLE> .1 .2 </TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>B</FOR>
|
||||
<TABLE> .01 .02 .03 .04 </TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>C</FOR>
|
||||
<TABLE> .11 .22 .33 </TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>D</FOR>
|
||||
<GIVEN>A</GIVEN>
|
||||
<GIVEN>B</GIVEN>
|
||||
<GIVEN>C</GIVEN>
|
||||
<TABLE>
|
||||
.522 .008 .99 .01 .2 .8 .003 .457 .423 .007 .92 .04 .5 .232 .033 .227 .112 .048 .91 .21 .24 .18 .005 .227
|
||||
.212 .04 .59 .21 .6 .1 .023 .215 .913 .017 .96 .01 .55 .422 .013 .417 .272 .068 .61 .11 .26 .28 .205 .322
|
||||
.142 .028 .19 .11 .5 .67 .013 .437 .163 .067 .12 .06 .1 .262 .063 .167 .512 .028 .11 .41 .14 .68 .015 .92
|
||||
</TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>E</FOR>
|
||||
<GIVEN>D</GIVEN>
|
||||
<TABLE>
|
||||
.111 .11 .1
|
||||
.222 .22 .2
|
||||
.333 .33 .3
|
||||
.444 .44 .4
|
||||
</TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>F</FOR>
|
||||
<GIVEN>D</GIVEN>
|
||||
<TABLE>
|
||||
.112 .111 .110
|
||||
.223 .222 .221
|
||||
.334 .333 .332
|
||||
</TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>G</FOR>
|
||||
<GIVEN>D</GIVEN>
|
||||
<TABLE>
|
||||
.101 .102 .103
|
||||
.201 .202 .203
|
||||
</TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
</NETWORK>
|
||||
</BIF>
|
||||
|
120
packages/CLPBN/clpbn/bp/examples/smokers_2.fg
Normal file
120
packages/CLPBN/clpbn/bp/examples/smokers_2.fg
Normal file
@ -0,0 +1,120 @@
|
||||
14
|
||||
|
||||
1
|
||||
6
|
||||
2
|
||||
2
|
||||
0 9.974182
|
||||
1 1.000000
|
||||
|
||||
1
|
||||
7
|
||||
2
|
||||
2
|
||||
0 9.974182
|
||||
1 1.000000
|
||||
|
||||
1
|
||||
4
|
||||
2
|
||||
2
|
||||
0 4.055200
|
||||
1 1.000000
|
||||
|
||||
1
|
||||
5
|
||||
2
|
||||
2
|
||||
0 4.055200
|
||||
1 1.000000
|
||||
|
||||
1
|
||||
0
|
||||
2
|
||||
2
|
||||
0 7.389056
|
||||
1 1.000000
|
||||
|
||||
1
|
||||
2
|
||||
2
|
||||
2
|
||||
0 7.389056
|
||||
1 1.000000
|
||||
|
||||
1
|
||||
1
|
||||
2
|
||||
2
|
||||
0 7.389056
|
||||
1 1.000000
|
||||
|
||||
1
|
||||
3
|
||||
2
|
||||
2
|
||||
0 7.389056
|
||||
1 1.000000
|
||||
|
||||
2
|
||||
4 6
|
||||
2 2
|
||||
4
|
||||
0 4.481689
|
||||
1 1.000000
|
||||
2 4.481689
|
||||
3 4.481689
|
||||
|
||||
2
|
||||
5 7
|
||||
2 2
|
||||
4
|
||||
0 4.481689
|
||||
1 1.000000
|
||||
2 4.481689
|
||||
3 4.481689
|
||||
|
||||
2
|
||||
0 4
|
||||
2 2
|
||||
4
|
||||
0 3.004166
|
||||
1 3.004166
|
||||
2 3.004166
|
||||
3 3.004166
|
||||
|
||||
3
|
||||
2 5 4
|
||||
2 2 2
|
||||
8
|
||||
0 3.004166
|
||||
1 3.004166
|
||||
2 3.004166
|
||||
3 1.000000
|
||||
4 3.004166
|
||||
5 1.000000
|
||||
6 3.004166
|
||||
7 3.004166
|
||||
|
||||
3
|
||||
1 4 5
|
||||
2 2 2
|
||||
8
|
||||
0 3.004166
|
||||
1 3.004166
|
||||
2 3.004166
|
||||
3 1.000000
|
||||
4 3.004166
|
||||
5 1.000000
|
||||
6 3.004166
|
||||
7 3.004166
|
||||
|
||||
2
|
||||
3 5
|
||||
2 2
|
||||
4
|
||||
0 3.004166
|
||||
1 3.004166
|
||||
2 3.004166
|
||||
3 3.004166
|
||||
|
239
packages/CLPBN/clpbn/bp/examples/smokers_3.fg
Normal file
239
packages/CLPBN/clpbn/bp/examples/smokers_3.fg
Normal file
@ -0,0 +1,239 @@
|
||||
27
|
||||
|
||||
1
|
||||
12
|
||||
2
|
||||
2
|
||||
0 9.974182
|
||||
1 1.000000
|
||||
|
||||
1
|
||||
13
|
||||
2
|
||||
2
|
||||
0 9.974182
|
||||
1 1.000000
|
||||
|
||||
1
|
||||
14
|
||||
2
|
||||
2
|
||||
0 9.974182
|
||||
1 1.000000
|
||||
|
||||
1
|
||||
9
|
||||
2
|
||||
2
|
||||
0 4.055200
|
||||
1 1.000000
|
||||
|
||||
1
|
||||
10
|
||||
2
|
||||
2
|
||||
0 4.055200
|
||||
1 1.000000
|
||||
|
||||
1
|
||||
11
|
||||
2
|
||||
2
|
||||
0 4.055200
|
||||
1 1.000000
|
||||
|
||||
1
|
||||
0
|
||||
2
|
||||
2
|
||||
0 7.389056
|
||||
1 1.000000
|
||||
|
||||
1
|
||||
3
|
||||
2
|
||||
2
|
||||
0 7.389056
|
||||
1 1.000000
|
||||
|
||||
1
|
||||
6
|
||||
2
|
||||
2
|
||||
0 7.389056
|
||||
1 1.000000
|
||||
|
||||
1
|
||||
1
|
||||
2
|
||||
2
|
||||
0 7.389056
|
||||
1 1.000000
|
||||
|
||||
1
|
||||
4
|
||||
2
|
||||
2
|
||||
0 7.389056
|
||||
1 1.000000
|
||||
|
||||
1
|
||||
7
|
||||
2
|
||||
2
|
||||
0 7.389056
|
||||
1 1.000000
|
||||
|
||||
1
|
||||
2
|
||||
2
|
||||
2
|
||||
0 7.389056
|
||||
1 1.000000
|
||||
|
||||
1
|
||||
5
|
||||
2
|
||||
2
|
||||
0 7.389056
|
||||
1 1.000000
|
||||
|
||||
1
|
||||
8
|
||||
2
|
||||
2
|
||||
0 7.389056
|
||||
1 1.000000
|
||||
|
||||
2
|
||||
9 12
|
||||
2 2
|
||||
4
|
||||
0 4.481689
|
||||
1 1.000000
|
||||
2 4.481689
|
||||
3 4.481689
|
||||
|
||||
2
|
||||
10 13
|
||||
2 2
|
||||
4
|
||||
0 4.481689
|
||||
1 1.000000
|
||||
2 4.481689
|
||||
3 4.481689
|
||||
|
||||
2
|
||||
11 14
|
||||
2 2
|
||||
4
|
||||
0 4.481689
|
||||
1 1.000000
|
||||
2 4.481689
|
||||
3 4.481689
|
||||
|
||||
2
|
||||
0 9
|
||||
2 2
|
||||
4
|
||||
0 3.004166
|
||||
1 3.004166
|
||||
2 3.004166
|
||||
3 3.004166
|
||||
|
||||
3
|
||||
3 10 9
|
||||
2 2 2
|
||||
8
|
||||
0 3.004166
|
||||
1 3.004166
|
||||
2 3.004166
|
||||
3 1.000000
|
||||
4 3.004166
|
||||
5 1.000000
|
||||
6 3.004166
|
||||
7 3.004166
|
||||
|
||||
3
|
||||
6 11 9
|
||||
2 2 2
|
||||
8
|
||||
0 3.004166
|
||||
1 3.004166
|
||||
2 3.004166
|
||||
3 1.000000
|
||||
4 3.004166
|
||||
5 1.000000
|
||||
6 3.004166
|
||||
7 3.004166
|
||||
|
||||
3
|
||||
1 9 10
|
||||
2 2 2
|
||||
8
|
||||
0 3.004166
|
||||
1 3.004166
|
||||
2 3.004166
|
||||
3 1.000000
|
||||
4 3.004166
|
||||
5 1.000000
|
||||
6 3.004166
|
||||
7 3.004166
|
||||
|
||||
2
|
||||
4 10
|
||||
2 2
|
||||
4
|
||||
0 3.004166
|
||||
1 3.004166
|
||||
2 3.004166
|
||||
3 3.004166
|
||||
|
||||
3
|
||||
7 11 10
|
||||
2 2 2
|
||||
8
|
||||
0 3.004166
|
||||
1 3.004166
|
||||
2 3.004166
|
||||
3 1.000000
|
||||
4 3.004166
|
||||
5 1.000000
|
||||
6 3.004166
|
||||
7 3.004166
|
||||
|
||||
3
|
||||
2 9 11
|
||||
2 2 2
|
||||
8
|
||||
0 3.004166
|
||||
1 3.004166
|
||||
2 3.004166
|
||||
3 1.000000
|
||||
4 3.004166
|
||||
5 1.000000
|
||||
6 3.004166
|
||||
7 3.004166
|
||||
|
||||
3
|
||||
5 10 11
|
||||
2 2 2
|
||||
8
|
||||
0 3.004166
|
||||
1 3.004166
|
||||
2 3.004166
|
||||
3 1.000000
|
||||
4 3.004166
|
||||
5 1.000000
|
||||
6 3.004166
|
||||
7 3.004166
|
||||
|
||||
2
|
||||
8 11
|
||||
2 2
|
||||
4
|
||||
0 3.004166
|
||||
1 3.004166
|
||||
2 3.004166
|
||||
3 3.004166
|
||||
|
398
packages/CLPBN/clpbn/bp/examples/smokers_4.fg
Normal file
398
packages/CLPBN/clpbn/bp/examples/smokers_4.fg
Normal file
@ -0,0 +1,398 @@
|
||||
44
|
||||
|
||||
1
|
||||
20
|
||||
2
|
||||
2
|
||||
0 9.974182
|
||||
1 1.000000
|
||||
|
||||
1
|
||||
21
|
||||
2
|
||||
2
|
||||
0 9.974182
|
||||
1 1.000000
|
||||
|
||||
1
|
||||
22
|
||||
2
|
||||
2
|
||||
0 9.974182
|
||||
1 1.000000
|
||||
|
||||
1
|
||||
23
|
||||
2
|
||||
2
|
||||
0 9.974182
|
||||
1 1.000000
|
||||
|
||||
1
|
||||
16
|
||||
2
|
||||
2
|
||||
0 4.055200
|
||||
1 1.000000
|
||||
|
||||
1
|
||||
17
|
||||
2
|
||||
2
|
||||
0 4.055200
|
||||
1 1.000000
|
||||
|
||||
1
|
||||
18
|
||||
2
|
||||
2
|
||||
0 4.055200
|
||||
1 1.000000
|
||||
|
||||
1
|
||||
19
|
||||
2
|
||||
2
|
||||
0 4.055200
|
||||
1 1.000000
|
||||
|
||||
1
|
||||
0
|
||||
2
|
||||
2
|
||||
0 7.389056
|
||||
1 1.000000
|
||||
|
||||
1
|
||||
4
|
||||
2
|
||||
2
|
||||
0 7.389056
|
||||
1 1.000000
|
||||
|
||||
1
|
||||
8
|
||||
2
|
||||
2
|
||||
0 7.389056
|
||||
1 1.000000
|
||||
|
||||
1
|
||||
12
|
||||
2
|
||||
2
|
||||
0 7.389056
|
||||
1 1.000000
|
||||
|
||||
1
|
||||
1
|
||||
2
|
||||
2
|
||||
0 7.389056
|
||||
1 1.000000
|
||||
|
||||
1
|
||||
5
|
||||
2
|
||||
2
|
||||
0 7.389056
|
||||
1 1.000000
|
||||
|
||||
1
|
||||
9
|
||||
2
|
||||
2
|
||||
0 7.389056
|
||||
1 1.000000
|
||||
|
||||
1
|
||||
13
|
||||
2
|
||||
2
|
||||
0 7.389056
|
||||
1 1.000000
|
||||
|
||||
1
|
||||
2
|
||||
2
|
||||
2
|
||||
0 7.389056
|
||||
1 1.000000
|
||||
|
||||
1
|
||||
6
|
||||
2
|
||||
2
|
||||
0 7.389056
|
||||
1 1.000000
|
||||
|
||||
1
|
||||
10
|
||||
2
|
||||
2
|
||||
0 7.389056
|
||||
1 1.000000
|
||||
|
||||
1
|
||||
14
|
||||
2
|
||||
2
|
||||
0 7.389056
|
||||
1 1.000000
|
||||
|
||||
1
|
||||
3
|
||||
2
|
||||
2
|
||||
0 7.389056
|
||||
1 1.000000
|
||||
|
||||
1
|
||||
7
|
||||
2
|
||||
2
|
||||
0 7.389056
|
||||
1 1.000000
|
||||
|
||||
1
|
||||
11
|
||||
2
|
||||
2
|
||||
0 7.389056
|
||||
1 1.000000
|
||||
|
||||
1
|
||||
15
|
||||
2
|
||||
2
|
||||
0 7.389056
|
||||
1 1.000000
|
||||
|
||||
2
|
||||
16 20
|
||||
2 2
|
||||
4
|
||||
0 4.481689
|
||||
1 1.000000
|
||||
2 4.481689
|
||||
3 4.481689
|
||||
|
||||
2
|
||||
17 21
|
||||
2 2
|
||||
4
|
||||
0 4.481689
|
||||
1 1.000000
|
||||
2 4.481689
|
||||
3 4.481689
|
||||
|
||||
2
|
||||
18 22
|
||||
2 2
|
||||
4
|
||||
0 4.481689
|
||||
1 1.000000
|
||||
2 4.481689
|
||||
3 4.481689
|
||||
|
||||
2
|
||||
19 23
|
||||
2 2
|
||||
4
|
||||
0 4.481689
|
||||
1 1.000000
|
||||
2 4.481689
|
||||
3 4.481689
|
||||
|
||||
2
|
||||
0 16
|
||||
2 2
|
||||
4
|
||||
0 3.004166
|
||||
1 3.004166
|
||||
2 3.004166
|
||||
3 3.004166
|
||||
|
||||
3
|
||||
4 17 16
|
||||
2 2 2
|
||||
8
|
||||
0 3.004166
|
||||
1 3.004166
|
||||
2 3.004166
|
||||
3 1.000000
|
||||
4 3.004166
|
||||
5 1.000000
|
||||
6 3.004166
|
||||
7 3.004166
|
||||
|
||||
3
|
||||
8 18 16
|
||||
2 2 2
|
||||
8
|
||||
0 3.004166
|
||||
1 3.004166
|
||||
2 3.004166
|
||||
3 1.000000
|
||||
4 3.004166
|
||||
5 1.000000
|
||||
6 3.004166
|
||||
7 3.004166
|
||||
|
||||
3
|
||||
12 19 16
|
||||
2 2 2
|
||||
8
|
||||
0 3.004166
|
||||
1 3.004166
|
||||
2 3.004166
|
||||
3 1.000000
|
||||
4 3.004166
|
||||
5 1.000000
|
||||
6 3.004166
|
||||
7 3.004166
|
||||
|
||||
3
|
||||
1 16 17
|
||||
2 2 2
|
||||
8
|
||||
0 3.004166
|
||||
1 3.004166
|
||||
2 3.004166
|
||||
3 1.000000
|
||||
4 3.004166
|
||||
5 1.000000
|
||||
6 3.004166
|
||||
7 3.004166
|
||||
|
||||
2
|
||||
5 17
|
||||
2 2
|
||||
4
|
||||
0 3.004166
|
||||
1 3.004166
|
||||
2 3.004166
|
||||
3 3.004166
|
||||
|
||||
3
|
||||
9 18 17
|
||||
2 2 2
|
||||
8
|
||||
0 3.004166
|
||||
1 3.004166
|
||||
2 3.004166
|
||||
3 1.000000
|
||||
4 3.004166
|
||||
5 1.000000
|
||||
6 3.004166
|
||||
7 3.004166
|
||||
|
||||
3
|
||||
13 19 17
|
||||
2 2 2
|
||||
8
|
||||
0 3.004166
|
||||
1 3.004166
|
||||
2 3.004166
|
||||
3 1.000000
|
||||
4 3.004166
|
||||
5 1.000000
|
||||
6 3.004166
|
||||
7 3.004166
|
||||
|
||||
3
|
||||
2 16 18
|
||||
2 2 2
|
||||
8
|
||||
0 3.004166
|
||||
1 3.004166
|
||||
2 3.004166
|
||||
3 1.000000
|
||||
4 3.004166
|
||||
5 1.000000
|
||||
6 3.004166
|
||||
7 3.004166
|
||||
|
||||
3
|
||||
6 17 18
|
||||
2 2 2
|
||||
8
|
||||
0 3.004166
|
||||
1 3.004166
|
||||
2 3.004166
|
||||
3 1.000000
|
||||
4 3.004166
|
||||
5 1.000000
|
||||
6 3.004166
|
||||
7 3.004166
|
||||
|
||||
2
|
||||
10 18
|
||||
2 2
|
||||
4
|
||||
0 3.004166
|
||||
1 3.004166
|
||||
2 3.004166
|
||||
3 3.004166
|
||||
|
||||
3
|
||||
14 19 18
|
||||
2 2 2
|
||||
8
|
||||
0 3.004166
|
||||
1 3.004166
|
||||
2 3.004166
|
||||
3 1.000000
|
||||
4 3.004166
|
||||
5 1.000000
|
||||
6 3.004166
|
||||
7 3.004166
|
||||
|
||||
3
|
||||
3 16 19
|
||||
2 2 2
|
||||
8
|
||||
0 3.004166
|
||||
1 3.004166
|
||||
2 3.004166
|
||||
3 1.000000
|
||||
4 3.004166
|
||||
5 1.000000
|
||||
6 3.004166
|
||||
7 3.004166
|
||||
|
||||
3
|
||||
7 17 19
|
||||
2 2 2
|
||||
8
|
||||
0 3.004166
|
||||
1 3.004166
|
||||
2 3.004166
|
||||
3 1.000000
|
||||
4 3.004166
|
||||
5 1.000000
|
||||
6 3.004166
|
||||
7 3.004166
|
||||
|
||||
3
|
||||
11 18 19
|
||||
2 2 2
|
||||
8
|
||||
0 3.004166
|
||||
1 3.004166
|
||||
2 3.004166
|
||||
3 1.000000
|
||||
4 3.004166
|
||||
5 1.000000
|
||||
6 3.004166
|
||||
7 3.004166
|
||||
|
||||
2
|
||||
15 19
|
||||
2 2
|
||||
4
|
||||
0 3.004166
|
||||
1 3.004166
|
||||
2 3.004166
|
||||
3 3.004166
|
||||
|
@ -1,17 +0,0 @@
|
||||
MARKOV
|
||||
3
|
||||
2 2 2
|
||||
3
|
||||
1 0
|
||||
1 1
|
||||
3 2 0 1
|
||||
|
||||
2
|
||||
.695 .305
|
||||
|
||||
2
|
||||
.25 .75
|
||||
|
||||
8
|
||||
0.2 0.45 0.32 0.7
|
||||
0.8 0.55 0.68 0.3
|
@ -1,36 +0,0 @@
|
||||
MARKOV
|
||||
5
|
||||
4 2 3 2 3
|
||||
7
|
||||
1 0
|
||||
1 1
|
||||
1 2
|
||||
1 3
|
||||
1 4
|
||||
2 0 1
|
||||
4 1 2 3 4
|
||||
|
||||
4
|
||||
0.1 0.7 0.43 0.22
|
||||
|
||||
2
|
||||
0.2 0.6
|
||||
|
||||
3
|
||||
0.3 0.5 0.2
|
||||
|
||||
2
|
||||
0.15 0.75
|
||||
|
||||
3
|
||||
0.25 0.45 0.15
|
||||
|
||||
8
|
||||
0.210 0.333 0.457 0.4
|
||||
0.811 0.000 0.189 0.89
|
||||
|
||||
36
|
||||
0.1 0.15 0.2 0.25 0.3 0.45 0.5 0.55 0.65 0.7 0.75 0.9
|
||||
0.11 0.22 0.33 0.44 0.55 0.66 0.77 0.88 0.91 0.93 0.95 0.97
|
||||
0.42 0.22 0.33 0.44 0.15 0.36 0.27 0.28 0.21 0.13 0.25 0.17
|
||||
|
@ -1,128 +0,0 @@
|
||||
<?xml version="1.0" encoding="US-ASCII"?>
|
||||
|
||||
<!--
|
||||
|
||||
A B C
|
||||
\ | /
|
||||
\ | /
|
||||
D
|
||||
/ | \
|
||||
/ | \
|
||||
E F G
|
||||
|
||||
-->
|
||||
|
||||
<BIF VERSION="0.3">
|
||||
<NETWORK>
|
||||
<NAME>Node with several parents and childs</NAME>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>A</NAME>
|
||||
<OUTCOME>a1</OUTCOME>
|
||||
<OUTCOME>a2</OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>B</NAME>
|
||||
<OUTCOME>b1</OUTCOME>
|
||||
<OUTCOME>b2</OUTCOME>
|
||||
<OUTCOME>b3</OUTCOME>
|
||||
<OUTCOME>b4</OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>C</NAME>
|
||||
<OUTCOME>c1</OUTCOME>
|
||||
<OUTCOME>c2</OUTCOME>
|
||||
<OUTCOME>c3</OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>D</NAME>
|
||||
<OUTCOME>d1</OUTCOME>
|
||||
<OUTCOME>d2</OUTCOME>
|
||||
<OUTCOME>d3</OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>E</NAME>
|
||||
<OUTCOME>e1</OUTCOME>
|
||||
<OUTCOME>e2</OUTCOME>
|
||||
<OUTCOME>e3</OUTCOME>
|
||||
<OUTCOME>e4</OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>F</NAME>
|
||||
<OUTCOME>f1</OUTCOME>
|
||||
<OUTCOME>f2</OUTCOME>
|
||||
<OUTCOME>f3</OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>G</NAME>
|
||||
<OUTCOME>g1</OUTCOME>
|
||||
<OUTCOME>g2</OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>A</FOR>
|
||||
<TABLE> .1 .2 </TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>B</FOR>
|
||||
<TABLE> .01 .02 .03 .04 </TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>C</FOR>
|
||||
<TABLE> .11 .22 .33 </TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>D</FOR>
|
||||
<GIVEN>A</GIVEN>
|
||||
<GIVEN>B</GIVEN>
|
||||
<GIVEN>C</GIVEN>
|
||||
<TABLE>
|
||||
.522 .008 .99 .01 .2 .8 .003 .457 .423 .007 .92 .04 .5 .232 .033 .227 .112 .048 .91 .21 .24 .18 .005 .227
|
||||
.212 .04 .59 .21 .6 .1 .023 .215 .913 .017 .96 .01 .55 .422 .013 .417 .272 .068 .61 .11 .26 .28 .205 .322
|
||||
.142 .028 .19 .11 .5 .67 .013 .437 .163 .067 .12 .06 .1 .262 .063 .167 .512 .028 .11 .41 .14 .68 .015 .92
|
||||
</TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>E</FOR>
|
||||
<GIVEN>D</GIVEN>
|
||||
<TABLE>
|
||||
.111 .11 .1
|
||||
.222 .22 .2
|
||||
.333 .33 .3
|
||||
.444 .44 .4
|
||||
</TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>F</FOR>
|
||||
<GIVEN>D</GIVEN>
|
||||
<TABLE>
|
||||
.112 .111 .110
|
||||
.223 .222 .221
|
||||
.334 .333 .332
|
||||
</TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>G</FOR>
|
||||
<GIVEN>D</GIVEN>
|
||||
<TABLE>
|
||||
.101 .102 .103
|
||||
.201 .202 .203
|
||||
</TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
</NETWORK>
|
||||
</BIF>
|
||||
|
@ -1,36 +0,0 @@
|
||||
MARKOV
|
||||
5
|
||||
4 2 3 2 3
|
||||
7
|
||||
1 0
|
||||
1 1
|
||||
1 2
|
||||
1 3
|
||||
1 4
|
||||
2 0 1
|
||||
4 1 2 3 4
|
||||
|
||||
4
|
||||
0.1 0.7 0.43 0.22
|
||||
|
||||
2
|
||||
0.2 0.6
|
||||
|
||||
3
|
||||
0.3 0.5 0.2
|
||||
|
||||
2
|
||||
0.15 0.75
|
||||
|
||||
3
|
||||
0.25 0.45 0.15
|
||||
|
||||
8
|
||||
0.210 0.333 0.457 0.4
|
||||
0.811 0.000 0.189 0.89
|
||||
|
||||
36
|
||||
0.1 0.15 0.2 0.25 0.3 0.45 0.5 0.55 0.65 0.7 0.75 0.9
|
||||
0.11 0.22 0.33 0.44 0.55 0.66 0.77 0.88 0.91 0.93 0.95 0.97
|
||||
0.42 0.22 0.33 0.44 0.15 0.36 0.27 0.28 0.21 0.13 0.25 0.17
|
||||
|
@ -1,60 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
cp ~/bin/yap ~/bin/town_comp
|
||||
YAP=~/bin/town_comp
|
||||
|
||||
#OUT_FILE_NAME=results`date "+ %H:%M:%S %d-%m-%Y"`.log
|
||||
OUT_FILE_NAME=bp_compress.log
|
||||
rm -f $OUT_FILE_NAME
|
||||
rm -f ignore.$OUT_FILE_NAME
|
||||
|
||||
|
||||
function run_solver
|
||||
{
|
||||
if [ $2 = bp ]
|
||||
then
|
||||
extra_flag1=clpbn_bp:set_solver_parameter\(run_mode,$4\)
|
||||
extra_flag2=clpbn_bp:set_solver_parameter\(schedule,$5\)
|
||||
extra_flag3=clpbn_bp:set_solver_parameter\(always_loopy_solver,$6\)
|
||||
else
|
||||
extra_flag1=true
|
||||
extra_flag2=true
|
||||
extra_flag3=true
|
||||
fi
|
||||
/usr/bin/time -o $OUT_FILE_NAME -a -f "real:%E\tuser:%U\tsys:%S" $YAP << EOF >> $OUT_FILE_NAME 2>> ignore.$OUT_FILE_NAME
|
||||
[$1].
|
||||
clpbn:set_clpbn_flag(solver,$2),
|
||||
clpbn_bp:use_log_space,
|
||||
$extra_flag1, $extra_flag2, $extra_flag3,
|
||||
run_query(_R),
|
||||
open("$OUT_FILE_NAME", 'append',S),
|
||||
format(S, '$3: ~15+ ',[]),
|
||||
close(S).
|
||||
EOF
|
||||
}
|
||||
|
||||
|
||||
function run_all_graphs
|
||||
{
|
||||
echo "*******************************************************************" >> "$OUT_FILE_NAME"
|
||||
echo "results for solver $2" >> $OUT_FILE_NAME
|
||||
echo "*******************************************************************" >> "$OUT_FILE_NAME"
|
||||
run_solver town_1000 $1 town_1000 $3 $4 $5
|
||||
run_solver town_5000 $1 town_5000 $3 $4 $5
|
||||
run_solver town_10000 $1 town_10000 $3 $4 $5
|
||||
run_solver town_50000 $1 town_50000 $3 $4 $5
|
||||
run_solver town_100000 $1 town_100000 $3 $4 $5
|
||||
run_solver town_500000 $1 town_500000 $3 $4 $5
|
||||
run_solver town_1000000 $1 town_1000000 $3 $4 $5
|
||||
run_solver town_2500000 $1 town_2500000 $3 $4 $5
|
||||
run_solver town_5000000 $1 town_5000000 $3 $4 $5
|
||||
run_solver town_7500000 $1 town_7500000 $3 $4 $5
|
||||
run_solver town_10000000 $1 town_10000000 $3 $4 $5
|
||||
}
|
||||
|
||||
run_solver town_10000 "bp(compress,seq_fixed)" town_10000 compress seq_fixed true
|
||||
exit
|
||||
|
||||
##########
|
||||
run_all_graphs bp "bp(compress,seq_fixed) " compress seq_fixed true
|
||||
|
@ -1,51 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
YAP=~/bin/town_conv
|
||||
|
||||
#OUT_FILE_NAME=results`date "+ %H:%M:%S %d-%m-%Y"`.log
|
||||
OUT_FILE_NAME=bp_convert.log
|
||||
rm -f $OUT_FILE_NAME
|
||||
rm -f ignore.$OUT_FILE_NAME
|
||||
|
||||
|
||||
function run_solver
|
||||
{
|
||||
if [ $2 = bp ]
|
||||
then
|
||||
extra_flag1=clpbn_bp:set_solver_parameter\(run_mode,$4\)
|
||||
extra_flag2=clpbn_bp:set_solver_parameter\(schedule,$5\)
|
||||
extra_flag3=clpbn_bp:set_solver_parameter\(always_loopy_solver,$6\)
|
||||
else
|
||||
extra_flag1=true
|
||||
extra_flag2=true
|
||||
extra_flag3=true
|
||||
fi
|
||||
/usr/bin/time -o $OUT_FILE_NAME -a -f "real:%E\tuser:%U\tsys:%S" $YAP << EOF >> $OUT_FILE_NAME 2>> ignore.$OUT_FILE_NAME
|
||||
[$1].
|
||||
clpbn:set_clpbn_flag(solver,$2),
|
||||
clpbn_bp:use_log_space,
|
||||
$extra_flag1, $extra_flag2, $extra_flag3,
|
||||
run_query(_R),
|
||||
open("$OUT_FILE_NAME", 'append',S),
|
||||
format(S, '$3: ~15+ ',[]),
|
||||
close(S).
|
||||
EOF
|
||||
}
|
||||
|
||||
|
||||
function run_all_graphs
|
||||
{
|
||||
echo "*******************************************************************" >> "$OUT_FILE_NAME"
|
||||
echo "results for solver $2" >> $OUT_FILE_NAME
|
||||
echo "*******************************************************************" >> "$OUT_FILE_NAME"
|
||||
run_solver town_1000 $1 town_1000 $3 $4 $5
|
||||
run_solver town_5000 $1 town_5000 $3 $4 $5
|
||||
run_solver town_10000 $1 town_10000 $3 $4 $5
|
||||
run_solver town_50000 $1 town_50000 $3 $4 $5
|
||||
run_solver town_100000 $1 town_100000 $3 $4 $5
|
||||
run_solver town_500000 $1 town_500000 $3 $4 $5
|
||||
run_solver town_1000000 $1 town_1000000 $3 $4 $5
|
||||
}
|
||||
|
||||
run_all_graphs bp "bp(convert,seq_fixed) " convert seq_fixed false
|
||||
|
@ -1,50 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
YAP=~/bin/town_norm
|
||||
|
||||
#OUT_FILE_NAME=results`date "+ %H:%M:%S %d-%m-%Y"`.log
|
||||
OUT_FILE_NAME=bp_normal.log
|
||||
rm -f $OUT_FILE_NAME
|
||||
rm -f ignore.$OUT_FILE_NAME
|
||||
|
||||
|
||||
function run_solver
|
||||
{
|
||||
if [ $2 = bp ]
|
||||
then
|
||||
extra_flag1=clpbn_bp:set_solver_parameter\(run_mode,$4\)
|
||||
extra_flag2=clpbn_bp:set_solver_parameter\(schedule,$5\)
|
||||
extra_flag3=clpbn_bp:set_solver_parameter\(always_loopy_solver,$6\)
|
||||
else
|
||||
extra_flag1=true
|
||||
extra_flag2=true
|
||||
extra_flag3=true
|
||||
fi
|
||||
/usr/bin/time -o $OUT_FILE_NAME -a -f "real:%E\tuser:%U\tsys:%S" $YAP << EOF >> $OUT_FILE_NAME 2>> ignore.$OUT_FILE_NAME
|
||||
[$1].
|
||||
clpbn:set_clpbn_flag(solver,$2),
|
||||
clpbn_bp:use_log_space,
|
||||
$extra_flag1, $extra_flag2, $extra_flag3,
|
||||
run_query(_R),
|
||||
open("$OUT_FILE_NAME", 'append',S),
|
||||
format(S, '$3: ~15+ ',[]),
|
||||
close(S).
|
||||
EOF
|
||||
}
|
||||
|
||||
|
||||
function run_all_graphs
|
||||
{
|
||||
echo "*******************************************************************" >> "$OUT_FILE_NAME"
|
||||
echo "results for solver $2" >> $OUT_FILE_NAME
|
||||
echo "*******************************************************************" >> "$OUT_FILE_NAME"
|
||||
run_solver town_1000 $1 town_1000 $3 $4 $5
|
||||
run_solver town_5000 $1 town_5000 $3 $4 $5
|
||||
run_solver town_10000 $1 town_10000 $3 $4 $5
|
||||
run_solver town_50000 $1 town_50000 $3 $4 $5
|
||||
run_solver town_100000 $1 town_100000 $3 $4 $5
|
||||
run_solver town_500000 $1 town_500000 $3 $4 $5
|
||||
run_solver town_1000000 $1 town_1000000 $3 $4 $5
|
||||
}
|
||||
|
||||
run_all_graphs bp "bp(normal,seq_fixed) " normal seq_fixed false
|
@ -1,51 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
YAP=~/bin/town_gibbs
|
||||
|
||||
#OUT_FILE_NAME=results`date "+ %H:%M:%S %d-%m-%Y"`.log
|
||||
OUT_FILE_NAME=gibbs.log
|
||||
rm -f $OUT_FILE_NAME
|
||||
rm -f ignore.$OUT_FILE_NAME
|
||||
|
||||
|
||||
function run_solver
|
||||
{
|
||||
if [ $2 = bp ]
|
||||
then
|
||||
extra_flag1=clpbn_bp:set_solver_parameter\(run_mode,$4\)
|
||||
extra_flag2=clpbn_bp:set_solver_parameter\(schedule,$5\)
|
||||
extra_flag3=clpbn_bp:set_solver_parameter\(always_loopy_solver,$6\)
|
||||
else
|
||||
extra_flag1=true
|
||||
extra_flag2=true
|
||||
extra_flag3=true
|
||||
fi
|
||||
/usr/bin/time -o $OUT_FILE_NAME -a -f "real:%E\tuser:%U\tsys:%S" $YAP << EOF >> $OUT_FILE_NAME 2>> ignore.$OUT_FILE_NAME
|
||||
[$1].
|
||||
clpbn:set_clpbn_flag(solver,$2),
|
||||
clpbn_bp:use_log_space,
|
||||
$extra_flag1, $extra_flag2, $extra_flag3,
|
||||
run_query(_R),
|
||||
open("$OUT_FILE_NAME", 'append',S),
|
||||
format(S, '$3: ~15+ ',[]),
|
||||
close(S).
|
||||
EOF
|
||||
}
|
||||
|
||||
|
||||
function run_all_graphs
|
||||
{
|
||||
echo "*******************************************************************" >> "$OUT_FILE_NAME"
|
||||
echo "results for solver $2" >> $OUT_FILE_NAME
|
||||
echo "*******************************************************************" >> "$OUT_FILE_NAME"
|
||||
run_solver town_1000 $1 town_1000 $3 $4 $5
|
||||
run_solver town_5000 $1 town_5000 $3 $4 $5
|
||||
run_solver town_10000 $1 town_10000 $3 $4 $5
|
||||
run_solver town_50000 $1 town_50000 $3 $4 $5
|
||||
run_solver town_100000 $1 town_100000 $3 $4 $5
|
||||
run_solver town_500000 $1 town_500000 $3 $4 $5
|
||||
run_solver town_1000000 $1 town_1000000 $3 $4 $5
|
||||
}
|
||||
|
||||
run_all_graphs gibbs "gibbs "
|
||||
|
@ -1,51 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
YAP=~/bin/town_jt
|
||||
|
||||
#OUT_FILE_NAME=results`date "+ %H:%M:%S %d-%m-%Y"`.log
|
||||
OUT_FILE_NAME=jt.log
|
||||
rm -f $OUT_FILE_NAME
|
||||
rm -f ignore.$OUT_FILE_NAME
|
||||
|
||||
|
||||
function run_solver
|
||||
{
|
||||
if [ $2 = bp ]
|
||||
then
|
||||
extra_flag1=clpbn_bp:set_solver_parameter\(run_mode,$4\)
|
||||
extra_flag2=clpbn_bp:set_solver_parameter\(schedule,$5\)
|
||||
extra_flag3=clpbn_bp:set_solver_parameter\(always_loopy_solver,$6\)
|
||||
else
|
||||
extra_flag1=true
|
||||
extra_flag2=true
|
||||
extra_flag3=true
|
||||
fi
|
||||
/usr/bin/time -o $OUT_FILE_NAME -a -f "real:%E\tuser:%U\tsys:%S" $YAP << EOF >> $OUT_FILE_NAME 2>> ignore.$OUT_FILE_NAME
|
||||
[$1].
|
||||
clpbn:set_clpbn_flag(solver,$2),
|
||||
clpbn_bp:use_log_space,
|
||||
$extra_flag1, $extra_flag2, $extra_flag3,
|
||||
run_query(_R),
|
||||
open("$OUT_FILE_NAME", 'append',S),
|
||||
format(S, '$3: ~15+ ',[]),
|
||||
close(S).
|
||||
EOF
|
||||
}
|
||||
|
||||
|
||||
function run_all_graphs
|
||||
{
|
||||
echo "*******************************************************************" >> "$OUT_FILE_NAME"
|
||||
echo "results for solver $2" >> $OUT_FILE_NAME
|
||||
echo "*******************************************************************" >> "$OUT_FILE_NAME"
|
||||
run_solver town_1000 $1 town_1000 $3 $4 $5
|
||||
run_solver town_5000 $1 town_5000 $3 $4 $5
|
||||
run_solver town_10000 $1 town_10000 $3 $4 $5
|
||||
run_solver town_50000 $1 town_50000 $3 $4 $5
|
||||
run_solver town_100000 $1 town_100000 $3 $4 $5
|
||||
run_solver town_500000 $1 town_500000 $3 $4 $5
|
||||
run_solver town_1000000 $1 town_1000000 $3 $4 $5
|
||||
}
|
||||
|
||||
run_all_graphs jt "jt "
|
||||
|
@ -1,51 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
YAP=~/bin/town_ve
|
||||
|
||||
#OUT_FILE_NAME=results`date "+ %H:%M:%S %d-%m-%Y"`.log
|
||||
OUT_FILE_NAME=ve.log
|
||||
rm -f $OUT_FILE_NAME
|
||||
rm -f ignore.$OUT_FILE_NAME
|
||||
|
||||
|
||||
function run_solver
|
||||
{
|
||||
if [ $2 = bp ]
|
||||
then
|
||||
extra_flag1=clpbn_bp:set_solver_parameter\(run_mode,$4\)
|
||||
extra_flag2=clpbn_bp:set_solver_parameter\(schedule,$5\)
|
||||
extra_flag3=clpbn_bp:set_solver_parameter\(always_loopy_solver,$6\)
|
||||
else
|
||||
extra_flag1=true
|
||||
extra_flag2=true
|
||||
extra_flag3=true
|
||||
fi
|
||||
/usr/bin/time -o $OUT_FILE_NAME -a -f "real:%E\tuser:%U\tsys:%S" $YAP << EOF >> $OUT_FILE_NAME 2>> ignore.$OUT_FILE_NAME
|
||||
[$1].
|
||||
clpbn:set_clpbn_flag(solver,$2),
|
||||
clpbn_bp:use_log_space,
|
||||
$extra_flag1, $extra_flag2, $extra_flag3,
|
||||
run_query(_R),
|
||||
open("$OUT_FILE_NAME", 'append',S),
|
||||
format(S, '$3: ~15+ ',[]),
|
||||
close(S).
|
||||
EOF
|
||||
}
|
||||
|
||||
|
||||
function run_all_graphs
|
||||
{
|
||||
echo "*******************************************************************" >> "$OUT_FILE_NAME"
|
||||
echo "results for solver $2" >> $OUT_FILE_NAME
|
||||
echo "*******************************************************************" >> "$OUT_FILE_NAME"
|
||||
run_solver town_1000 $1 town_1000 $3 $4 $5
|
||||
run_solver town_5000 $1 town_5000 $3 $4 $5
|
||||
run_solver town_10000 $1 town_10000 $3 $4 $5
|
||||
run_solver town_50000 $1 town_50000 $3 $4 $5
|
||||
run_solver town_100000 $1 town_100000 $3 $4 $5
|
||||
run_solver town_500000 $1 town_500000 $3 $4 $5
|
||||
run_solver town_1000000 $1 town_1000000 $3 $4 $5
|
||||
}
|
||||
|
||||
run_all_graphs ve "ve "
|
||||
|
@ -1,65 +0,0 @@
|
||||
|
||||
conservative_city(City, Cons) :-
|
||||
cons_table(City, ConsDist),
|
||||
{ Cons = conservative_city(City) with p([y,n], ConsDist) }.
|
||||
|
||||
|
||||
gender(X, Gender) :-
|
||||
gender_table(X, GenderDist),
|
||||
{ Gender = gender(X) with p([m,f], GenderDist) }.
|
||||
|
||||
|
||||
hair_color(X, Color) :-
|
||||
lives(X, City),
|
||||
conservative_city(City, Cons),
|
||||
hair_color_table(X,ColorTable),
|
||||
{ Color = hair_color(X) with
|
||||
p([t,f], ColorTable,[Cons]) }.
|
||||
|
||||
|
||||
car_color(X, Color) :-
|
||||
hair_color(X, HColor),
|
||||
car_color_table(X,CColorTable),
|
||||
{ Color = car_color(X) with
|
||||
p([t,f], CColorTable,[HColor]) }.
|
||||
|
||||
|
||||
height(X, Height) :-
|
||||
gender(X, Gender),
|
||||
height_table(X,HeightTable),
|
||||
{ Height = height(X) with
|
||||
p([t,f], HeightTable,[Gender]) }.
|
||||
|
||||
|
||||
shoe_size(X, Shoesize) :-
|
||||
height(X, Height),
|
||||
shoe_size_table(X,ShoesizeTable),
|
||||
{ Shoesize = shoe_size(X) with
|
||||
p([t,f], ShoesizeTable,[Height]) }.
|
||||
|
||||
|
||||
guilty(X, Guilt) :-
|
||||
guilty_table(X, GuiltDist),
|
||||
{ Guilt = guilty(X) with p([y,n], GuiltDist) }.
|
||||
|
||||
|
||||
descn(X, Descn) :-
|
||||
car_color(X, Car),
|
||||
hair_color(X, Hair),
|
||||
height(X, Height),
|
||||
guilty(X, Guilt),
|
||||
descn_table(X, DescTable),
|
||||
{ Descn = descn(X) with
|
||||
p([t,f], DescTable,[Car,Hair,Height,Guilt]) }.
|
||||
|
||||
|
||||
witness(City, Witness) :-
|
||||
descn(joe, DescnJ),
|
||||
descn(p2, Descn2),
|
||||
wit_table(WitTable),
|
||||
{ Witness = witness(City) with
|
||||
p([t,f], WitTable,[DescnJ, Descn2]) }.
|
||||
|
||||
|
||||
:- ensure_loaded(tables).
|
||||
|
@ -1,46 +0,0 @@
|
||||
|
||||
cons_table(amsterdam, [0.2, 0.8]) :- !.
|
||||
cons_table(_, [0.8, 0.2]).
|
||||
|
||||
|
||||
gender_table(_, [0.55, 0.44]).
|
||||
|
||||
|
||||
hair_color_table(_,
|
||||
/* conservative_city */
|
||||
/* y n */
|
||||
[ 0.05, 0.1,
|
||||
0.95, 0.9 ]).
|
||||
|
||||
|
||||
car_color_table(_,
|
||||
/* t f */
|
||||
[ 0.9, 0.2,
|
||||
0.1, 0.8 ]).
|
||||
|
||||
|
||||
height_table(_,
|
||||
/* m f */
|
||||
[ 0.6, 0.4,
|
||||
0.4, 0.6 ]).
|
||||
|
||||
|
||||
shoe_size_table(_,
|
||||
/* t f */
|
||||
[ 0.9, 0.1,
|
||||
0.1, 0.9 ]).
|
||||
|
||||
|
||||
guilty_table(_, [0.23, 0.77]).
|
||||
|
||||
|
||||
descn_table(_,
|
||||
/* color, hair, height, guilt */
|
||||
/* ttttt tttf ttft ttff tfttt tftf tfft tfff ttttt fttf ftft ftff ffttt fftf ffft ffff */
|
||||
[ 0.99, 0.5, 0.23, 0.88, 0.41, 0.3, 0.76, 0.87, 0.44, 0.43, 0.29, 0.72, 0.33, 0.91, 0.95, 0.92,
|
||||
0.01, 0.5, 0.77, 0.12, 0.59, 0.7, 0.24, 0.13, 0.56, 0.57, 0.61, 0.28, 0.77, 0.09, 0.05, 0.08]).
|
||||
|
||||
|
||||
wit_table([0.2, 0.45, 0.24, 0.34,
|
||||
0.8, 0.55, 0.76, 0.66]).
|
||||
|
@ -1,59 +0,0 @@
|
||||
#!/home/tgomes/bin/yap -L --
|
||||
|
||||
/*
|
||||
Steps:
|
||||
1. generate N facts lives(I, nyc), 0 <= I < N.
|
||||
2. generate evidence on descn for N people, *** except for 1 ***
|
||||
3. Run query ?- guilty(joe, Guilty), witness(joe, t), descn(2,t), descn(3, f), descn(4, f) ...
|
||||
*/
|
||||
|
||||
:- initialization(main).
|
||||
|
||||
|
||||
main :-
|
||||
unix(argv([H])),
|
||||
generate_town(H).
|
||||
|
||||
|
||||
generate_town(N) :-
|
||||
atomic_concat(['town_', N, '.yap'], FileName),
|
||||
open(FileName, 'write', S),
|
||||
write(S, ':- source.\n'),
|
||||
write(S, ':- style_check(all).\n'),
|
||||
write(S, ':- yap_flag(unknown,error).\n'),
|
||||
write(S, ':- yap_flag(write_strings,on).\n'),
|
||||
write(S, ':- use_module(library(clpbn)).\n'),
|
||||
write(S, ':- set_clpbn_flag(solver, bp).\n'),
|
||||
write(S, ':- [-schema].\n\n'),
|
||||
write(S, 'lives(_joe, nyc).\n'),
|
||||
atom_number(N, N2),
|
||||
generate_people(S, N2, 2),
|
||||
write(S, '\nrun_query(Guilty) :- \n'),
|
||||
write(S, '\tguilty(joe, Guilty),\n'),
|
||||
write(S, '\twitness(nyc, t),\n'),
|
||||
write(S, '\trunall(X, ev(X)).\n\n\n'),
|
||||
write(S, 'runall(G, Wrapper) :-\n'),
|
||||
write(S, '\tfindall(G, Wrapper, L),\n'),
|
||||
write(S, '\texecute_all(L).\n\n\n'),
|
||||
write(S, 'execute_all([]).\n'),
|
||||
write(S, 'execute_all(G.L) :-\n'),
|
||||
write(S, '\tcall(G),\n'),
|
||||
write(S, '\texecute_all(L).\n\n\n'),
|
||||
generate_query(S, N2, 2),
|
||||
close(S).
|
||||
|
||||
|
||||
generate_people(_, N, Counting1) :- !.
|
||||
generate_people(S, N, Counting) :-
|
||||
format(S, 'lives(p~w, nyc).~n', [Counting]),
|
||||
Counting1 is Counting + 1,
|
||||
generate_people(S, N, Counting1).
|
||||
|
||||
|
||||
generate_query(S, N, Counting) :-
|
||||
Counting > N, !.
|
||||
generate_query(S, N, Counting) :- !,
|
||||
format(S, 'ev(descn(p~w, t)).~n', [Counting]),
|
||||
Counting1 is Counting + 1,
|
||||
generate_query(S, N, Counting1).
|
||||
|
@ -1,69 +0,0 @@
|
||||
<?xml version="1.0" encoding="US-ASCII"?>
|
||||
|
||||
<!--
|
||||
|
||||
A B
|
||||
\ /
|
||||
\ /
|
||||
C
|
||||
|
|
||||
|
|
||||
D
|
||||
|
||||
-->
|
||||
|
||||
|
||||
<BIF VERSION="0.3">
|
||||
<NETWORK>
|
||||
<NAME>Simple Loop</NAME>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>A</NAME>
|
||||
<OUTCOME>a1</OUTCOME>
|
||||
<OUTCOME>a2</OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>B</NAME>
|
||||
<OUTCOME>b1</OUTCOME>
|
||||
<OUTCOME>b2</OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>C</NAME>
|
||||
<OUTCOME>c1</OUTCOME>
|
||||
<OUTCOME>c2</OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<VARIABLE TYPE="nature">
|
||||
<NAME>D</NAME>
|
||||
<OUTCOME>d1</OUTCOME>
|
||||
<OUTCOME>d2</OUTCOME>
|
||||
</VARIABLE>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>A</FOR>
|
||||
<TABLE> .001 .009 </TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>B</FOR>
|
||||
<TABLE> .002 .008 </TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>C</FOR>
|
||||
<GIVEN>A</GIVEN>
|
||||
<GIVEN>B</GIVEN>
|
||||
<TABLE> .95 .05 .94 .06 .29 .71 .001 .999 </TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
<DEFINITION>
|
||||
<FOR>D</FOR>
|
||||
<GIVEN>C</GIVEN>
|
||||
<TABLE> .9 .1 .05 .95 </TABLE>
|
||||
</DEFINITION>
|
||||
|
||||
</NETWORK>
|
||||
</BIF>
|
||||
|
Reference in New Issue
Block a user