new version of bp

This commit is contained in:
Vitor Santos Costa 2012-03-22 11:33:24 +00:00
parent 6e36498cac
commit 21d317b223
91 changed files with 1255511 additions and 3840 deletions

View File

@ -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++) {

View File

@ -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_;
};

View File

@ -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];

View File

@ -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];
}

View File

@ -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
{

View File

@ -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
{

View File

@ -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 ++;
// }
// }

View File

@ -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

View File

@ -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;
}

View File

@ -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;

File diff suppressed because it is too large Load Diff

View 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

View File

@ -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;
}

View File

@ -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

View File

@ -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);

View File

@ -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()) {

View File

@ -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_;
};

View File

@ -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;
}

View File

@ -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_;
};

View File

@ -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;

View File

@ -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

View File

@ -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
{

View File

@ -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);

View 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;
}

View 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

View File

@ -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

View 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);
}

View 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

View 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

View File

@ -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());
}

View File

@ -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);
}

View 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

View 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;
}

View 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

View File

@ -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;\

View 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);
}

View 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

View 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);
}
}
}
}

View 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

View 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_;
}

View 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

View File

@ -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

View File

@ -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] << ") = " ;

View File

@ -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_;

View File

@ -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

View 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

View File

@ -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;

View 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

View File

@ -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;
}
}

View File

@ -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_;
};

View File

@ -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();
}

View File

@ -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])).

View File

@ -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>

View File

@ -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>

View File

@ -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>

View 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

View File

@ -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>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View 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,_)].

View File

@ -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>

View File

@ -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>

View 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).

View 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).

View 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).

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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]).

View File

@ -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

View File

@ -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>

View File

@ -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]).

View File

@ -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>

View 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

View 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

View 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

View File

@ -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

View File

@ -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

View File

@ -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>

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 "

View File

@ -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 "

View File

@ -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 "

View File

@ -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).

View File

@ -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]).

View File

@ -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).

View File

@ -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>