new version of bp
This commit is contained in:
parent
6e36498cac
commit
21d317b223
@ -8,6 +8,7 @@
|
|||||||
#include "xmlParser/xmlParser.h"
|
#include "xmlParser/xmlParser.h"
|
||||||
|
|
||||||
#include "BayesNet.h"
|
#include "BayesNet.h"
|
||||||
|
#include "Util.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -75,7 +76,7 @@ BayesNet::readFromBifFormat (const char* fileName)
|
|||||||
}
|
}
|
||||||
node->setParents (parents);
|
node->setParents (parents);
|
||||||
unsigned count = 0;
|
unsigned count = 0;
|
||||||
ParamSet params (nParams);
|
Params params (nParams);
|
||||||
stringstream s (def.getChildNode("TABLE").getText());
|
stringstream s (def.getChildNode("TABLE").getText());
|
||||||
while (!s.eof() && count < nParams) {
|
while (!s.eof() && count < nParams) {
|
||||||
s >> params[count];
|
s >> params[count];
|
||||||
@ -93,27 +94,18 @@ BayesNet::readFromBifFormat (const char* fileName)
|
|||||||
}
|
}
|
||||||
|
|
||||||
setIndexes();
|
setIndexes();
|
||||||
if (NSPACE == NumberSpace::LOGARITHM) {
|
if (Globals::logDomain) {
|
||||||
distributionsToLogs();
|
distributionsToLogs();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
BayesNet::addNode (BayesNode* n)
|
|
||||||
{
|
|
||||||
indexMap_.insert (make_pair (n->varId(), nodes_.size()));
|
|
||||||
nodes_.push_back (n);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
BayesNode*
|
BayesNode*
|
||||||
BayesNet::addNode (string label, const States& states)
|
BayesNet::addNode (string label, const States& states)
|
||||||
{
|
{
|
||||||
VarId vid = nodes_.size();
|
VarId vid = nodes_.size();
|
||||||
indexMap_.insert (make_pair (vid, nodes_.size()));
|
varMap_.insert (make_pair (vid, nodes_.size()));
|
||||||
GraphicalModel::addVariableInformation (vid, label, states);
|
GraphicalModel::addVariableInformation (vid, label, states);
|
||||||
BayesNode* node = new BayesNode (VarNode (vid, states.size()));
|
BayesNode* node = new BayesNode (VarNode (vid, states.size()));
|
||||||
nodes_.push_back (node);
|
nodes_.push_back (node);
|
||||||
@ -123,56 +115,20 @@ BayesNet::addNode (string label, const States& states)
|
|||||||
|
|
||||||
|
|
||||||
BayesNode*
|
BayesNode*
|
||||||
BayesNet::addNode (VarId vid,
|
BayesNet::addNode (VarId vid, unsigned dsize, int evidence, Distribution* dist)
|
||||||
unsigned dsize,
|
|
||||||
int evidence,
|
|
||||||
BnNodeSet& parents,
|
|
||||||
Distribution* dist)
|
|
||||||
{
|
{
|
||||||
indexMap_.insert (make_pair (vid, nodes_.size()));
|
varMap_.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()));
|
|
||||||
nodes_.push_back (new BayesNode (vid, dsize, evidence, dist));
|
nodes_.push_back (new BayesNode (vid, dsize, evidence, dist));
|
||||||
return nodes_.back();
|
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*
|
BayesNode*
|
||||||
BayesNet::getBayesNode (VarId vid) const
|
BayesNet::getBayesNode (VarId vid) const
|
||||||
{
|
{
|
||||||
IndexMap::const_iterator it = indexMap_.find (vid);
|
IndexMap::const_iterator it = varMap_.find (vid);
|
||||||
if (it == indexMap_.end()) {
|
if (it == varMap_.end()) {
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
return nodes_[it->second];
|
return nodes_[it->second];
|
||||||
@ -233,7 +189,7 @@ BayesNet::getDistribution (unsigned distId) const
|
|||||||
{
|
{
|
||||||
Distribution* dist = 0;
|
Distribution* dist = 0;
|
||||||
for (unsigned i = 0; i < dists_.size(); i++) {
|
for (unsigned i = 0; i < dists_.size(); i++) {
|
||||||
if (dists_[i]->id == distId) {
|
if (dists_[i]->id == (int) distId) {
|
||||||
dist = dists_[i];
|
dist = dists_[i];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -290,33 +246,25 @@ BayesNet::getLeafNodes (void) const
|
|||||||
BayesNet*
|
BayesNet*
|
||||||
BayesNet::getMinimalRequesiteNetwork (VarId vid) const
|
BayesNet::getMinimalRequesiteNetwork (VarId vid) const
|
||||||
{
|
{
|
||||||
return getMinimalRequesiteNetwork (VarIdSet() = {vid});
|
return getMinimalRequesiteNetwork (VarIds() = {vid});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
BayesNet*
|
BayesNet*
|
||||||
BayesNet::getMinimalRequesiteNetwork (const VarIdSet& queryVarIds) const
|
BayesNet::getMinimalRequesiteNetwork (const VarIds& queryVarIds) const
|
||||||
{
|
{
|
||||||
BnNodeSet queryVars;
|
BnNodeSet queryVars;
|
||||||
|
Scheduling scheduling;
|
||||||
for (unsigned i = 0; i < queryVarIds.size(); i++) {
|
for (unsigned i = 0; i < queryVarIds.size(); i++) {
|
||||||
assert (getBayesNode (queryVarIds[i]));
|
BayesNode* n = getBayesNode (queryVarIds[i]);
|
||||||
queryVars.push_back (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);
|
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()) {
|
while (!scheduling.empty()) {
|
||||||
ScheduleInfo& sch = scheduling.front();
|
ScheduleInfo& sch = scheduling.front();
|
||||||
StateInfo* state = states[sch.node->getIndex()];
|
StateInfo* state = states[sch.node->getIndex()];
|
||||||
@ -385,7 +333,7 @@ BayesNet::constructGraph (BayesNet* bn,
|
|||||||
const vector<StateInfo*>& states) const
|
const vector<StateInfo*>& states) const
|
||||||
{
|
{
|
||||||
BnNodeSet mrnNodes;
|
BnNodeSet mrnNodes;
|
||||||
vector<VarIdSet> parents;
|
vector<VarIds> parents;
|
||||||
for (unsigned i = 0; i < nodes_.size(); i++) {
|
for (unsigned i = 0; i < nodes_.size(); i++) {
|
||||||
bool isRequired = false;
|
bool isRequired = false;
|
||||||
if (states[i]) {
|
if (states[i]) {
|
||||||
@ -394,7 +342,7 @@ BayesNet::constructGraph (BayesNet* bn,
|
|||||||
states[i]->markedOnTop;
|
states[i]->markedOnTop;
|
||||||
}
|
}
|
||||||
if (isRequired) {
|
if (isRequired) {
|
||||||
parents.push_back (VarIdSet());
|
parents.push_back (VarIds());
|
||||||
if (states[i]->markedOnTop) {
|
if (states[i]->markedOnTop) {
|
||||||
const BnNodeSet& ps = nodes_[i]->getParents();
|
const BnNodeSet& ps = nodes_[i]->getParents();
|
||||||
for (unsigned j = 0; j < ps.size(); j++) {
|
for (unsigned j = 0; j < ps.size(); j++) {
|
||||||
@ -473,7 +421,7 @@ BayesNet::printGraphicalModel (void) const
|
|||||||
void
|
void
|
||||||
BayesNet::exportToGraphViz (const char* fileName,
|
BayesNet::exportToGraphViz (const char* fileName,
|
||||||
bool showNeighborless,
|
bool showNeighborless,
|
||||||
const VarIdSet& highlightVarIds) const
|
const VarIds& highlightVarIds) const
|
||||||
{
|
{
|
||||||
ofstream out (fileName);
|
ofstream out (fileName);
|
||||||
if (!out.is_open()) {
|
if (!out.is_open()) {
|
||||||
@ -556,7 +504,7 @@ BayesNet::exportToBifFormat (const char* fileName) const
|
|||||||
out << "\t<GIVEN>" << parents[j]->label();
|
out << "\t<GIVEN>" << parents[j]->label();
|
||||||
out << "</GIVEN>" << endl;
|
out << "</GIVEN>" << endl;
|
||||||
}
|
}
|
||||||
ParamSet params = revertParameterReorder (nodes_[i]->getParameters(),
|
Params params = revertParameterReorder (nodes_[i]->getParameters(),
|
||||||
nodes_[i]->nrStates());
|
nodes_[i]->nrStates());
|
||||||
out << "\t<TABLE>" ;
|
out << "\t<TABLE>" ;
|
||||||
for (unsigned j = 0; j < params.size(); j++) {
|
for (unsigned j = 0; j < params.size(); j++) {
|
||||||
@ -627,8 +575,8 @@ BayesNet::getAdjacentNodes (int v) const
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
ParamSet
|
Params
|
||||||
BayesNet::reorderParameters (const ParamSet& params, unsigned dsize) const
|
BayesNet::reorderParameters (const Params& params, unsigned dsize) const
|
||||||
{
|
{
|
||||||
// the interchange format for bayesian networks keeps the probabilities
|
// the interchange format for bayesian networks keeps the probabilities
|
||||||
// in the following order:
|
// in the following order:
|
||||||
@ -640,7 +588,7 @@ BayesNet::reorderParameters (const ParamSet& params, unsigned dsize) const
|
|||||||
// p(a2|b2,c1) p(a2|b2,c2).
|
// p(a2|b2,c1) p(a2|b2,c2).
|
||||||
unsigned count = 0;
|
unsigned count = 0;
|
||||||
unsigned rowSize = params.size() / dsize;
|
unsigned rowSize = params.size() / dsize;
|
||||||
ParamSet reordered;
|
Params reordered;
|
||||||
while (reordered.size() < params.size()) {
|
while (reordered.size() < params.size()) {
|
||||||
unsigned idx = count;
|
unsigned idx = count;
|
||||||
for (unsigned i = 0; i < rowSize; i++) {
|
for (unsigned i = 0; i < rowSize; i++) {
|
||||||
@ -654,12 +602,12 @@ BayesNet::reorderParameters (const ParamSet& params, unsigned dsize) const
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
ParamSet
|
Params
|
||||||
BayesNet::revertParameterReorder (const ParamSet& params, unsigned dsize) const
|
BayesNet::revertParameterReorder (const Params& params, unsigned dsize) const
|
||||||
{
|
{
|
||||||
unsigned count = 0;
|
unsigned count = 0;
|
||||||
unsigned rowSize = params.size() / dsize;
|
unsigned rowSize = params.size() / dsize;
|
||||||
ParamSet reordered;
|
Params reordered;
|
||||||
while (reordered.size() < params.size()) {
|
while (reordered.size() < params.size()) {
|
||||||
unsigned idx = count;
|
unsigned idx = count;
|
||||||
for (unsigned i = 0; i < dsize; i++) {
|
for (unsigned i = 0; i < dsize; i++) {
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
#include "GraphicalModel.h"
|
#include "GraphicalModel.h"
|
||||||
#include "BayesNode.h"
|
#include "BayesNode.h"
|
||||||
#include "Shared.h"
|
#include "Horus.h"
|
||||||
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
@ -53,11 +53,9 @@ class BayesNet : public GraphicalModel
|
|||||||
~BayesNet (void);
|
~BayesNet (void);
|
||||||
|
|
||||||
void readFromBifFormat (const char*);
|
void readFromBifFormat (const char*);
|
||||||
void addNode (BayesNode*);
|
|
||||||
BayesNode* addNode (string, const States&);
|
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 (VarId, unsigned, int, Distribution*);
|
||||||
BayesNode* addNode (string, States, BnNodeSet&, ParamSet&);
|
|
||||||
BayesNode* getBayesNode (VarId) const;
|
BayesNode* getBayesNode (VarId) const;
|
||||||
BayesNode* getBayesNode (string) const;
|
BayesNode* getBayesNode (string) const;
|
||||||
VarNode* getVariableNode (VarId) const;
|
VarNode* getVariableNode (VarId) const;
|
||||||
@ -69,7 +67,7 @@ class BayesNet : public GraphicalModel
|
|||||||
BnNodeSet getRootNodes (void) const;
|
BnNodeSet getRootNodes (void) const;
|
||||||
BnNodeSet getLeafNodes (void) const;
|
BnNodeSet getLeafNodes (void) const;
|
||||||
BayesNet* getMinimalRequesiteNetwork (VarId) const;
|
BayesNet* getMinimalRequesiteNetwork (VarId) const;
|
||||||
BayesNet* getMinimalRequesiteNetwork (const VarIdSet&) const;
|
BayesNet* getMinimalRequesiteNetwork (const VarIds&) const;
|
||||||
void constructGraph (
|
void constructGraph (
|
||||||
BayesNet*, const vector<StateInfo*>&) const;
|
BayesNet*, const vector<StateInfo*>&) const;
|
||||||
bool isPolyTree (void) const;
|
bool isPolyTree (void) const;
|
||||||
@ -78,7 +76,7 @@ class BayesNet : public GraphicalModel
|
|||||||
void freeDistributions (void);
|
void freeDistributions (void);
|
||||||
void printGraphicalModel (void) const;
|
void printGraphicalModel (void) const;
|
||||||
void exportToGraphViz (const char*, bool = true,
|
void exportToGraphViz (const char*, bool = true,
|
||||||
const VarIdSet& = VarIdSet()) const;
|
const VarIds& = VarIds()) const;
|
||||||
void exportToBifFormat (const char*) const;
|
void exportToBifFormat (const char*) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -87,8 +85,8 @@ class BayesNet : public GraphicalModel
|
|||||||
bool containsUndirectedCycle (void) const;
|
bool containsUndirectedCycle (void) const;
|
||||||
bool containsUndirectedCycle (int, int, vector<bool>&)const;
|
bool containsUndirectedCycle (int, int, vector<bool>&)const;
|
||||||
vector<int> getAdjacentNodes (int) const;
|
vector<int> getAdjacentNodes (int) const;
|
||||||
ParamSet reorderParameters (const ParamSet&, unsigned) const;
|
Params reorderParameters (const Params&, unsigned) const;
|
||||||
ParamSet revertParameterReorder (const ParamSet&, unsigned) const;
|
Params revertParameterReorder (const Params&, unsigned) const;
|
||||||
void scheduleParents (const BayesNode*, Scheduling&) const;
|
void scheduleParents (const BayesNode*, Scheduling&) const;
|
||||||
void scheduleChilds (const BayesNode*, Scheduling&) const;
|
void scheduleChilds (const BayesNode*, Scheduling&) const;
|
||||||
|
|
||||||
@ -96,7 +94,7 @@ class BayesNet : public GraphicalModel
|
|||||||
DistSet dists_;
|
DistSet dists_;
|
||||||
|
|
||||||
typedef unordered_map<unsigned, unsigned> IndexMap;
|
typedef unordered_map<unsigned, unsigned> IndexMap;
|
||||||
IndexMap indexMap_;
|
IndexMap varMap_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ BayesNode::getDistribution (void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
const ParamSet&
|
const Params&
|
||||||
BayesNode::getParameters (void)
|
BayesNode::getParameters (void)
|
||||||
{
|
{
|
||||||
return dist_->params;
|
return dist_->params;
|
||||||
@ -79,12 +79,12 @@ BayesNode::getParameters (void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
ParamSet
|
Params
|
||||||
BayesNode::getRow (int rowIndex) const
|
BayesNode::getRow (int rowIndex) const
|
||||||
{
|
{
|
||||||
int rowSize = getRowSize();
|
int rowSize = getRowSize();
|
||||||
int offset = rowSize * rowIndex;
|
int offset = rowSize * rowIndex;
|
||||||
ParamSet row (rowSize);
|
Params row (rowSize);
|
||||||
for (int i = 0; i < rowSize; i++) {
|
for (int i = 0; i < rowSize; i++) {
|
||||||
row[i] = dist_->params[offset + 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
|
int
|
||||||
BayesNode::getIndexOfParent (const BayesNode* parent) const
|
BayesNode::getIndexOfParent (const BayesNode* parent) const
|
||||||
{
|
{
|
||||||
@ -173,42 +138,20 @@ BayesNode::getIndexOfParent (const BayesNode* parent) const
|
|||||||
|
|
||||||
|
|
||||||
string
|
string
|
||||||
BayesNode::cptEntryToString (const CptEntry& entry) const
|
BayesNode::cptEntryToString (
|
||||||
|
int row,
|
||||||
|
const vector<unsigned>& stateConf) const
|
||||||
{
|
{
|
||||||
stringstream ss;
|
stringstream ss;
|
||||||
ss << "p(" ;
|
ss << "p(" ;
|
||||||
const DConf& conf = entry.getDomainConfiguration();
|
|
||||||
int row = entry.getParameterIndex() / getRowSize();
|
|
||||||
ss << states()[row];
|
ss << states()[row];
|
||||||
if (parents_.size() > 0) {
|
if (parents_.size() > 0) {
|
||||||
ss << "|" ;
|
ss << "|" ;
|
||||||
for (unsigned int i = 0; i < conf.size(); i++) {
|
for (unsigned int i = 0; i < stateConf.size(); i++) {
|
||||||
if (i != 0) {
|
if (i != 0) {
|
||||||
ss << ",";
|
ss << ",";
|
||||||
}
|
}
|
||||||
ss << parents_[i]->states()[conf[i]];
|
ss << parents_[i]->states()[stateConf[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 << ")" ;
|
ss << ")" ;
|
||||||
@ -334,7 +277,7 @@ operator << (ostream& o, const BayesNode& node)
|
|||||||
o << endl;
|
o << endl;
|
||||||
|
|
||||||
for (unsigned int i = 0; i < states.size(); i++) {
|
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;
|
o << left << setw (domainWidth) << states[i] << right;
|
||||||
for (unsigned j = 0; j < node.getRowSize(); j++) {
|
for (unsigned j = 0; j < node.getRowSize(); j++) {
|
||||||
o << setw (widths[j]) << row[j];
|
o << setw (widths[j]) << row[j];
|
||||||
|
@ -4,9 +4,8 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "VarNode.h"
|
#include "VarNode.h"
|
||||||
#include "CptEntry.h"
|
|
||||||
#include "Distribution.h"
|
#include "Distribution.h"
|
||||||
#include "Shared.h"
|
#include "Horus.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
@ -22,17 +21,14 @@ class BayesNode : public VarNode
|
|||||||
void addChild (BayesNode*);
|
void addChild (BayesNode*);
|
||||||
void setDistribution (Distribution*);
|
void setDistribution (Distribution*);
|
||||||
Distribution* getDistribution (void);
|
Distribution* getDistribution (void);
|
||||||
const ParamSet& getParameters (void);
|
const Params& getParameters (void);
|
||||||
ParamSet getRow (int) const;
|
Params getRow (int) const;
|
||||||
void setProbability (int, const CptEntry&, double);
|
|
||||||
bool isRoot (void);
|
bool isRoot (void);
|
||||||
bool isLeaf (void);
|
bool isLeaf (void);
|
||||||
bool hasNeighbors (void) const;
|
bool hasNeighbors (void) const;
|
||||||
int getCptSize (void);
|
int getCptSize (void);
|
||||||
const vector<CptEntry>& getCptEntries (void);
|
|
||||||
int getIndexOfParent (const BayesNode*) const;
|
int getIndexOfParent (const BayesNode*) const;
|
||||||
string cptEntryToString (const CptEntry&) const;
|
string cptEntryToString (int, const vector<unsigned>&) const;
|
||||||
string cptEntryToString (int, const CptEntry&) const;
|
|
||||||
|
|
||||||
const BnNodeSet& getParents (void) const { return parents_; }
|
const BnNodeSet& getParents (void) const { return parents_; }
|
||||||
const BnNodeSet& getChilds (void) const { return childs_; }
|
const BnNodeSet& getChilds (void) const { return childs_; }
|
||||||
@ -42,9 +38,8 @@ class BayesNode : public VarNode
|
|||||||
return dist_->params.size() / nrStates();
|
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;
|
int idx = (row * getRowSize()) + col;
|
||||||
return dist_->params[idx];
|
return dist_->params[idx];
|
||||||
}
|
}
|
||||||
|
@ -9,12 +9,11 @@
|
|||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
|
||||||
#include "BnBpSolver.h"
|
#include "BnBpSolver.h"
|
||||||
|
#include "Indexer.h"
|
||||||
|
|
||||||
BnBpSolver::BnBpSolver (const BayesNet& bn) : Solver (&bn)
|
BnBpSolver::BnBpSolver (const BayesNet& bn) : Solver (&bn)
|
||||||
{
|
{
|
||||||
bayesNet_ = &bn;
|
bayesNet_ = &bn;
|
||||||
jointCalcType_ = CHAIN_RULE;
|
|
||||||
//jointCalcType_ = JUNCTION_NODE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -39,21 +38,18 @@ BnBpSolver::runSolver (void)
|
|||||||
start = clock();
|
start = clock();
|
||||||
}
|
}
|
||||||
initializeSolver();
|
initializeSolver();
|
||||||
if (!BpOptions::useAlwaysLoopySolver && bayesNet_->isPolyTree()) {
|
runLoopySolver();
|
||||||
runPolyTreeSolver();
|
if (DL >= 2) {
|
||||||
} else {
|
cout << endl;
|
||||||
runLoopySolver();
|
if (nIters_ < BpOptions::maxIter) {
|
||||||
if (DL >= 2) {
|
cout << "Belief propagation converged in " ;
|
||||||
|
cout << nIters_ << " iterations" << endl;
|
||||||
|
} else {
|
||||||
|
cout << "The maximum number of iterations was hit, terminating..." ;
|
||||||
cout << endl;
|
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();
|
unsigned size = bayesNet_->nrNodes();
|
||||||
if (COLLECT_STATISTICS) {
|
if (COLLECT_STATISTICS) {
|
||||||
unsigned nIters = 0;
|
unsigned nIters = 0;
|
||||||
@ -71,7 +67,7 @@ BnBpSolver::runSolver (void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
ParamSet
|
Params
|
||||||
BnBpSolver::getPosterioriOf (VarId vid)
|
BnBpSolver::getPosterioriOf (VarId vid)
|
||||||
{
|
{
|
||||||
BayesNode* node = bayesNet_->getBayesNode (vid);
|
BayesNode* node = bayesNet_->getBayesNode (vid);
|
||||||
@ -81,8 +77,8 @@ BnBpSolver::getPosterioriOf (VarId vid)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
ParamSet
|
Params
|
||||||
BnBpSolver::getJointDistributionOf (const VarIdSet& jointVarIds)
|
BnBpSolver::getJointDistributionOf (const VarIds& jointVarIds)
|
||||||
{
|
{
|
||||||
if (DL >= 2) {
|
if (DL >= 2) {
|
||||||
cout << "calculating joint distribution on: " ;
|
cout << "calculating joint distribution on: " ;
|
||||||
@ -92,12 +88,7 @@ BnBpSolver::getJointDistributionOf (const VarIdSet& jointVarIds)
|
|||||||
}
|
}
|
||||||
cout << endl;
|
cout << endl;
|
||||||
}
|
}
|
||||||
|
return getJointByConditioning (jointVarIds);
|
||||||
if (jointCalcType_ == JUNCTION_NODE) {
|
|
||||||
return getJointByJunctionNode (jointVarIds);
|
|
||||||
} else {
|
|
||||||
return getJointByChainRule (jointVarIds);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -121,8 +112,8 @@ BnBpSolver::initializeSolver (void)
|
|||||||
|
|
||||||
BnNodeSet roots = bayesNet_->getRootNodes();
|
BnNodeSet roots = bayesNet_->getRootNodes();
|
||||||
for (unsigned i = 0; i < roots.size(); i++) {
|
for (unsigned i = 0; i < roots.size(); i++) {
|
||||||
const ParamSet& params = roots[i]->getParameters();
|
const Params& params = roots[i]->getParameters();
|
||||||
ParamSet& piVals = ninf(roots[i])->getPiValues();
|
Params& piVals = ninf(roots[i])->getPiValues();
|
||||||
for (unsigned ri = 0; ri < roots[i]->nrStates(); ri++) {
|
for (unsigned ri = 0; ri < roots[i]->nrStates(); ri++) {
|
||||||
piVals[ri] = params[ri];
|
piVals[ri] = params[ri];
|
||||||
}
|
}
|
||||||
@ -149,8 +140,8 @@ BnBpSolver::initializeSolver (void)
|
|||||||
|
|
||||||
for (unsigned i = 0; i < nodes.size(); i++) {
|
for (unsigned i = 0; i < nodes.size(); i++) {
|
||||||
if (nodes[i]->hasEvidence()) {
|
if (nodes[i]->hasEvidence()) {
|
||||||
ParamSet& piVals = ninf(nodes[i])->getPiValues();
|
Params& piVals = ninf(nodes[i])->getPiValues();
|
||||||
ParamSet& ldVals = ninf(nodes[i])->getLambdaValues();
|
Params& ldVals = ninf(nodes[i])->getLambdaValues();
|
||||||
for (unsigned xi = 0; xi < nodes[i]->nrStates(); xi++) {
|
for (unsigned xi = 0; xi < nodes[i]->nrStates(); xi++) {
|
||||||
piVals[xi] = Util::noEvidence();
|
piVals[xi] = Util::noEvidence();
|
||||||
ldVals[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
|
void
|
||||||
BnBpSolver::runLoopySolver()
|
BnBpSolver::runLoopySolver()
|
||||||
{
|
{
|
||||||
@ -298,7 +219,7 @@ BnBpSolver::converged (void) const
|
|||||||
}
|
}
|
||||||
bool converged = true;
|
bool converged = true;
|
||||||
if (BpOptions::schedule == BpOptions::Schedule::MAX_RESIDUAL) {
|
if (BpOptions::schedule == BpOptions::Schedule::MAX_RESIDUAL) {
|
||||||
Param maxResidual = (*(sortedOrder_.begin()))->getResidual();
|
double maxResidual = (*(sortedOrder_.begin()))->getResidual();
|
||||||
if (maxResidual < BpOptions::accuracy) {
|
if (maxResidual < BpOptions::accuracy) {
|
||||||
converged = true;
|
converged = true;
|
||||||
} else {
|
} else {
|
||||||
@ -306,7 +227,7 @@ BnBpSolver::converged (void) const
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (unsigned i = 0; i < links_.size(); i++) {
|
for (unsigned i = 0; i < links_.size(); i++) {
|
||||||
Param residual = links_[i]->getResidual();
|
double residual = links_[i]->getResidual();
|
||||||
if (DL >= 2) {
|
if (DL >= 2) {
|
||||||
cout << links_[i]->toString() + " residual change = " ;
|
cout << links_[i]->toString() + " residual change = " ;
|
||||||
cout << residual << endl;
|
cout << residual << endl;
|
||||||
@ -395,36 +316,38 @@ BnBpSolver::updatePiValues (BayesNode* x)
|
|||||||
if (DL >= 3) {
|
if (DL >= 3) {
|
||||||
cout << "updating " << PI_SYMBOL << " values for " << x->label() << endl;
|
cout << "updating " << PI_SYMBOL << " values for " << x->label() << endl;
|
||||||
}
|
}
|
||||||
ParamSet& piValues = ninf(x)->getPiValues();
|
Params& piValues = ninf(x)->getPiValues();
|
||||||
const BpLinkSet& parentLinks = ninf(x)->getIncomingParentLinks();
|
const BpLinkSet& parentLinks = ninf(x)->getIncomingParentLinks();
|
||||||
const vector<CptEntry>& entries = x->getCptEntries();
|
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* calcs1 = 0;
|
||||||
stringstream* calcs2 = 0;
|
stringstream* calcs2 = 0;
|
||||||
|
|
||||||
ParamSet messageProducts (entries.size());
|
Params messageProducts (indexer.size());
|
||||||
for (unsigned k = 0; k < entries.size(); k++) {
|
for (unsigned k = 0; k < indexer.size(); k++) {
|
||||||
if (DL >= 5) {
|
if (DL >= 5) {
|
||||||
calcs1 = new stringstream;
|
calcs1 = new stringstream;
|
||||||
calcs2 = new stringstream;
|
calcs2 = new stringstream;
|
||||||
}
|
}
|
||||||
double messageProduct = Util::multIdenty();
|
double messageProduct = Util::multIdenty();
|
||||||
const DConf& conf = entries[k].getDomainConfiguration();
|
if (Globals::logDomain) {
|
||||||
switch (NSPACE) {
|
for (unsigned i = 0; i < parentLinks.size(); i++) {
|
||||||
case NumberSpace::NORMAL:
|
messageProduct += parentLinks[i]->getMessage()[indexer[i]];
|
||||||
for (unsigned i = 0; i < parentLinks.size(); i++) {
|
}
|
||||||
messageProduct *= parentLinks[i]->getMessage()[conf[i]];
|
} else {
|
||||||
if (DL >= 5) {
|
for (unsigned i = 0; i < parentLinks.size(); i++) {
|
||||||
if (i != 0) *calcs1 << " + " ;
|
messageProduct *= parentLinks[i]->getMessage()[indexer[i]];
|
||||||
if (i != 0) *calcs2 << " + " ;
|
if (DL >= 5) {
|
||||||
*calcs1 << parentLinks[i]->toString (conf[i]);
|
if (i != 0) *calcs1 << " + " ;
|
||||||
*calcs2 << parentLinks[i]->getMessage()[conf[i]];
|
if (i != 0) *calcs2 << " + " ;
|
||||||
}
|
*calcs1 << parentLinks[i]->toString (indexer[i]);
|
||||||
}
|
*calcs2 << parentLinks[i]->getMessage()[indexer[i]];
|
||||||
break;
|
|
||||||
case NumberSpace::LOGARITHM:
|
|
||||||
for (unsigned i = 0; i < parentLinks.size(); i++) {
|
|
||||||
messageProduct += parentLinks[i]->getMessage()[conf[i]];
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
messageProducts[k] = messageProduct;
|
messageProducts[k] = messageProduct;
|
||||||
if (DL >= 5) {
|
if (DL >= 5) {
|
||||||
@ -439,6 +362,7 @@ BnBpSolver::updatePiValues (BayesNode* x)
|
|||||||
delete calcs1;
|
delete calcs1;
|
||||||
delete calcs2;
|
delete calcs2;
|
||||||
}
|
}
|
||||||
|
++ indexer;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned xi = 0; xi < x->nrStates(); xi++) {
|
for (unsigned xi = 0; xi < x->nrStates(); xi++) {
|
||||||
@ -447,26 +371,28 @@ BnBpSolver::updatePiValues (BayesNode* x)
|
|||||||
calcs1 = new stringstream;
|
calcs1 = new stringstream;
|
||||||
calcs2 = new stringstream;
|
calcs2 = new stringstream;
|
||||||
}
|
}
|
||||||
switch (NSPACE) {
|
indexer.reset();
|
||||||
case NumberSpace::NORMAL:
|
if (Globals::logDomain) {
|
||||||
for (unsigned k = 0; k < entries.size(); k++) {
|
for (unsigned k = 0; k < indexer.size(); k++) {
|
||||||
sum += x->getProbability (xi, entries[k]) * messageProducts[k];
|
Util::logSum (sum,
|
||||||
if (DL >= 5) {
|
x->getProbability(xi, indexer.linearIndex()) + messageProducts[k]);
|
||||||
if (k != 0) *calcs1 << " + " ;
|
++ indexer;
|
||||||
if (k != 0) *calcs2 << " + " ;
|
}
|
||||||
*calcs1 << x->cptEntryToString (xi, entries[k]);
|
} else {
|
||||||
*calcs1 << ".mp" << k;
|
for (unsigned k = 0; k < indexer.size(); k++) {
|
||||||
*calcs2 << Util::fl (x->getProbability (xi, entries[k]));
|
sum += x->getProbability (xi, indexer.linearIndex()) * messageProducts[k];
|
||||||
*calcs2 << "*" << messageProducts[k];
|
if (DL >= 5) {
|
||||||
}
|
if (k != 0) *calcs1 << " + " ;
|
||||||
}
|
if (k != 0) *calcs2 << " + " ;
|
||||||
break;
|
*calcs1 << x->cptEntryToString (xi, indexer.indices());
|
||||||
case NumberSpace::LOGARITHM:
|
*calcs1 << ".mp" << k;
|
||||||
for (unsigned k = 0; k < entries.size(); k++) {
|
*calcs2 << Util::fl (x->getProbability (xi, indexer.linearIndex()));
|
||||||
Util::logSum (sum,
|
*calcs2 << "*" << messageProducts[k];
|
||||||
x->getProbability(xi,entries[k]) + messageProducts[k]);
|
|
||||||
}
|
}
|
||||||
|
++ indexer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
piValues[xi] = sum;
|
piValues[xi] = sum;
|
||||||
if (DL >= 5) {
|
if (DL >= 5) {
|
||||||
cout << " " << PI_SYMBOL << "(" << x->label() << ")" ;
|
cout << " " << PI_SYMBOL << "(" << x->label() << ")" ;
|
||||||
@ -489,7 +415,7 @@ BnBpSolver::updateLambdaValues (BayesNode* x)
|
|||||||
if (DL >= 3) {
|
if (DL >= 3) {
|
||||||
cout << "updating " << LD_SYMBOL << " values for " << x->label() << endl;
|
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();
|
const BpLinkSet& childLinks = ninf(x)->getIncomingChildLinks();
|
||||||
stringstream* calcs1 = 0;
|
stringstream* calcs1 = 0;
|
||||||
stringstream* calcs2 = 0;
|
stringstream* calcs2 = 0;
|
||||||
@ -500,22 +426,20 @@ BnBpSolver::updateLambdaValues (BayesNode* x)
|
|||||||
calcs2 = new stringstream;
|
calcs2 = new stringstream;
|
||||||
}
|
}
|
||||||
double product = Util::multIdenty();
|
double product = Util::multIdenty();
|
||||||
switch (NSPACE) {
|
if (Globals::logDomain) {
|
||||||
case NumberSpace::NORMAL:
|
for (unsigned i = 0; i < childLinks.size(); i++) {
|
||||||
for (unsigned i = 0; i < childLinks.size(); i++) {
|
product += childLinks[i]->getMessage()[xi];
|
||||||
product *= childLinks[i]->getMessage()[xi];
|
}
|
||||||
if (DL >= 5) {
|
} else {
|
||||||
if (i != 0) *calcs1 << "." ;
|
for (unsigned i = 0; i < childLinks.size(); i++) {
|
||||||
if (i != 0) *calcs2 << "*" ;
|
product *= childLinks[i]->getMessage()[xi];
|
||||||
*calcs1 << childLinks[i]->toString (xi);
|
if (DL >= 5) {
|
||||||
*calcs2 << childLinks[i]->getMessage()[xi];
|
if (i != 0) *calcs1 << "." ;
|
||||||
}
|
if (i != 0) *calcs2 << "*" ;
|
||||||
}
|
*calcs1 << childLinks[i]->toString (xi);
|
||||||
break;
|
*calcs2 << childLinks[i]->getMessage()[xi];
|
||||||
case NumberSpace::LOGARITHM:
|
|
||||||
for (unsigned i = 0; i < childLinks.size(); i++) {
|
|
||||||
product += childLinks[i]->getMessage()[xi];
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
lambdaValues[xi] = product;
|
lambdaValues[xi] = product;
|
||||||
if (DL >= 5) {
|
if (DL >= 5) {
|
||||||
@ -542,12 +466,12 @@ BnBpSolver::calculatePiMessage (BpLink* link)
|
|||||||
// πX(Zi)
|
// πX(Zi)
|
||||||
BayesNode* z = link->getSource();
|
BayesNode* z = link->getSource();
|
||||||
BayesNode* x = link->getDestination();
|
BayesNode* x = link->getDestination();
|
||||||
ParamSet& zxPiNextMessage = link->getNextMessage();
|
Params& zxPiNextMessage = link->getNextMessage();
|
||||||
const BpLinkSet& zChildLinks = ninf(z)->getIncomingChildLinks();
|
const BpLinkSet& zChildLinks = ninf(z)->getIncomingChildLinks();
|
||||||
stringstream* calcs1 = 0;
|
stringstream* calcs1 = 0;
|
||||||
stringstream* calcs2 = 0;
|
stringstream* calcs2 = 0;
|
||||||
|
|
||||||
const ParamSet& zPiValues = ninf(z)->getPiValues();
|
const Params& zPiValues = ninf(z)->getPiValues();
|
||||||
for (unsigned zi = 0; zi < z->nrStates(); zi++) {
|
for (unsigned zi = 0; zi < z->nrStates(); zi++) {
|
||||||
double product = zPiValues[zi];
|
double product = zPiValues[zi];
|
||||||
if (DL >= 5) {
|
if (DL >= 5) {
|
||||||
@ -557,24 +481,22 @@ BnBpSolver::calculatePiMessage (BpLink* link)
|
|||||||
*calcs1 << "[" << z->states()[zi] << "]" ;
|
*calcs1 << "[" << z->states()[zi] << "]" ;
|
||||||
*calcs2 << product;
|
*calcs2 << product;
|
||||||
}
|
}
|
||||||
switch (NSPACE) {
|
if (Globals::logDomain) {
|
||||||
case NumberSpace::NORMAL:
|
for (unsigned i = 0; i < zChildLinks.size(); i++) {
|
||||||
for (unsigned i = 0; i < zChildLinks.size(); i++) {
|
if (zChildLinks[i]->getSource() != x) {
|
||||||
if (zChildLinks[i]->getSource() != x) {
|
product += zChildLinks[i]->getMessage()[zi];
|
||||||
product *= zChildLinks[i]->getMessage()[zi];
|
}
|
||||||
if (DL >= 5) {
|
}
|
||||||
*calcs1 << "." << zChildLinks[i]->toString (zi);
|
} else {
|
||||||
*calcs2 << " * " << zChildLinks[i]->getMessage()[zi];
|
for (unsigned i = 0; i < zChildLinks.size(); i++) {
|
||||||
}
|
if (zChildLinks[i]->getSource() != x) {
|
||||||
}
|
product *= zChildLinks[i]->getMessage()[zi];
|
||||||
}
|
if (DL >= 5) {
|
||||||
break;
|
*calcs1 << "." << zChildLinks[i]->toString (zi);
|
||||||
case NumberSpace::LOGARITHM:
|
*calcs2 << " * " << zChildLinks[i]->getMessage()[zi];
|
||||||
for (unsigned i = 0; i < zChildLinks.size(); i++) {
|
|
||||||
if (zChildLinks[i]->getSource() != x) {
|
|
||||||
product += zChildLinks[i]->getMessage()[zi];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
zxPiNextMessage[zi] = product;
|
zxPiNextMessage[zi] = product;
|
||||||
if (DL >= 5) {
|
if (DL >= 5) {
|
||||||
@ -605,52 +527,53 @@ BnBpSolver::calculateLambdaMessage (BpLink* link)
|
|||||||
if (x->hasEvidence()) {
|
if (x->hasEvidence()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ParamSet& yxLambdaNextMessage = link->getNextMessage();
|
Params& yxLambdaNextMessage = link->getNextMessage();
|
||||||
const BpLinkSet& yParentLinks = ninf(y)->getIncomingParentLinks();
|
const BpLinkSet& yParentLinks = ninf(y)->getIncomingParentLinks();
|
||||||
const ParamSet& yLambdaValues = ninf(y)->getLambdaValues();
|
const Params& yLambdaValues = ninf(y)->getLambdaValues();
|
||||||
const vector<CptEntry>& allEntries = y->getCptEntries();
|
|
||||||
int parentIndex = y->getIndexOfParent (x);
|
int parentIndex = y->getIndexOfParent (x);
|
||||||
stringstream* calcs1 = 0;
|
stringstream* calcs1 = 0;
|
||||||
stringstream* calcs2 = 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());
|
const BnNodeSet& ps = y->getParents();
|
||||||
for (unsigned k = 0; k < entries.size(); k++) {
|
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) {
|
if (DL >= 5) {
|
||||||
calcs1 = new stringstream;
|
calcs1 = new stringstream;
|
||||||
calcs2 = new stringstream;
|
calcs2 = new stringstream;
|
||||||
}
|
}
|
||||||
double messageProduct = Util::multIdenty();
|
double messageProduct = Util::multIdenty();
|
||||||
const DConf& conf = entries[k].getDomainConfiguration();
|
if (Globals::logDomain) {
|
||||||
switch (NSPACE) {
|
for (unsigned i = 0; i < yParentLinks.size(); i++) {
|
||||||
case NumberSpace::NORMAL:
|
if (yParentLinks[i]->getSource() != x) {
|
||||||
for (unsigned i = 0; i < yParentLinks.size(); i++) {
|
messageProduct += yParentLinks[i]->getMessage()[indexer[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]];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
case NumberSpace::LOGARITHM:
|
} else {
|
||||||
for (unsigned i = 0; i < yParentLinks.size(); i++) {
|
for (unsigned i = 0; i < yParentLinks.size(); i++) {
|
||||||
if (yParentLinks[i]->getSource() != x) {
|
if (yParentLinks[i]->getSource() != x) {
|
||||||
messageProduct += yParentLinks[i]->getMessage()[conf[i]];
|
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;
|
messageProducts[k] = messageProduct;
|
||||||
|
++ indexer;
|
||||||
if (DL >= 5) {
|
if (DL >= 5) {
|
||||||
cout << " mp" << k;
|
cout << " mp" << k;
|
||||||
cout << " = " << (*calcs1).str();
|
cout << " = " << (*calcs1).str();
|
||||||
@ -672,13 +595,6 @@ BnBpSolver::calculateLambdaMessage (BpLink* link)
|
|||||||
calcs1 = new stringstream;
|
calcs1 = new stringstream;
|
||||||
calcs2 = 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();
|
double outerSum = Util::addIdenty();
|
||||||
for (unsigned yi = 0; yi < y->nrStates(); yi++) {
|
for (unsigned yi = 0; yi < y->nrStates(); yi++) {
|
||||||
if (DL >= 5) {
|
if (DL >= 5) {
|
||||||
@ -686,27 +602,35 @@ BnBpSolver::calculateLambdaMessage (BpLink* link)
|
|||||||
(yi != 0) ? *calcs2 << " + {" : *calcs2 << "{" ;
|
(yi != 0) ? *calcs2 << " + {" : *calcs2 << "{" ;
|
||||||
}
|
}
|
||||||
double innerSum = Util::addIdenty();
|
double innerSum = Util::addIdenty();
|
||||||
switch (NSPACE) {
|
indexer.reset();
|
||||||
case NumberSpace::NORMAL:
|
if (Globals::logDomain) {
|
||||||
for (unsigned k = 0; k < entries.size(); k++) {
|
for (unsigned k = 0; k < N; k++) {
|
||||||
if (DL >= 5) {
|
while (indexer[parentIndex] != xi) {
|
||||||
if (k != 0) *calcs1 << " + " ;
|
++ indexer;
|
||||||
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];
|
|
||||||
}
|
}
|
||||||
outerSum += innerSum * yLambdaValues[yi];
|
Util::logSum (innerSum, y->getProbability (
|
||||||
break;
|
yi, indexer.linearIndex()) + messageProducts[k]);
|
||||||
case NumberSpace::LOGARITHM:
|
++ indexer;
|
||||||
for (unsigned k = 0; k < entries.size(); k++) {
|
}
|
||||||
Util::logSum (innerSum,
|
Util::logSum (outerSum, innerSum + yLambdaValues[yi]);
|
||||||
y->getProbability(yi, entries[k]) + messageProducts[k]);
|
} else {
|
||||||
}
|
for (unsigned k = 0; k < N; k++) {
|
||||||
Util::logSum (outerSum, innerSum + yLambdaValues[yi]);
|
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) {
|
if (DL >= 5) {
|
||||||
*calcs1 << "}." << LD_SYMBOL << "(" << y->label() << ")" ;
|
*calcs1 << "}." << LD_SYMBOL << "(" << y->label() << ")" ;
|
||||||
@ -730,62 +654,45 @@ BnBpSolver::calculateLambdaMessage (BpLink* link)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
ParamSet
|
Params
|
||||||
BnBpSolver::getJointByJunctionNode (const VarIdSet& jointVarIds)
|
BnBpSolver::getJointByConditioning (const VarIds& jointVarIds) const
|
||||||
{
|
|
||||||
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
|
|
||||||
{
|
{
|
||||||
BnNodeSet jointVars;
|
BnNodeSet jointVars;
|
||||||
for (unsigned i = 0; i < jointVarIds.size(); i++) {
|
for (unsigned i = 0; i < jointVarIds.size(); i++) {
|
||||||
|
assert (bayesNet_->getBayesNode (jointVarIds[i]));
|
||||||
jointVars.push_back (bayesNet_->getBayesNode (jointVarIds[i]));
|
jointVars.push_back (bayesNet_->getBayesNode (jointVarIds[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
BayesNet* mrn = bayesNet_->getMinimalRequesiteNetwork (jointVarIds[0]);
|
BayesNet* mrn = bayesNet_->getMinimalRequesiteNetwork (jointVarIds[0]);
|
||||||
BnBpSolver solver (*mrn);
|
BnBpSolver solver (*mrn);
|
||||||
solver.runSolver();
|
solver.runSolver();
|
||||||
ParamSet prevBeliefs = solver.getPosterioriOf (jointVarIds[0]);
|
Params prevBeliefs = solver.getPosterioriOf (jointVarIds[0]);
|
||||||
delete mrn;
|
delete mrn;
|
||||||
|
|
||||||
VarNodes observedVars = {jointVars[0]};
|
VarIds observedVids = {jointVars[0]->varId()};
|
||||||
|
|
||||||
for (unsigned i = 1; i < jointVarIds.size(); i++) {
|
for (unsigned i = 1; i < jointVarIds.size(); i++) {
|
||||||
mrn = bayesNet_->getMinimalRequesiteNetwork (jointVarIds[i]);
|
assert (jointVars[i]->hasEvidence() == false);
|
||||||
ParamSet newBeliefs;
|
VarIds reqVars = {jointVarIds[i]};
|
||||||
vector<DConf> confs =
|
reqVars.insert (reqVars.end(), observedVids.begin(), observedVids.end());
|
||||||
Util::getDomainConfigurations (observedVars);
|
mrn = bayesNet_->getMinimalRequesiteNetwork (reqVars);
|
||||||
for (unsigned j = 0; j < confs.size(); j++) {
|
Params newBeliefs;
|
||||||
for (unsigned k = 0; k < observedVars.size(); k++) {
|
VarNodes observedVars;
|
||||||
if (!observedVars[k]->hasEvidence()) {
|
for (unsigned j = 0; j < observedVids.size(); j++) {
|
||||||
BayesNode* node = mrn->getBayesNode (observedVars[k]->varId());
|
observedVars.push_back (mrn->getBayesNode (observedVids[j]));
|
||||||
if (node) {
|
}
|
||||||
node->setEvidence (confs[j][k]);
|
StatesIndexer idx (observedVars, false);
|
||||||
}
|
while (idx.valid()) {
|
||||||
}
|
for (unsigned j = 0; j < observedVars.size(); j++) {
|
||||||
|
observedVars[j]->setEvidence (idx[j]);
|
||||||
}
|
}
|
||||||
BnBpSolver solver (*mrn);
|
BnBpSolver solver (*mrn);
|
||||||
solver.runSolver();
|
solver.runSolver();
|
||||||
ParamSet beliefs = solver.getPosterioriOf (jointVarIds[i]);
|
Params beliefs = solver.getPosterioriOf (jointVarIds[i]);
|
||||||
for (unsigned k = 0; k < beliefs.size(); k++) {
|
for (unsigned k = 0; k < beliefs.size(); k++) {
|
||||||
newBeliefs.push_back (beliefs[k]);
|
newBeliefs.push_back (beliefs[k]);
|
||||||
}
|
}
|
||||||
|
++ idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
int count = -1;
|
int count = -1;
|
||||||
@ -796,7 +703,7 @@ BnBpSolver::getJointByChainRule (const VarIdSet& jointVarIds) const
|
|||||||
newBeliefs[j] *= prevBeliefs[count];
|
newBeliefs[j] *= prevBeliefs[count];
|
||||||
}
|
}
|
||||||
prevBeliefs = newBeliefs;
|
prevBeliefs = newBeliefs;
|
||||||
observedVars.push_back (jointVars[i]);
|
observedVids.push_back (jointVars[i]->varId());
|
||||||
delete mrn;
|
delete mrn;
|
||||||
}
|
}
|
||||||
return prevBeliefs;
|
return prevBeliefs;
|
||||||
@ -817,9 +724,9 @@ BnBpSolver::printPiLambdaValues (const BayesNode* var) const
|
|||||||
cout << "--------------------------------" ;
|
cout << "--------------------------------" ;
|
||||||
cout << endl;
|
cout << endl;
|
||||||
const States& states = var->states();
|
const States& states = var->states();
|
||||||
const ParamSet& piVals = ninf(var)->getPiValues();
|
const Params& piVals = ninf(var)->getPiValues();
|
||||||
const ParamSet& ldVals = ninf(var)->getLambdaValues();
|
const Params& ldVals = ninf(var)->getLambdaValues();
|
||||||
const ParamSet& beliefs = ninf(var)->getBeliefs();
|
const Params& beliefs = ninf(var)->getBeliefs();
|
||||||
for (unsigned xi = 0; xi < var->nrStates(); xi++) {
|
for (unsigned xi = 0; xi < var->nrStates(); xi++) {
|
||||||
cout << setw (10) << states[xi];
|
cout << setw (10) << states[xi];
|
||||||
cout << setw (19) << piVals[xi];
|
cout << setw (19) << piVals[xi];
|
||||||
@ -847,33 +754,27 @@ BnBpSolver::printAllMessageStatus (void) const
|
|||||||
BpNodeInfo::BpNodeInfo (BayesNode* node)
|
BpNodeInfo::BpNodeInfo (BayesNode* node)
|
||||||
{
|
{
|
||||||
node_ = node;
|
node_ = node;
|
||||||
piValsCalc_ = false;
|
|
||||||
ldValsCalc_ = false;
|
|
||||||
nPiMsgsRcv_ = 0;
|
|
||||||
nLdMsgsRcv_ = 0;
|
|
||||||
piVals_.resize (node->nrStates(), Util::one());
|
piVals_.resize (node->nrStates(), Util::one());
|
||||||
ldVals_.resize (node->nrStates(), Util::one());
|
ldVals_.resize (node->nrStates(), Util::one());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ParamSet
|
Params
|
||||||
BpNodeInfo::getBeliefs (void) const
|
BpNodeInfo::getBeliefs (void) const
|
||||||
{
|
{
|
||||||
double sum = 0.0;
|
double sum = 0.0;
|
||||||
ParamSet beliefs (node_->nrStates());
|
Params beliefs (node_->nrStates());
|
||||||
switch (NSPACE) {
|
if (Globals::logDomain) {
|
||||||
case NumberSpace::NORMAL:
|
for (unsigned xi = 0; xi < node_->nrStates(); xi++) {
|
||||||
for (unsigned xi = 0; xi < node_->nrStates(); xi++) {
|
beliefs[xi] = exp (piVals_[xi] + ldVals_[xi]);
|
||||||
beliefs[xi] = piVals_[xi] * ldVals_[xi];
|
sum += beliefs[xi];
|
||||||
sum += beliefs[xi];
|
}
|
||||||
}
|
} else {
|
||||||
break;
|
for (unsigned xi = 0; xi < node_->nrStates(); xi++) {
|
||||||
case NumberSpace::LOGARITHM:
|
beliefs[xi] = piVals_[xi] * ldVals_[xi];
|
||||||
for (unsigned xi = 0; xi < node_->nrStates(); xi++) {
|
sum += beliefs[xi];
|
||||||
beliefs[xi] = exp (piVals_[xi] + ldVals_[xi]);
|
}
|
||||||
sum += beliefs[xi];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
assert (sum);
|
assert (sum);
|
||||||
for (unsigned xi = 0; xi < node_->nrStates(); xi++) {
|
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
|
bool
|
||||||
BpNodeInfo::receivedBottomInfluence (void) const
|
BpNodeInfo::receivedBottomInfluence (void) const
|
||||||
{
|
{
|
||||||
|
@ -6,7 +6,8 @@
|
|||||||
|
|
||||||
#include "Solver.h"
|
#include "Solver.h"
|
||||||
#include "BayesNet.h"
|
#include "BayesNet.h"
|
||||||
#include "Shared.h"
|
#include "Horus.h"
|
||||||
|
#include "Util.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
@ -16,7 +17,6 @@ static const string PI_SYMBOL = "pi" ;
|
|||||||
static const string LD_SYMBOL = "ld" ;
|
static const string LD_SYMBOL = "ld" ;
|
||||||
|
|
||||||
enum LinkOrientation {UP, DOWN};
|
enum LinkOrientation {UP, DOWN};
|
||||||
enum JointCalcType {CHAIN_RULE, JUNCTION_NODE};
|
|
||||||
|
|
||||||
class BpLink
|
class BpLink
|
||||||
{
|
{
|
||||||
@ -27,11 +27,11 @@ class BpLink
|
|||||||
destin_ = d;
|
destin_ = d;
|
||||||
orientation_ = o;
|
orientation_ = o;
|
||||||
if (orientation_ == LinkOrientation::DOWN) {
|
if (orientation_ == LinkOrientation::DOWN) {
|
||||||
v1_.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()));
|
v2_.resize (s->nrStates(), Util::tl (1.0 / s->nrStates()));
|
||||||
} else {
|
} else {
|
||||||
v1_.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()));
|
v2_.resize (d->nrStates(), Util::tl (1.0 / d->nrStates()));
|
||||||
}
|
}
|
||||||
currMsg_ = &v1_;
|
currMsg_ = &v1_;
|
||||||
nextMsg_ = &v2_;
|
nextMsg_ = &v2_;
|
||||||
@ -78,8 +78,8 @@ class BpLink
|
|||||||
BayesNode* getSource (void) const { return source_; }
|
BayesNode* getSource (void) const { return source_; }
|
||||||
BayesNode* getDestination (void) const { return destin_; }
|
BayesNode* getDestination (void) const { return destin_; }
|
||||||
LinkOrientation getOrientation (void) const { return orientation_; }
|
LinkOrientation getOrientation (void) const { return orientation_; }
|
||||||
const ParamSet& getMessage (void) const { return *currMsg_; }
|
const Params& getMessage (void) const { return *currMsg_; }
|
||||||
ParamSet& getNextMessage (void) { return *nextMsg_; }
|
Params& getNextMessage (void) { return *nextMsg_; }
|
||||||
bool messageWasSended (void) const { return msgSended_; }
|
bool messageWasSended (void) const { return msgSended_; }
|
||||||
double getResidual (void) const { return residual_; }
|
double getResidual (void) const { return residual_; }
|
||||||
void clearResidual (void) { residual_ = 0;}
|
void clearResidual (void) { residual_ = 0;}
|
||||||
@ -88,10 +88,10 @@ class BpLink
|
|||||||
BayesNode* source_;
|
BayesNode* source_;
|
||||||
BayesNode* destin_;
|
BayesNode* destin_;
|
||||||
LinkOrientation orientation_;
|
LinkOrientation orientation_;
|
||||||
ParamSet v1_;
|
Params v1_;
|
||||||
ParamSet v2_;
|
Params v2_;
|
||||||
ParamSet* currMsg_;
|
Params* currMsg_;
|
||||||
ParamSet* nextMsg_;
|
Params* nextMsg_;
|
||||||
bool msgSended_;
|
bool msgSended_;
|
||||||
double residual_;
|
double residual_;
|
||||||
};
|
};
|
||||||
@ -105,22 +105,11 @@ class BpNodeInfo
|
|||||||
public:
|
public:
|
||||||
BpNodeInfo (BayesNode*);
|
BpNodeInfo (BayesNode*);
|
||||||
|
|
||||||
ParamSet getBeliefs (void) const;
|
Params getBeliefs (void) const;
|
||||||
bool receivedBottomInfluence (void) const;
|
bool receivedBottomInfluence (void) const;
|
||||||
|
|
||||||
ParamSet& getPiValues (void) { return piVals_; }
|
Params& getPiValues (void) { return piVals_; }
|
||||||
ParamSet& getLambdaValues (void) { return ldVals_; }
|
Params& 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;
|
|
||||||
|
|
||||||
const BpLinkSet& getIncomingParentLinks (void) { return inParentLinks_; }
|
const BpLinkSet& getIncomingParentLinks (void) { return inParentLinks_; }
|
||||||
const BpLinkSet& getIncomingChildLinks (void) { return inChildLinks_; }
|
const BpLinkSet& getIncomingChildLinks (void) { return inChildLinks_; }
|
||||||
@ -135,17 +124,13 @@ class BpNodeInfo
|
|||||||
private:
|
private:
|
||||||
DISALLOW_COPY_AND_ASSIGN (BpNodeInfo);
|
DISALLOW_COPY_AND_ASSIGN (BpNodeInfo);
|
||||||
|
|
||||||
ParamSet piVals_; // pi values
|
const BayesNode* node_;
|
||||||
ParamSet ldVals_; // lambda values
|
Params piVals_; // pi values
|
||||||
unsigned nPiMsgsRcv_;
|
Params ldVals_; // lambda values
|
||||||
unsigned nLdMsgsRcv_;
|
|
||||||
bool piValsCalc_;
|
|
||||||
bool ldValsCalc_;
|
|
||||||
BpLinkSet inParentLinks_;
|
BpLinkSet inParentLinks_;
|
||||||
BpLinkSet inChildLinks_;
|
BpLinkSet inChildLinks_;
|
||||||
BpLinkSet outParentLinks_;
|
BpLinkSet outParentLinks_;
|
||||||
BpLinkSet outChildLinks_;
|
BpLinkSet outChildLinks_;
|
||||||
const BayesNode* node_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -157,15 +142,14 @@ class BnBpSolver : public Solver
|
|||||||
~BnBpSolver (void);
|
~BnBpSolver (void);
|
||||||
|
|
||||||
void runSolver (void);
|
void runSolver (void);
|
||||||
ParamSet getPosterioriOf (VarId);
|
Params getPosterioriOf (VarId);
|
||||||
ParamSet getJointDistributionOf (const VarIdSet&);
|
Params getJointDistributionOf (const VarIds&);
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DISALLOW_COPY_AND_ASSIGN (BnBpSolver);
|
DISALLOW_COPY_AND_ASSIGN (BnBpSolver);
|
||||||
|
|
||||||
void initializeSolver (void);
|
void initializeSolver (void);
|
||||||
void runPolyTreeSolver (void);
|
|
||||||
void runLoopySolver (void);
|
void runLoopySolver (void);
|
||||||
void maxResidualSchedule (void);
|
void maxResidualSchedule (void);
|
||||||
bool converged (void) const;
|
bool converged (void) const;
|
||||||
@ -173,8 +157,8 @@ class BnBpSolver : public Solver
|
|||||||
void updateLambdaValues (BayesNode*);
|
void updateLambdaValues (BayesNode*);
|
||||||
void calculateLambdaMessage (BpLink*);
|
void calculateLambdaMessage (BpLink*);
|
||||||
void calculatePiMessage (BpLink*);
|
void calculatePiMessage (BpLink*);
|
||||||
ParamSet getJointByJunctionNode (const VarIdSet&);
|
Params getJointByJunctionNode (const VarIds&);
|
||||||
ParamSet getJointByChainRule (const VarIdSet&) const;
|
Params getJointByConditioning (const VarIds&) const;
|
||||||
void printPiLambdaValues (const BayesNode*) const;
|
void printPiLambdaValues (const BayesNode*) const;
|
||||||
void printAllMessageStatus (void) const;
|
void printAllMessageStatus (void) const;
|
||||||
|
|
||||||
@ -240,7 +224,6 @@ class BnBpSolver : public Solver
|
|||||||
vector<BpLink*> links_;
|
vector<BpLink*> links_;
|
||||||
vector<BpNodeInfo*> nodesI_;
|
vector<BpNodeInfo*> nodesI_;
|
||||||
unsigned nIters_;
|
unsigned nIters_;
|
||||||
JointCalcType jointCalcType_;
|
|
||||||
|
|
||||||
struct compare
|
struct compare
|
||||||
{
|
{
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
#include "Distribution.h"
|
#include "Distribution.h"
|
||||||
|
|
||||||
|
|
||||||
bool CFactorGraph::checkForIdenticalFactors_ = true;
|
bool CFactorGraph::checkForIdenticalFactors = true;
|
||||||
|
|
||||||
CFactorGraph::CFactorGraph (const FactorGraph& fg)
|
CFactorGraph::CFactorGraph (const FactorGraph& fg)
|
||||||
{
|
{
|
||||||
@ -38,8 +38,8 @@ CFactorGraph::~CFactorGraph (void)
|
|||||||
for (unsigned i = 0; i < varClusters_.size(); i++) {
|
for (unsigned i = 0; i < varClusters_.size(); i++) {
|
||||||
delete varClusters_[i];
|
delete varClusters_[i];
|
||||||
}
|
}
|
||||||
for (unsigned i = 0; i < factorClusters_.size(); i++) {
|
for (unsigned i = 0; i < facClusters_.size(); i++) {
|
||||||
delete factorClusters_[i];
|
delete facClusters_[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,33 +72,17 @@ CFactorGraph::setInitialColors (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
const FgFacSet& facNodes = groundFg_->getFactorNodes();
|
const FgFacSet& facNodes = groundFg_->getFactorNodes();
|
||||||
if (checkForIdenticalFactors_) {
|
if (checkForIdenticalFactors) {
|
||||||
for (unsigned i = 0; i < facNodes.size() - 1; i++) {
|
|
||||||
// facNodes[i]->factor()->orderFactorVariables();
|
|
||||||
// FIXME
|
|
||||||
}
|
|
||||||
for (unsigned i = 0, s = facNodes.size(); i < s; i++) {
|
for (unsigned i = 0, s = facNodes.size(); i < s; i++) {
|
||||||
Distribution* dist1 = facNodes[i]->getDistribution();
|
Distribution* dist1 = facNodes[i]->getDistribution();
|
||||||
for (unsigned j = 0; j < i; j++) {
|
for (unsigned j = 0; j < i; j++) {
|
||||||
Distribution* dist2 = facNodes[j]->getDistribution();
|
Distribution* dist2 = facNodes[j]->getDistribution();
|
||||||
if (dist1 != dist2 && dist1->params == dist2->params) {
|
if (dist1 != dist2 && dist1->params == dist2->params) {
|
||||||
facNodes[i]->factor()->setDistribution (dist2);
|
if (facNodes[i]->factor()->getRanges() ==
|
||||||
// delete dist2;
|
facNodes[j]->factor()->getRanges()) {
|
||||||
break;
|
facNodes[i]->factor()->setDistribution (dist2);
|
||||||
}
|
|
||||||
/*
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -194,7 +178,7 @@ CFactorGraph::createClusters (const VarSignMap& varGroups,
|
|||||||
varClusters_.push_back (vc);
|
varClusters_.push_back (vc);
|
||||||
}
|
}
|
||||||
|
|
||||||
factorClusters_.reserve (factorGroups.size());
|
facClusters_.reserve (factorGroups.size());
|
||||||
for (FacSignMap::const_iterator it = factorGroups.begin();
|
for (FacSignMap::const_iterator it = factorGroups.begin();
|
||||||
it != factorGroups.end(); it++) {
|
it != factorGroups.end(); it++) {
|
||||||
FgFacNode* groupFactor = it->second[0];
|
FgFacNode* groupFactor = it->second[0];
|
||||||
@ -205,7 +189,7 @@ CFactorGraph::createClusters (const VarSignMap& varGroups,
|
|||||||
VarId vid = neighs[i]->varId();
|
VarId vid = neighs[i]->varId();
|
||||||
varClusters.push_back (vid2VarCluster_.find (vid)->second);
|
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++) {
|
for (unsigned i = 0; i < neighs.size(); i++) {
|
||||||
*it = getColor (neighs[i]);
|
*it = getColor (neighs[i]);
|
||||||
it ++;
|
it ++;
|
||||||
*it = neighs[i]->factor()->getPositionOf (varNode->varId());
|
*it = neighs[i]->factor()->indexOf (varNode->varId());
|
||||||
it ++;
|
it ++;
|
||||||
}
|
}
|
||||||
*it = getColor (varNode);
|
*it = getColor (varNode);
|
||||||
@ -256,8 +240,8 @@ CFactorGraph::getCompressedFactorGraph (void)
|
|||||||
fg->addVariable (newVar);
|
fg->addVariable (newVar);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned i = 0; i < factorClusters_.size(); i++) {
|
for (unsigned i = 0; i < facClusters_.size(); i++) {
|
||||||
const VarClusterSet& myVarClusters = factorClusters_[i]->getVarClusters();
|
const VarClusterSet& myVarClusters = facClusters_[i]->getVarClusters();
|
||||||
VarNodes myGroundVars;
|
VarNodes myGroundVars;
|
||||||
myGroundVars.reserve (myVarClusters.size());
|
myGroundVars.reserve (myVarClusters.size());
|
||||||
for (unsigned j = 0; j < myVarClusters.size(); j++) {
|
for (unsigned j = 0; j < myVarClusters.size(); j++) {
|
||||||
@ -265,9 +249,9 @@ CFactorGraph::getCompressedFactorGraph (void)
|
|||||||
myGroundVars.push_back (v);
|
myGroundVars.push_back (v);
|
||||||
}
|
}
|
||||||
Factor* newFactor = new Factor (myGroundVars,
|
Factor* newFactor = new Factor (myGroundVars,
|
||||||
factorClusters_[i]->getGroundFactors()[0]->getDistribution());
|
facClusters_[i]->getGroundFactors()[0]->getDistribution());
|
||||||
FgFacNode* fn = new FgFacNode (newFactor);
|
FgFacNode* fn = new FgFacNode (newFactor);
|
||||||
factorClusters_[i]->setRepresentativeFactor (fn);
|
facClusters_[i]->setRepresentativeFactor (fn);
|
||||||
fg->addFactor (fn);
|
fg->addFactor (fn);
|
||||||
for (unsigned j = 0; j < myGroundVars.size(); j++) {
|
for (unsigned j = 0; j < myGroundVars.size(); j++) {
|
||||||
fg->addEdge (fn, static_cast<FgVarNode*> (myGroundVars[j]));
|
fg->addEdge (fn, static_cast<FgVarNode*> (myGroundVars[j]));
|
||||||
@ -280,14 +264,15 @@ CFactorGraph::getCompressedFactorGraph (void)
|
|||||||
|
|
||||||
|
|
||||||
unsigned
|
unsigned
|
||||||
CFactorGraph::getGroundEdgeCount (const FacCluster* fc,
|
CFactorGraph::getGroundEdgeCount (
|
||||||
const VarCluster* vc) const
|
const FacCluster* fc,
|
||||||
|
const VarCluster* vc) const
|
||||||
{
|
{
|
||||||
const FgFacSet& clusterGroundFactors = fc->getGroundFactors();
|
const FgFacSet& clusterGroundFactors = fc->getGroundFactors();
|
||||||
FgVarNode* varNode = vc->getGroundFgVarNodes()[0];
|
FgVarNode* varNode = vc->getGroundFgVarNodes()[0];
|
||||||
unsigned count = 0;
|
unsigned count = 0;
|
||||||
for (unsigned i = 0; i < clusterGroundFactors.size(); i++) {
|
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 ++;
|
count ++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -296,7 +281,7 @@ CFactorGraph::getGroundEdgeCount (const FacCluster* fc,
|
|||||||
// FgVarNode* var = vc->getGroundFgVarNodes()[i];
|
// FgVarNode* var = vc->getGroundFgVarNodes()[i];
|
||||||
// unsigned count2 = 0;
|
// unsigned count2 = 0;
|
||||||
// for (unsigned i = 0; i < clusterGroundFactors.size(); i++) {
|
// for (unsigned i = 0; i < clusterGroundFactors.size(); i++) {
|
||||||
// if (clusterGroundFactors[i]->getPositionOf (var) != -1) {
|
// if (clusterGroundFactors[i]->getPosition (var) != -1) {
|
||||||
// count2 ++;
|
// count2 ++;
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
#include "FactorGraph.h"
|
#include "FactorGraph.h"
|
||||||
#include "Factor.h"
|
#include "Factor.h"
|
||||||
#include "Shared.h"
|
#include "Horus.h"
|
||||||
|
|
||||||
class VarCluster;
|
class VarCluster;
|
||||||
class FacCluster;
|
class FacCluster;
|
||||||
@ -18,15 +18,16 @@ class SignatureHash;
|
|||||||
typedef long Color;
|
typedef long Color;
|
||||||
typedef unordered_map<unsigned, vector<Color> > VarColorMap;
|
typedef unordered_map<unsigned, vector<Color> > VarColorMap;
|
||||||
typedef unordered_map<const Distribution*, Color> DistColorMap;
|
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<VarCluster*> VarClusterSet;
|
||||||
typedef vector<FacCluster*> FacClusterSet;
|
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;
|
typedef unordered_map<Signature, FgFacSet, SignatureHash> FacSignMap;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct Signature {
|
struct Signature
|
||||||
|
{
|
||||||
Signature (unsigned size)
|
Signature (unsigned size)
|
||||||
{
|
{
|
||||||
colors.resize (size);
|
colors.resize (size);
|
||||||
@ -90,12 +91,12 @@ class VarCluster
|
|||||||
|
|
||||||
void addFacCluster (FacCluster* fc)
|
void addFacCluster (FacCluster* fc)
|
||||||
{
|
{
|
||||||
factorClusters_.push_back (fc);
|
facClusters_.push_back (fc);
|
||||||
}
|
}
|
||||||
|
|
||||||
const FacClusterSet& getFacClusters (void) const
|
const FacClusterSet& getFacClusters (void) const
|
||||||
{
|
{
|
||||||
return factorClusters_;
|
return facClusters_;
|
||||||
}
|
}
|
||||||
|
|
||||||
FgVarNode* getRepresentativeVariable (void) const { return representVar_; }
|
FgVarNode* getRepresentativeVariable (void) const { return representVar_; }
|
||||||
@ -103,9 +104,9 @@ class VarCluster
|
|||||||
const FgVarSet& getGroundFgVarNodes (void) const { return groundVars_; }
|
const FgVarSet& getGroundFgVarNodes (void) const { return groundVars_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FgVarSet groundVars_;
|
FgVarSet groundVars_;
|
||||||
FacClusterSet factorClusters_;
|
FacClusterSet facClusters_;
|
||||||
FgVarNode* representVar_;
|
FgVarNode* representVar_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -151,9 +152,9 @@ class FacCluster
|
|||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FgFacSet groundFactors_;
|
FgFacSet groundFactors_;
|
||||||
VarClusterSet varClusters_;
|
VarClusterSet varClusters_;
|
||||||
FgFacNode* representFactor_;
|
FgFacNode* representFactor_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -172,18 +173,10 @@ class CFactorGraph
|
|||||||
return vc->getRepresentativeVariable();
|
return vc->getRepresentativeVariable();
|
||||||
}
|
}
|
||||||
|
|
||||||
const VarClusterSet& getVariableClusters (void) { return varClusters_; }
|
const VarClusterSet& getVarClusters (void) { return varClusters_; }
|
||||||
const FacClusterSet& getFacClusters (void) { return factorClusters_; }
|
const FacClusterSet& getFacClusters (void) { return facClusters_; }
|
||||||
|
|
||||||
static void enableCheckForIdenticalFactors (void)
|
static bool checkForIdenticalFactors;
|
||||||
{
|
|
||||||
checkForIdenticalFactors_ = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void disableCheckForIdenticalFactors (void)
|
|
||||||
{
|
|
||||||
checkForIdenticalFactors_ = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setInitialColors (void);
|
void setInitialColors (void);
|
||||||
@ -227,10 +220,9 @@ class CFactorGraph
|
|||||||
vector<Signature> varSignatures_;
|
vector<Signature> varSignatures_;
|
||||||
vector<Signature> factorSignatures_;
|
vector<Signature> factorSignatures_;
|
||||||
VarClusterSet varClusters_;
|
VarClusterSet varClusters_;
|
||||||
FacClusterSet factorClusters_;
|
FacClusterSet facClusters_;
|
||||||
VarId2VarCluster vid2VarCluster_;
|
VarId2VarCluster vid2VarCluster_;
|
||||||
const FactorGraph* groundFg_;
|
const FactorGraph* groundFg_;
|
||||||
bool static checkForIdenticalFactors_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // HORUS_CFACTORGRAPH_H
|
#endif // HORUS_CFACTORGRAPH_H
|
||||||
|
@ -13,32 +13,31 @@ CbpSolver::~CbpSolver (void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
ParamSet
|
Params
|
||||||
CbpSolver::getPosterioriOf (VarId vid)
|
CbpSolver::getPosterioriOf (VarId vid)
|
||||||
{
|
{
|
||||||
|
assert (lfg_->getEquivalentVariable (vid));
|
||||||
FgVarNode* var = lfg_->getEquivalentVariable (vid);
|
FgVarNode* var = lfg_->getEquivalentVariable (vid);
|
||||||
ParamSet probs;
|
Params probs;
|
||||||
if (var->hasEvidence()) {
|
if (var->hasEvidence()) {
|
||||||
probs.resize (var->nrStates(), Util::noEvidence());
|
probs.resize (var->nrStates(), Util::noEvidence());
|
||||||
probs[var->getEvidence()] = Util::withEvidence();
|
probs[var->getEvidence()] = Util::withEvidence();
|
||||||
} else {
|
} else {
|
||||||
probs.resize (var->nrStates(), Util::multIdenty());
|
probs.resize (var->nrStates(), Util::multIdenty());
|
||||||
const SpLinkSet& links = ninf(var)->getLinks();
|
const SpLinkSet& links = ninf(var)->getLinks();
|
||||||
switch (NSPACE) {
|
if (Globals::logDomain) {
|
||||||
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:
|
|
||||||
for (unsigned i = 0; i < links.size(); i++) {
|
for (unsigned i = 0; i < links.size(); i++) {
|
||||||
CbpSolverLink* l = static_cast<CbpSolverLink*> (links[i]);
|
CbpSolverLink* l = static_cast<CbpSolverLink*> (links[i]);
|
||||||
Util::add (probs, l->getPoweredMessage());
|
Util::add (probs, l->getPoweredMessage());
|
||||||
}
|
}
|
||||||
Util::normalize (probs);
|
Util::normalize (probs);
|
||||||
Util::fromLog (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;
|
return probs;
|
||||||
@ -46,26 +45,19 @@ CbpSolver::getPosterioriOf (VarId vid)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
ParamSet
|
Params
|
||||||
CbpSolver::getJointDistributionOf (const VarIdSet& jointVarIds)
|
CbpSolver::getJointDistributionOf (const VarIds& jointVarIds)
|
||||||
{
|
{
|
||||||
unsigned msgSize = 1;
|
VarIds eqVarIds;
|
||||||
vector<unsigned> dsizes (jointVarIds.size());
|
|
||||||
for (unsigned i = 0; i < jointVarIds.size(); i++) {
|
for (unsigned i = 0; i < jointVarIds.size(); i++) {
|
||||||
dsizes[i] = lfg_->getEquivalentVariable (jointVarIds[i])->nrStates();
|
eqVarIds.push_back (lfg_->getEquivalentVariable (jointVarIds[i])->varId());
|
||||||
msgSize *= dsizes[i];
|
|
||||||
}
|
}
|
||||||
unsigned reps = 1;
|
return FgBpSolver::getJointDistributionOf (eqVarIds);
|
||||||
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
|
void
|
||||||
CbpSolver::initializeSolver (void)
|
CbpSolver::initializeSolver (void)
|
||||||
{
|
{
|
||||||
@ -119,7 +111,6 @@ CbpSolver::createLinks (void)
|
|||||||
vcs[j]->getRepresentativeVariable(), c));
|
vcs[j]->getRepresentativeVariable(), c));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -197,10 +188,10 @@ CbpSolver::maxResidualSchedule (void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
ParamSet
|
Params
|
||||||
CbpSolver::getVar2FactorMsg (const SpLink* link) const
|
CbpSolver::getVar2FactorMsg (const SpLink* link) const
|
||||||
{
|
{
|
||||||
ParamSet msg;
|
Params msg;
|
||||||
const FgVarNode* src = link->getVariable();
|
const FgVarNode* src = link->getVariable();
|
||||||
const FgFacNode* dst = link->getFactor();
|
const FgFacNode* dst = link->getFactor();
|
||||||
const CbpSolverLink* l = static_cast<const CbpSolverLink*> (link);
|
const CbpSolverLink* l = static_cast<const CbpSolverLink*> (link);
|
||||||
@ -216,27 +207,26 @@ CbpSolver::getVar2FactorMsg (const SpLink* link) const
|
|||||||
cout << " " << "init: " << Util::parametersToString (msg) << endl;
|
cout << " " << "init: " << Util::parametersToString (msg) << endl;
|
||||||
}
|
}
|
||||||
const SpLinkSet& links = ninf(src)->getLinks();
|
const SpLinkSet& links = ninf(src)->getLinks();
|
||||||
switch (NSPACE) {
|
if (Globals::logDomain) {
|
||||||
case NumberSpace::NORMAL:
|
for (unsigned i = 0; i < links.size(); i++) {
|
||||||
for (unsigned i = 0; i < links.size(); i++) {
|
if (links[i]->getFactor() != dst) {
|
||||||
if (links[i]->getFactor() != dst) {
|
CbpSolverLink* l = static_cast<CbpSolverLink*> (links[i]);
|
||||||
CbpSolverLink* l = static_cast<CbpSolverLink*> (links[i]);
|
Util::add (msg, l->getPoweredMessage());
|
||||||
Util::multiply (msg, l->getPoweredMessage());
|
}
|
||||||
if (DL >= 5) {
|
}
|
||||||
cout << " msg from " << l->getFactor()->getLabel() << ": " ;
|
} else {
|
||||||
cout << Util::parametersToString (l->getPoweredMessage()) << endl;
|
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());
|
||||||
break;
|
if (DL >= 5) {
|
||||||
case NumberSpace::LOGARITHM:
|
cout << " msg from " << l->getFactor()->getLabel() << ": " ;
|
||||||
for (unsigned i = 0; i < links.size(); i++) {
|
cout << Util::parametersToString (l->getPoweredMessage()) << endl;
|
||||||
if (links[i]->getFactor() != dst) {
|
|
||||||
CbpSolverLink* l = static_cast<CbpSolverLink*> (links[i]);
|
|
||||||
Util::add (msg, l->getPoweredMessage());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DL >= 5) {
|
if (DL >= 5) {
|
||||||
cout << " result = " << Util::parametersToString (msg) << endl;
|
cout << " result = " << Util::parametersToString (msg) << endl;
|
||||||
}
|
}
|
||||||
|
@ -23,11 +23,11 @@ class CbpSolverLink : public SpLink
|
|||||||
Util::pow (poweredMsg_, edgeCount_);
|
Util::pow (poweredMsg_, edgeCount_);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned getNumberOfEdges (void) const { return edgeCount_; }
|
unsigned getNumberOfEdges (void) const { return edgeCount_; }
|
||||||
const ParamSet& getPoweredMessage (void) const { return poweredMsg_; }
|
const Params& getPoweredMessage (void) const { return poweredMsg_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ParamSet poweredMsg_;
|
Params poweredMsg_;
|
||||||
unsigned edgeCount_;
|
unsigned edgeCount_;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -39,15 +39,15 @@ class CbpSolver : public FgBpSolver
|
|||||||
CbpSolver (FactorGraph& fg) : FgBpSolver (fg) { }
|
CbpSolver (FactorGraph& fg) : FgBpSolver (fg) { }
|
||||||
~CbpSolver (void);
|
~CbpSolver (void);
|
||||||
|
|
||||||
ParamSet getPosterioriOf (VarId);
|
Params getPosterioriOf (VarId);
|
||||||
ParamSet getJointDistributionOf (const VarIdSet&);
|
Params getJointDistributionOf (const VarIds&);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void initializeSolver (void);
|
void initializeSolver (void);
|
||||||
void createLinks (void);
|
void createLinks (void);
|
||||||
|
|
||||||
void maxResidualSchedule (void);
|
void maxResidualSchedule (void);
|
||||||
ParamSet getVar2FactorMsg (const SpLink*) const;
|
Params getVar2FactorMsg (const SpLink*) const;
|
||||||
void printLinkInformation (void) const;
|
void printLinkInformation (void) const;
|
||||||
|
|
||||||
|
|
||||||
|
1169
packages/CLPBN/clpbn/bp/ConstraintTree.cpp
Normal file
1169
packages/CLPBN/clpbn/bp/ConstraintTree.cpp
Normal file
File diff suppressed because it is too large
Load Diff
189
packages/CLPBN/clpbn/bp/ConstraintTree.h
Normal file
189
packages/CLPBN/clpbn/bp/ConstraintTree.h
Normal file
@ -0,0 +1,189 @@
|
|||||||
|
#ifndef HORUS_CONSTRAINTTREE_H
|
||||||
|
#define HORUS_CONSTRAINTTREE_H
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
#include "TinySet.h"
|
||||||
|
#include "LiftedUtils.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
|
||||||
|
class CTNode;
|
||||||
|
typedef vector<CTNode*> CTNodes;
|
||||||
|
|
||||||
|
class ConstraintTree;
|
||||||
|
typedef vector<ConstraintTree*> ConstraintTrees;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class CTNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CTNode (const CTNode& n) : symbol_(n.symbol()), level_(n.level()) { }
|
||||||
|
|
||||||
|
CTNode (Symbol s, unsigned l) : symbol_(s) , level_(l) { }
|
||||||
|
|
||||||
|
unsigned level (void) const { return level_; }
|
||||||
|
|
||||||
|
void setLevel (unsigned level) { level_ = level; }
|
||||||
|
|
||||||
|
Symbol symbol (void) const { return symbol_; }
|
||||||
|
|
||||||
|
void setSymbol (const Symbol s) { symbol_ = s; }
|
||||||
|
|
||||||
|
CTNodes& childs (void) { return childs_; }
|
||||||
|
|
||||||
|
const CTNodes& childs (void) const { return childs_; }
|
||||||
|
|
||||||
|
unsigned nrChilds (void) const { return childs_.size(); }
|
||||||
|
|
||||||
|
bool isRoot (void) const { return level_ == 0; }
|
||||||
|
|
||||||
|
bool isLeaf (void) const { return childs_.empty(); }
|
||||||
|
|
||||||
|
void addChild (CTNode*, bool = true);
|
||||||
|
void removeChild (CTNode*);
|
||||||
|
SymbolSet childSymbols (void) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void updateChildLevels (CTNode*, unsigned);
|
||||||
|
|
||||||
|
Symbol symbol_;
|
||||||
|
CTNodes childs_;
|
||||||
|
unsigned level_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ostream& operator<< (ostream &out, const CTNode&);
|
||||||
|
|
||||||
|
|
||||||
|
class ConstraintTree
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ConstraintTree (const LogVars&);
|
||||||
|
ConstraintTree (const LogVars&, const Tuples&);
|
||||||
|
ConstraintTree (const ConstraintTree&);
|
||||||
|
~ConstraintTree (void);
|
||||||
|
|
||||||
|
CTNode* root (void) const { return root_; }
|
||||||
|
|
||||||
|
bool empty (void) const { return root_->childs().empty(); }
|
||||||
|
|
||||||
|
const LogVars& logVars (void) const
|
||||||
|
{
|
||||||
|
assert (LogVarSet (logVars_) == logVarSet_);
|
||||||
|
return logVars_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const LogVarSet& logVarSet (void) const
|
||||||
|
{
|
||||||
|
assert (LogVarSet (logVars_) == logVarSet_);
|
||||||
|
return logVarSet_;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned nrLogVars (void) const
|
||||||
|
{
|
||||||
|
return logVars_.size();
|
||||||
|
assert (LogVarSet (logVars_) == logVarSet_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void addTuple (const Tuple&);
|
||||||
|
bool containsTuple (const Tuple&);
|
||||||
|
void moveToTop (const LogVars&);
|
||||||
|
void moveToBottom (const LogVars&);
|
||||||
|
void join (ConstraintTree*, bool = false);
|
||||||
|
unsigned getLevel (LogVar) const;
|
||||||
|
void rename (LogVar, LogVar);
|
||||||
|
void applySubstitution (const Substitution&);
|
||||||
|
void project (const LogVarSet&);
|
||||||
|
void remove (const LogVarSet&);
|
||||||
|
bool isSingleton (LogVar);
|
||||||
|
LogVarSet singletons (void);
|
||||||
|
TupleSet tupleSet (unsigned = 0) const;
|
||||||
|
TupleSet tupleSet (const LogVars&);
|
||||||
|
unsigned size (void) const;
|
||||||
|
unsigned nrSymbols (LogVar);
|
||||||
|
void exportToGraphViz (const char*, bool = false) const;
|
||||||
|
bool isCountNormalized (const LogVarSet&);
|
||||||
|
unsigned getConditionalCount (const LogVarSet&);
|
||||||
|
TinySet<unsigned> getConditionalCounts (const LogVarSet&);
|
||||||
|
bool isCarteesianProduct (const LogVarSet&) const;
|
||||||
|
|
||||||
|
std::pair<ConstraintTree*, ConstraintTree*> split (
|
||||||
|
const Tuple&,
|
||||||
|
unsigned);
|
||||||
|
|
||||||
|
std::pair<ConstraintTree*, ConstraintTree*> split (
|
||||||
|
const ConstraintTree*,
|
||||||
|
unsigned) const;
|
||||||
|
|
||||||
|
ConstraintTrees countNormalize (const LogVarSet&);
|
||||||
|
|
||||||
|
ConstraintTrees jointCountNormalize (
|
||||||
|
ConstraintTree*,
|
||||||
|
ConstraintTree*,
|
||||||
|
LogVar,
|
||||||
|
LogVar,
|
||||||
|
LogVar);
|
||||||
|
|
||||||
|
static bool identical (
|
||||||
|
const ConstraintTree*,
|
||||||
|
const ConstraintTree*,
|
||||||
|
unsigned);
|
||||||
|
|
||||||
|
static bool overlap (
|
||||||
|
const ConstraintTree*,
|
||||||
|
const ConstraintTree*,
|
||||||
|
unsigned);
|
||||||
|
|
||||||
|
LogVars expand (LogVar);
|
||||||
|
ConstraintTrees ground (LogVar);
|
||||||
|
|
||||||
|
private:
|
||||||
|
unsigned countTuples (const CTNode*) const;
|
||||||
|
CTNodes getNodesBelow (CTNode*) const;
|
||||||
|
CTNodes getNodesAtLevel (unsigned) const;
|
||||||
|
void swapLogVar (LogVar);
|
||||||
|
bool join (CTNode*, const Tuple&, unsigned, CTNode*);
|
||||||
|
|
||||||
|
bool indenticalSubtrees (
|
||||||
|
const CTNode*,
|
||||||
|
const CTNode*,
|
||||||
|
bool) const;
|
||||||
|
|
||||||
|
void getTuples (
|
||||||
|
CTNode*,
|
||||||
|
Tuples,
|
||||||
|
unsigned,
|
||||||
|
Tuples&,
|
||||||
|
CTNodes&) const;
|
||||||
|
|
||||||
|
vector<std::pair<CTNode*, unsigned>> countNormalize (
|
||||||
|
const CTNode*,
|
||||||
|
unsigned);
|
||||||
|
|
||||||
|
static void split (
|
||||||
|
CTNode*,
|
||||||
|
CTNode*,
|
||||||
|
CTNodes&,
|
||||||
|
unsigned);
|
||||||
|
|
||||||
|
static bool overlap (const CTNode*, const CTNode*, unsigned);
|
||||||
|
static CTNode* copySubtree (const CTNode*);
|
||||||
|
static void deleteSubtree (CTNode*);
|
||||||
|
|
||||||
|
CTNode* root_;
|
||||||
|
LogVars logVars_;
|
||||||
|
LogVarSet logVarSet_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // HORUS_CONSTRAINTTREE_H
|
||||||
|
|
@ -1,38 +0,0 @@
|
|||||||
#include "CptEntry.h"
|
|
||||||
|
|
||||||
CptEntry::CptEntry (int cptIndex, vector<int> instantiations)
|
|
||||||
{
|
|
||||||
cptIndex_ = cptIndex;
|
|
||||||
instantiations_ = instantiations;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
CptEntry::getCptIndex (void) const
|
|
||||||
{
|
|
||||||
return cptIndex_;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
vector<int>
|
|
||||||
CptEntry::getDomainInstantiations (void) const
|
|
||||||
{
|
|
||||||
return instantiations_;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
|
||||||
CptEntry::matchConstraints (const vector<pair<int,int> >& constraints) const
|
|
||||||
{
|
|
||||||
for (unsigned int j = 0; j < constraints.size(); j++) {
|
|
||||||
int index = constraints[j].first;
|
|
||||||
if (instantiations_[index] != constraints[j].second) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
@ -1,43 +0,0 @@
|
|||||||
#ifndef HORUS_CPTENTRY_H
|
|
||||||
#define HORUS_CPTENTRY_H
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "Shared.h"
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
class CptEntry
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CptEntry (unsigned index, const DConf& conf)
|
|
||||||
{
|
|
||||||
index_ = index;
|
|
||||||
conf_ = conf;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned getParameterIndex (void) const { return index_; }
|
|
||||||
const DConf& getDomainConfiguration (void) const { return conf_; }
|
|
||||||
|
|
||||||
bool matchConstraints (const DConstraint& constr) const
|
|
||||||
{
|
|
||||||
return conf_[constr.first] == constr.second;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool matchConstraints (const vector<DConstraint>& constrs) const
|
|
||||||
{
|
|
||||||
for (unsigned j = 0; j < constrs.size(); j++) {
|
|
||||||
if (conf_[constrs[j].first] != constrs[j].second) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
unsigned index_;
|
|
||||||
DConf conf_;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // HORUS_CPTENTRY_H
|
|
||||||
|
|
@ -3,34 +3,39 @@
|
|||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "CptEntry.h"
|
#include "Horus.h"
|
||||||
#include "Shared.h"
|
|
||||||
|
//TODO die die die die die
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
|
||||||
struct Distribution
|
struct Distribution
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Distribution (unsigned id)
|
Distribution (int id)
|
||||||
|
{
|
||||||
|
this->id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
Distribution (const Params& params, int id = -1)
|
||||||
{
|
{
|
||||||
this->id = id;
|
this->id = id;
|
||||||
this->params = params;
|
this->params = params;
|
||||||
}
|
}
|
||||||
|
|
||||||
Distribution (const ParamSet& params, unsigned id = -1)
|
void updateParameters (const Params& params)
|
||||||
{
|
|
||||||
this->id = id;
|
|
||||||
this->params = params;
|
|
||||||
}
|
|
||||||
|
|
||||||
void updateParameters (const ParamSet& params)
|
|
||||||
{
|
{
|
||||||
this->params = params;
|
this->params = params;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned id;
|
bool shared (void)
|
||||||
ParamSet params;
|
{
|
||||||
vector<CptEntry> entries;
|
return id != -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int id;
|
||||||
|
Params params;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DISALLOW_COPY_AND_ASSIGN (Distribution);
|
DISALLOW_COPY_AND_ASSIGN (Distribution);
|
||||||
|
@ -65,7 +65,7 @@ void
|
|||||||
ElimGraph::addNode (EgNode* n)
|
ElimGraph::addNode (EgNode* n)
|
||||||
{
|
{
|
||||||
nodes_.push_back (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*
|
EgNode*
|
||||||
ElimGraph::getEgNode (VarId vid) const
|
ElimGraph::getEgNode (VarId vid) const
|
||||||
{
|
{
|
||||||
unordered_map<VarId,EgNode*>::const_iterator it = vid2nodes_.find (vid);
|
unordered_map<VarId,EgNode*>::const_iterator it =varMap_.find (vid);
|
||||||
if (it == vid2nodes_.end()) {
|
if (it ==varMap_.end()) {
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
return it->second;
|
return it->second;
|
||||||
@ -83,10 +83,10 @@ ElimGraph::getEgNode (VarId vid) const
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
VarIdSet
|
VarIds
|
||||||
ElimGraph::getEliminatingOrder (const VarIdSet& exclude)
|
ElimGraph::getEliminatingOrder (const VarIds& exclude)
|
||||||
{
|
{
|
||||||
VarIdSet elimOrder;
|
VarIds elimOrder;
|
||||||
marked_.resize (nodes_.size(), false);
|
marked_.resize (nodes_.size(), false);
|
||||||
|
|
||||||
for (unsigned i = 0; i < exclude.size(); i++) {
|
for (unsigned i = 0; i < exclude.size(); i++) {
|
||||||
@ -275,7 +275,7 @@ ElimGraph::printGraphicalModel (void) const
|
|||||||
void
|
void
|
||||||
ElimGraph::exportToGraphViz (const char* fileName,
|
ElimGraph::exportToGraphViz (const char* fileName,
|
||||||
bool showNeighborless,
|
bool showNeighborless,
|
||||||
const VarIdSet& highlightVarIds) const
|
const VarIds& highlightVarIds) const
|
||||||
{
|
{
|
||||||
ofstream out (fileName);
|
ofstream out (fileName);
|
||||||
if (!out.is_open()) {
|
if (!out.is_open()) {
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
#include "unordered_map"
|
#include "unordered_map"
|
||||||
|
|
||||||
#include "FactorGraph.h"
|
#include "FactorGraph.h"
|
||||||
#include "Shared.h"
|
#include "Horus.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
@ -45,10 +45,10 @@ class ElimGraph
|
|||||||
}
|
}
|
||||||
void addNode (EgNode*);
|
void addNode (EgNode*);
|
||||||
EgNode* getEgNode (VarId) const;
|
EgNode* getEgNode (VarId) const;
|
||||||
VarIdSet getEliminatingOrder (const VarIdSet&);
|
VarIds getEliminatingOrder (const VarIds&);
|
||||||
void printGraphicalModel (void) const;
|
void printGraphicalModel (void) const;
|
||||||
void exportToGraphViz (const char*, bool = true,
|
void exportToGraphViz (const char*, bool = true,
|
||||||
const VarIdSet& = VarIdSet()) const;
|
const VarIds& = VarIds()) const;
|
||||||
void setIndexes();
|
void setIndexes();
|
||||||
|
|
||||||
static void setEliminationHeuristic (ElimHeuristic h)
|
static void setEliminationHeuristic (ElimHeuristic h)
|
||||||
@ -68,7 +68,7 @@ class ElimGraph
|
|||||||
|
|
||||||
vector<EgNode*> nodes_;
|
vector<EgNode*> nodes_;
|
||||||
vector<bool> marked_;
|
vector<bool> marked_;
|
||||||
unordered_map<VarId,EgNode*> vid2nodes_;
|
unordered_map<VarId,EgNode*> varMap_;
|
||||||
static ElimHeuristic elimHeuristic_;
|
static ElimHeuristic elimHeuristic_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -7,7 +7,8 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
#include "Factor.h"
|
#include "Factor.h"
|
||||||
#include "StatesIndexer.h"
|
#include "Indexer.h"
|
||||||
|
#include "Util.h"
|
||||||
|
|
||||||
|
|
||||||
Factor::Factor (const Factor& g)
|
Factor::Factor (const Factor& g)
|
||||||
@ -21,7 +22,7 @@ Factor::Factor (VarId vid, unsigned nStates)
|
|||||||
{
|
{
|
||||||
varids_.push_back (vid);
|
varids_.push_back (vid);
|
||||||
ranges_.push_back (nStates);
|
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
|
// create a uniform distribution
|
||||||
double val = 1.0 / nParams;
|
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);
|
varids_.push_back (vid);
|
||||||
ranges_.push_back (nStates);
|
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++) {
|
for (unsigned i = 0; i < vars.size(); i++) {
|
||||||
varids_.push_back (vars[i]->varId());
|
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 Ranges& ranges,
|
||||||
const ParamSet& params)
|
const Params& params)
|
||||||
{
|
{
|
||||||
varids_ = vids;
|
varids_ = vids;
|
||||||
ranges_ = ranges;
|
ranges_ = ranges;
|
||||||
@ -83,11 +84,20 @@ Factor::Factor (const VarIdSet& vids,
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Factor::~Factor (void)
|
||||||
|
{
|
||||||
|
if (dist_->shared() == false) {
|
||||||
|
delete dist_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Factor::setParameters (const ParamSet& params)
|
Factor::setParameters (const Params& params)
|
||||||
{
|
{
|
||||||
assert (dist_->params.size() == params.size());
|
assert (dist_->params.size() == params.size());
|
||||||
dist_->updateParameters (params);
|
dist_->params = params;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -97,140 +107,159 @@ Factor::copyFromFactor (const Factor& g)
|
|||||||
{
|
{
|
||||||
varids_ = g.getVarIds();
|
varids_ = g.getVarIds();
|
||||||
ranges_ = g.getRanges();
|
ranges_ = g.getRanges();
|
||||||
dist_ = new Distribution (g.getDistribution()->params);
|
dist_ = new Distribution (g.getParameters());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Factor::multiplyByFactor (const Factor& g, const vector<CptEntry>* entries)
|
Factor::multiply (const Factor& g)
|
||||||
{
|
{
|
||||||
if (varids_.size() == 0) {
|
if (varids_.size() == 0) {
|
||||||
copyFromFactor (g);
|
copyFromFactor (g);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const VarIdSet& gvarids = g.getVarIds();
|
const VarIds& g_varids = g.getVarIds();
|
||||||
const Ranges& granges = g.getRanges();
|
const Ranges& g_ranges = g.getRanges();
|
||||||
const ParamSet& gparams = g.getParameters();
|
const Params& g_params = g.getParameters();
|
||||||
|
|
||||||
if (varids_ == gvarids) {
|
if (varids_ == g_varids) {
|
||||||
// optimization: if the factors contain the same set of variables,
|
// optimization: if the factors contain the same set of variables,
|
||||||
// we can do a 1 to 1 operation on the parameters
|
// we can do a 1 to 1 operation on the parameters
|
||||||
switch (NSPACE) {
|
if (Globals::logDomain) {
|
||||||
case NumberSpace::NORMAL:
|
Util::add (dist_->params, g_params);
|
||||||
Util::multiply (dist_->params, gparams);
|
} else {
|
||||||
break;
|
Util::multiply (dist_->params, g_params);
|
||||||
case NumberSpace::LOGARITHM:
|
|
||||||
Util::add (dist_->params, gparams);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
bool hasCommonVars = false;
|
bool sharedVars = false;
|
||||||
vector<unsigned> gvarpos;
|
vector<unsigned> gvarpos;
|
||||||
for (unsigned i = 0; i < gvarids.size(); i++) {
|
for (unsigned i = 0; i < g_varids.size(); i++) {
|
||||||
int pos = getPositionOf (gvarids[i]);
|
int idx = indexOf (g_varids[i]);
|
||||||
if (pos == -1) {
|
if (idx == -1) {
|
||||||
insertVariable (gvarids[i], granges[i]);
|
insertVariable (g_varids[i], g_ranges[i]);
|
||||||
gvarpos.push_back (varids_.size() - 1);
|
gvarpos.push_back (varids_.size() - 1);
|
||||||
} else {
|
} else {
|
||||||
hasCommonVars = true;
|
sharedVars = true;
|
||||||
gvarpos.push_back (pos);
|
gvarpos.push_back (idx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (hasCommonVars) {
|
if (sharedVars == false) {
|
||||||
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 {
|
|
||||||
// optimization: if the original factors doesn't have common variables,
|
// optimization: if the original factors doesn't have common variables,
|
||||||
// we don't need to marry the states of the common variables
|
// we don't need to marry the states of the common variables
|
||||||
unsigned count = 0;
|
unsigned count = 0;
|
||||||
for (unsigned i = 0; i < dist_->params.size(); i++) {
|
for (unsigned i = 0; i < dist_->params.size(); i++) {
|
||||||
switch (NSPACE) {
|
if (Globals::logDomain) {
|
||||||
case NumberSpace::NORMAL:
|
dist_->params[i] += g_params[count];
|
||||||
dist_->params[i] *= gparams[count];
|
} else {
|
||||||
break;
|
dist_->params[i] *= g_params[count];
|
||||||
case NumberSpace::LOGARITHM:
|
|
||||||
dist_->params[i] += gparams[count];
|
|
||||||
}
|
}
|
||||||
count ++;
|
count ++;
|
||||||
if (count >= gparams.size()) {
|
if (count >= g_params.size()) {
|
||||||
count = 0;
|
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
|
void
|
||||||
Factor::insertVariable (VarId vid, unsigned nStates)
|
Factor::insertVariable (VarId varId, unsigned nrStates)
|
||||||
{
|
{
|
||||||
assert (getPositionOf (vid) == -1);
|
assert (indexOf (varId) == -1);
|
||||||
ParamSet newPs;
|
Params oldParams = dist_->params;
|
||||||
newPs.reserve (dist_->params.size() * nStates);
|
dist_->params.clear();
|
||||||
for (unsigned i = 0; i < dist_->params.size(); i++) {
|
dist_->params.reserve (oldParams.size() * nrStates);
|
||||||
for (unsigned j = 0; j < nStates; j++) {
|
for (unsigned i = 0; i < oldParams.size(); i++) {
|
||||||
newPs.push_back (dist_->params[i]);
|
for (unsigned reps = 0; reps < nrStates; reps++) {
|
||||||
|
dist_->params.push_back (oldParams[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
varids_.push_back (vid);
|
varids_.push_back (varId);
|
||||||
ranges_.push_back (nStates);
|
ranges_.push_back (nrStates);
|
||||||
dist_->updateParameters (newPs);
|
|
||||||
dist_->entries.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void
|
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) {
|
while (varids_.back() != vid) {
|
||||||
removeLastVariable();
|
sumOutLastVariable();
|
||||||
}
|
}
|
||||||
while (varids_.front() != vid) {
|
while (varids_.front() != vid) {
|
||||||
removeFirstVariable();
|
sumOutFirstVariable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Factor::removeVariable (VarId vid)
|
Factor::sumOutAllExcept (const VarIds& vids)
|
||||||
{
|
{
|
||||||
int pos = getPositionOf (vid);
|
for (unsigned i = 0; i < varids_.size(); i++) {
|
||||||
assert (pos != -1);
|
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()) {
|
if (vid == varids_.back()) {
|
||||||
removeLastVariable(); // optimization
|
sumOutLastVariable(); // optimization
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (vid == varids_.front()) {
|
if (vid == varids_.front()) {
|
||||||
removeFirstVariable(); // optimization
|
sumOutFirstVariable(); // optimization
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,36 +271,35 @@ Factor::removeVariable (VarId vid)
|
|||||||
// on the left of `var', with the states of the remaining vars fixed
|
// on the left of `var', with the states of the remaining vars fixed
|
||||||
unsigned leftVarOffset = 1;
|
unsigned leftVarOffset = 1;
|
||||||
|
|
||||||
for (int i = varids_.size() - 1; i > pos; i--) {
|
for (int i = varids_.size() - 1; i > idx; i--) {
|
||||||
varOffset *= ranges_[i];
|
varOffset *= ranges_[i];
|
||||||
leftVarOffset *= ranges_[i];
|
leftVarOffset *= ranges_[i];
|
||||||
}
|
}
|
||||||
leftVarOffset *= ranges_[pos];
|
leftVarOffset *= ranges_[idx];
|
||||||
|
|
||||||
unsigned offset = 0;
|
unsigned offset = 0;
|
||||||
unsigned count1 = 0;
|
unsigned count1 = 0;
|
||||||
unsigned count2 = 0;
|
unsigned count2 = 0;
|
||||||
unsigned newPsSize = dist_->params.size() / ranges_[pos];
|
unsigned newpsSize = dist_->params.size() / ranges_[idx];
|
||||||
|
|
||||||
ParamSet newPs;
|
Params newps;
|
||||||
newPs.reserve (newPsSize);
|
newps.reserve (newpsSize);
|
||||||
|
Params& params = dist_->params;
|
||||||
|
|
||||||
while (newPs.size() < newPsSize) {
|
while (newps.size() < newpsSize) {
|
||||||
double sum = Util::addIdenty();
|
double sum = Util::addIdenty();
|
||||||
for (unsigned i = 0; i < ranges_[pos]; i++) {
|
for (unsigned i = 0; i < ranges_[idx]; i++) {
|
||||||
switch (NSPACE) {
|
if (Globals::logDomain) {
|
||||||
case NumberSpace::NORMAL:
|
Util::logSum (sum, params[offset]);
|
||||||
sum += dist_->params[offset];
|
} else {
|
||||||
break;
|
sum += params[offset];
|
||||||
case NumberSpace::LOGARITHM:
|
|
||||||
Util::logSum (sum, dist_->params[offset]);
|
|
||||||
}
|
}
|
||||||
offset += varOffset;
|
offset += varOffset;
|
||||||
}
|
}
|
||||||
newPs.push_back (sum);
|
newps.push_back (sum);
|
||||||
count1 ++;
|
count1 ++;
|
||||||
if (pos == (int)varids_.size() - 1) {
|
if (idx == (int)varids_.size() - 1) {
|
||||||
offset = count1 * ranges_[pos];
|
offset = count1 * ranges_[idx];
|
||||||
} else {
|
} else {
|
||||||
if (((offset - varOffset + 1) % leftVarOffset) == 0) {
|
if (((offset - varOffset + 1) % leftVarOffset) == 0) {
|
||||||
count1 = 0;
|
count1 = 0;
|
||||||
@ -280,73 +308,66 @@ Factor::removeVariable (VarId vid)
|
|||||||
offset = (leftVarOffset * count2) + count1;
|
offset = (leftVarOffset * count2) + count1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
varids_.erase (varids_.begin() + pos);
|
varids_.erase (varids_.begin() + idx);
|
||||||
ranges_.erase (ranges_.begin() + pos);
|
ranges_.erase (ranges_.begin() + idx);
|
||||||
dist_->updateParameters (newPs);
|
dist_->params = newps;
|
||||||
dist_->entries.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Factor::removeFirstVariable (void)
|
Factor::sumOutFirstVariable (void)
|
||||||
{
|
{
|
||||||
ParamSet& params = dist_->params;
|
Params& params = dist_->params;
|
||||||
unsigned nStates = ranges_.front();
|
unsigned nStates = ranges_.front();
|
||||||
unsigned sep = params.size() / nStates;
|
unsigned sep = params.size() / nStates;
|
||||||
switch (NSPACE) {
|
if (Globals::logDomain) {
|
||||||
case NumberSpace::NORMAL:
|
for (unsigned i = sep; i < params.size(); i++) {
|
||||||
for (unsigned i = sep; i < params.size(); i++) {
|
Util::logSum (params[i % sep], params[i]);
|
||||||
params[i % sep] += params[i];
|
}
|
||||||
}
|
} else {
|
||||||
break;
|
for (unsigned i = sep; i < params.size(); i++) {
|
||||||
case NumberSpace::LOGARITHM:
|
params[i % sep] += params[i];
|
||||||
for (unsigned i = sep; i < params.size(); i++) {
|
}
|
||||||
Util::logSum (params[i % sep], params[i]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
params.resize (sep);
|
params.resize (sep);
|
||||||
varids_.erase (varids_.begin());
|
varids_.erase (varids_.begin());
|
||||||
ranges_.erase (ranges_.begin());
|
ranges_.erase (ranges_.begin());
|
||||||
dist_->entries.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Factor::removeLastVariable (void)
|
Factor::sumOutLastVariable (void)
|
||||||
{
|
{
|
||||||
ParamSet& params = dist_->params;
|
Params& params = dist_->params;
|
||||||
unsigned nStates = ranges_.back();
|
unsigned nStates = ranges_.back();
|
||||||
unsigned idx1 = 0;
|
unsigned idx1 = 0;
|
||||||
unsigned idx2 = 0;
|
unsigned idx2 = 0;
|
||||||
switch (NSPACE) {
|
if (Globals::logDomain) {
|
||||||
case NumberSpace::NORMAL:
|
while (idx1 < params.size()) {
|
||||||
while (idx1 < params.size()) {
|
params[idx2] = params[idx1];
|
||||||
params[idx2] = params[idx1];
|
idx1 ++;
|
||||||
|
for (unsigned j = 1; j < nStates; j++) {
|
||||||
|
Util::logSum (params[idx2], params[idx1]);
|
||||||
idx1 ++;
|
idx1 ++;
|
||||||
for (unsigned j = 1; j < nStates; j++) {
|
|
||||||
params[idx2] += params[idx1];
|
|
||||||
idx1 ++;
|
|
||||||
}
|
|
||||||
idx2 ++;
|
|
||||||
}
|
}
|
||||||
break;
|
idx2 ++;
|
||||||
case NumberSpace::LOGARITHM:
|
}
|
||||||
while (idx1 < params.size()) {
|
} else {
|
||||||
params[idx2] = params[idx1];
|
while (idx1 < params.size()) {
|
||||||
|
params[idx2] = params[idx1];
|
||||||
|
idx1 ++;
|
||||||
|
for (unsigned j = 1; j < nStates; j++) {
|
||||||
|
params[idx2] += params[idx1];
|
||||||
idx1 ++;
|
idx1 ++;
|
||||||
for (unsigned j = 1; j < nStates; j++) {
|
|
||||||
Util::logSum (params[idx2], params[idx1]);
|
|
||||||
idx1 ++;
|
|
||||||
}
|
|
||||||
idx2 ++;
|
|
||||||
}
|
}
|
||||||
|
idx2 ++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
params.resize (idx2);
|
params.resize (idx2);
|
||||||
varids_.pop_back();
|
varids_.pop_back();
|
||||||
ranges_.pop_back();
|
ranges_.pop_back();
|
||||||
dist_->entries.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -354,34 +375,31 @@ Factor::removeLastVariable (void)
|
|||||||
void
|
void
|
||||||
Factor::orderVariables (void)
|
Factor::orderVariables (void)
|
||||||
{
|
{
|
||||||
VarIdSet sortedVarIds = varids_;
|
VarIds sortedVarIds = varids_;
|
||||||
sort (sortedVarIds.begin(), sortedVarIds.end());
|
sort (sortedVarIds.begin(), sortedVarIds.end());
|
||||||
orderVariables (sortedVarIds);
|
reorderVariables (sortedVarIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Factor::orderVariables (const VarIdSet& newVarIdOrder)
|
Factor::reorderVariables (const VarIds& newVarIds)
|
||||||
{
|
{
|
||||||
assert (newVarIdOrder.size() == varids_.size());
|
assert (newVarIds.size() == varids_.size());
|
||||||
if (newVarIdOrder == varids_) {
|
if (newVarIds == varids_) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ranges newRangeOrder;
|
Ranges newRanges;
|
||||||
for (unsigned i = 0; i < newVarIdOrder.size(); i++) {
|
vector<unsigned> positions;
|
||||||
unsigned pos = getPositionOf (newVarIdOrder[i]);
|
for (unsigned i = 0; i < newVarIds.size(); i++) {
|
||||||
newRangeOrder.push_back (ranges_[pos]);
|
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();
|
unsigned N = ranges_.size();
|
||||||
ParamSet newPs (dist_->params.size());
|
Params newParams (dist_->params.size());
|
||||||
for (unsigned i = 0; i < dist_->params.size(); i++) {
|
for (unsigned i = 0; i < dist_->params.size(); i++) {
|
||||||
unsigned li = i;
|
unsigned li = i;
|
||||||
// calculate vector index corresponding to linear index
|
// calculate vector index corresponding to linear index
|
||||||
@ -397,35 +415,68 @@ Factor::orderVariables (const VarIdSet& newVarIdOrder)
|
|||||||
new_li += vi[positions[k]] * prod;
|
new_li += vi[positions[k]] * prod;
|
||||||
prod *= ranges_[positions[k]];
|
prod *= ranges_[positions[k]];
|
||||||
}
|
}
|
||||||
newPs[new_li] = dist_->params[i];
|
newParams[new_li] = dist_->params[i];
|
||||||
}
|
}
|
||||||
varids_ = newVarIdOrder;
|
varids_ = newVarIds;
|
||||||
ranges_ = newRangeOrder;
|
ranges_ = newRanges;
|
||||||
dist_->params = newPs;
|
dist_->params = newParams;
|
||||||
dist_->entries.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Factor::removeInconsistentEntries (VarId vid, unsigned evidence)
|
Factor::absorveEvidence (VarId vid, unsigned evidence)
|
||||||
{
|
{
|
||||||
int pos = getPositionOf (vid);
|
int idx = indexOf (vid);
|
||||||
assert (pos != -1);
|
assert (idx != -1);
|
||||||
ParamSet newPs;
|
|
||||||
newPs.reserve (dist_->params.size() / ranges_[pos]);
|
Params oldParams = dist_->params;
|
||||||
StatesIndexer idx (ranges_);
|
dist_->params.clear();
|
||||||
|
dist_->params.reserve (oldParams.size() / ranges_[idx]);
|
||||||
|
StatesIndexer indexer (ranges_);
|
||||||
for (unsigned i = 0; i < evidence; i++) {
|
for (unsigned i = 0; i < evidence; i++) {
|
||||||
idx.incrementState (pos);
|
indexer.increment (idx);
|
||||||
}
|
}
|
||||||
while (idx.valid()) {
|
while (indexer.valid()) {
|
||||||
newPs.push_back (dist_->params[idx.getLinearIndex()]);
|
dist_->params.push_back (oldParams[indexer]);
|
||||||
idx.nextSameState (pos);
|
indexer.incrementExcluding (idx);
|
||||||
}
|
}
|
||||||
varids_.erase (varids_.begin() + pos);
|
varids_.erase (varids_.begin() + idx);
|
||||||
ranges_.erase (ranges_.begin() + pos);
|
ranges_.erase (ranges_.begin() + idx);
|
||||||
dist_->updateParameters (newPs);
|
}
|
||||||
dist_->entries.clear();
|
|
||||||
|
|
||||||
|
|
||||||
|
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
|
void
|
||||||
Factor::printFactor (void) const
|
Factor::print (void) const
|
||||||
{
|
{
|
||||||
VarNodes vars;
|
VarNodes vars;
|
||||||
for (unsigned i = 0; i < varids_.size(); i++) {
|
for (unsigned i = 0; i < varids_.size(); i++) {
|
||||||
@ -457,53 +508,10 @@ Factor::printFactor (void) const
|
|||||||
cout << "f(" << jointStrings[i] << ")" ;
|
cout << "f(" << jointStrings[i] << ")" ;
|
||||||
cout << " = " << dist_->params[i] << endl;
|
cout << " = " << dist_->params[i] << endl;
|
||||||
}
|
}
|
||||||
|
cout << endl;
|
||||||
for (unsigned i = 0; i < vars.size(); i++) {
|
for (unsigned i = 0; i < vars.size(); i++) {
|
||||||
delete vars[i];
|
delete vars[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
Factor::getPositionOf (VarId vid) const
|
|
||||||
{
|
|
||||||
for (unsigned i = 0; i < varids_.size(); i++) {
|
|
||||||
if (varids_[i] == vid) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const vector<CptEntry>&
|
|
||||||
Factor::getCptEntries (void) const
|
|
||||||
{
|
|
||||||
if (dist_->entries.size() == 0) {
|
|
||||||
vector<DConf> confs (dist_->params.size());
|
|
||||||
for (unsigned i = 0; i < dist_->params.size(); i++) {
|
|
||||||
confs[i].resize (varids_.size());
|
|
||||||
}
|
|
||||||
unsigned nReps = 1;
|
|
||||||
for (int i = varids_.size() - 1; i >= 0; i--) {
|
|
||||||
unsigned index = 0;
|
|
||||||
while (index < dist_->params.size()) {
|
|
||||||
for (unsigned j = 0; j < ranges_[i]; j++) {
|
|
||||||
for (unsigned r = 0; r < nReps; r++) {
|
|
||||||
confs[index][i] = j;
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
nReps *= ranges_[i];
|
|
||||||
}
|
|
||||||
dist_->entries.clear();
|
|
||||||
dist_->entries.reserve (dist_->params.size());
|
|
||||||
for (unsigned i = 0; i < dist_->params.size(); i++) {
|
|
||||||
dist_->entries.push_back (CptEntry (i, confs[i]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dist_->entries;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "Distribution.h"
|
#include "Distribution.h"
|
||||||
#include "CptEntry.h"
|
|
||||||
#include "VarNode.h"
|
#include "VarNode.h"
|
||||||
|
|
||||||
|
|
||||||
@ -20,47 +19,46 @@ class Factor
|
|||||||
Factor (const Factor&);
|
Factor (const Factor&);
|
||||||
Factor (VarId, unsigned);
|
Factor (VarId, unsigned);
|
||||||
Factor (const VarNodes&);
|
Factor (const VarNodes&);
|
||||||
Factor (VarId, unsigned, const ParamSet&);
|
Factor (VarId, unsigned, const Params&);
|
||||||
Factor (VarNodes&, Distribution*);
|
Factor (VarNodes&, Distribution*);
|
||||||
Factor (const VarNodes&, const ParamSet&);
|
Factor (const VarNodes&, const Params&);
|
||||||
Factor (const VarIdSet&, const Ranges&, const ParamSet&);
|
Factor (const VarIds&, const Ranges&, const Params&);
|
||||||
|
~Factor (void);
|
||||||
|
|
||||||
void setParameters (const ParamSet&);
|
void setParameters (const Params&);
|
||||||
void copyFromFactor (const Factor& f);
|
void copyFromFactor (const Factor& f);
|
||||||
void multiplyByFactor (const Factor&, const vector<CptEntry>* = 0);
|
void multiply (const Factor&);
|
||||||
void insertVariable (VarId, unsigned);
|
void insertVariable (VarId, unsigned);
|
||||||
void removeAllVariablesExcept (VarId);
|
void insertVariables (const VarIds&, const Ranges&);
|
||||||
void removeVariable (VarId);
|
void sumOutAllExcept (VarId);
|
||||||
void removeFirstVariable (void);
|
void sumOutAllExcept (const VarIds&);
|
||||||
void removeLastVariable (void);
|
void sumOut (VarId);
|
||||||
|
void sumOutFirstVariable (void);
|
||||||
|
void sumOutLastVariable (void);
|
||||||
void orderVariables (void);
|
void orderVariables (void);
|
||||||
void orderVariables (const VarIdSet&);
|
void reorderVariables (const VarIds&);
|
||||||
void removeInconsistentEntries (VarId, unsigned);
|
void absorveEvidence (VarId, unsigned);
|
||||||
|
void normalize (void);
|
||||||
|
bool contains (const VarIds&) const;
|
||||||
|
int indexOf (VarId) const;
|
||||||
string getLabel (void) const;
|
string getLabel (void) const;
|
||||||
void printFactor (void) const;
|
void print (void) const;
|
||||||
int getPositionOf (VarId) const;
|
|
||||||
const vector<CptEntry>& getCptEntries (void) const;
|
|
||||||
|
|
||||||
const VarIdSet& getVarIds (void) const { return varids_; }
|
const VarIds& getVarIds (void) const { return varids_; }
|
||||||
const Ranges& getRanges (void) const { return ranges_; }
|
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_; }
|
Distribution* getDistribution (void) const { return dist_; }
|
||||||
unsigned nrVariables (void) const { return varids_.size(); }
|
unsigned nrVariables (void) const { return varids_.size(); }
|
||||||
unsigned nrParameters() const { return dist_->params.size(); }
|
unsigned nrParameters() const { return dist_->params.size(); }
|
||||||
|
|
||||||
void setDistribution (Distribution* dist)
|
void setDistribution (Distribution* dist)
|
||||||
{
|
{
|
||||||
dist_ = dist;
|
dist_ = dist;
|
||||||
}
|
}
|
||||||
void freeDistribution (void)
|
|
||||||
{
|
|
||||||
delete dist_;
|
|
||||||
dist_ = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
VarIdSet varids_;
|
VarIds varids_;
|
||||||
Ranges ranges_;
|
Ranges ranges_;
|
||||||
Distribution* dist_;
|
Distribution* dist_;
|
||||||
};
|
};
|
||||||
|
@ -9,6 +9,30 @@
|
|||||||
#include "FactorGraph.h"
|
#include "FactorGraph.h"
|
||||||
#include "Factor.h"
|
#include "Factor.h"
|
||||||
#include "BayesNet.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 (
|
FgFacNode* fn = new FgFacNode (
|
||||||
new Factor (neighs, nodes[i]->getDistribution()));
|
new Factor (neighs, nodes[i]->getDistribution()));
|
||||||
|
if (orderFactorVariables) {
|
||||||
|
sort (neighs.begin(), neighs.end(), CompVarId());
|
||||||
|
fn->factor()->orderVariables();
|
||||||
|
}
|
||||||
addFactor (fn);
|
addFactor (fn);
|
||||||
for (unsigned j = 0; j < neighs.size(); j++) {
|
for (unsigned j = 0; j < neighs.size(); j++) {
|
||||||
addEdge (fn, static_cast<FgVarNode*> (neighs[j]));
|
addEdge (fn, static_cast<FgVarNode*> (neighs[j]));
|
||||||
@ -110,13 +138,13 @@ FactorGraph::readFromUaiFormat (const char* fileName)
|
|||||||
cerr << ", given: " << nParams << endl;
|
cerr << ", given: " << nParams << endl;
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
ParamSet params (nParams);
|
Params params (nParams);
|
||||||
for (unsigned j = 0; j < nParams; j++) {
|
for (unsigned j = 0; j < nParams; j++) {
|
||||||
double param;
|
double param;
|
||||||
is >> param;
|
is >> param;
|
||||||
params[j] = param;
|
params[j] = param;
|
||||||
}
|
}
|
||||||
if (NSPACE == NumberSpace::LOGARITHM) {
|
if (Globals::logDomain) {
|
||||||
Util::toLog (params);
|
Util::toLog (params);
|
||||||
}
|
}
|
||||||
facNodes_[i]->factor()->setParameters (params);
|
facNodes_[i]->factor()->setParameters (params);
|
||||||
@ -158,7 +186,7 @@ FactorGraph::readFromLibDaiFormat (const char* fileName)
|
|||||||
while ((is.peek()) == '#') getline (is, line);
|
while ((is.peek()) == '#') getline (is, line);
|
||||||
|
|
||||||
is >> nVars;
|
is >> nVars;
|
||||||
VarIdSet vids;
|
VarIds vids;
|
||||||
for (unsigned j = 0; j < nVars; j++) {
|
for (unsigned j = 0; j < nVars; j++) {
|
||||||
VarId vid;
|
VarId vid;
|
||||||
while ((is.peek()) == '#') getline (is, line);
|
while ((is.peek()) == '#') getline (is, line);
|
||||||
@ -185,15 +213,14 @@ FactorGraph::readFromLibDaiFormat (const char* fileName)
|
|||||||
neighs.push_back (var);
|
neighs.push_back (var);
|
||||||
nParams *= var->nrStates();
|
nParams *= var->nrStates();
|
||||||
}
|
}
|
||||||
ParamSet params (nParams, 0);
|
Params params (nParams, 0);
|
||||||
unsigned nNonzeros;
|
unsigned nNonzeros;
|
||||||
while ((is.peek()) == '#')
|
while ((is.peek()) == '#') getline (is, line);
|
||||||
getline (is, line);
|
|
||||||
is >> nNonzeros;
|
is >> nNonzeros;
|
||||||
|
|
||||||
for (unsigned j = 0; j < nNonzeros; j++) {
|
for (unsigned j = 0; j < nNonzeros; j++) {
|
||||||
unsigned index;
|
unsigned index;
|
||||||
Param val;
|
double val;
|
||||||
while ((is.peek()) == '#') getline (is, line);
|
while ((is.peek()) == '#') getline (is, line);
|
||||||
is >> index;
|
is >> index;
|
||||||
while ((is.peek()) == '#') getline (is, line);
|
while ((is.peek()) == '#') getline (is, line);
|
||||||
@ -201,7 +228,7 @@ FactorGraph::readFromLibDaiFormat (const char* fileName)
|
|||||||
params[index] = val;
|
params[index] = val;
|
||||||
}
|
}
|
||||||
reverse (neighs.begin(), neighs.end());
|
reverse (neighs.begin(), neighs.end());
|
||||||
if (NSPACE == NumberSpace::LOGARITHM) {
|
if (Globals::logDomain) {
|
||||||
Util::toLog (params);
|
Util::toLog (params);
|
||||||
}
|
}
|
||||||
FgFacNode* fn = new FgFacNode (new Factor (neighs, params));
|
FgFacNode* fn = new FgFacNode (new Factor (neighs, params));
|
||||||
@ -233,7 +260,7 @@ FactorGraph::addVariable (FgVarNode* vn)
|
|||||||
{
|
{
|
||||||
varNodes_.push_back (vn);
|
varNodes_.push_back (vn);
|
||||||
vn->setIndex (varNodes_.size() - 1);
|
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
|
void
|
||||||
FactorGraph::addEdge (FgVarNode* vn, FgFacNode* fn)
|
FactorGraph::addEdge (FgVarNode* vn, FgFacNode* fn)
|
||||||
{
|
{
|
||||||
@ -326,10 +354,10 @@ void
|
|||||||
FactorGraph::printGraphicalModel (void) const
|
FactorGraph::printGraphicalModel (void) const
|
||||||
{
|
{
|
||||||
for (unsigned i = 0; i < varNodes_.size(); i++) {
|
for (unsigned i = 0; i < varNodes_.size(); i++) {
|
||||||
cout << "VarId = " << varNodes_[i]->varId() << endl;
|
cout << "VarId = " << varNodes_[i]->varId() << endl;
|
||||||
cout << "Label = " << varNodes_[i]->label() << endl;
|
cout << "Label = " << varNodes_[i]->label() << endl;
|
||||||
cout << "Nr States = " << varNodes_[i]->nrStates() << endl;
|
cout << "Nr States = " << varNodes_[i]->nrStates() << endl;
|
||||||
cout << "Evidence = " << varNodes_[i]->getEvidence() << endl;
|
cout << "Evidence = " << varNodes_[i]->getEvidence() << endl;
|
||||||
cout << "Factors = " ;
|
cout << "Factors = " ;
|
||||||
for (unsigned j = 0; j < varNodes_[i]->neighbors().size(); j++) {
|
for (unsigned j = 0; j < varNodes_[i]->neighbors().size(); j++) {
|
||||||
cout << varNodes_[i]->neighbors()[j]->getLabel() << " " ;
|
cout << varNodes_[i]->neighbors()[j]->getLabel() << " " ;
|
||||||
@ -337,7 +365,7 @@ FactorGraph::printGraphicalModel (void) const
|
|||||||
cout << endl << endl;
|
cout << endl << endl;
|
||||||
}
|
}
|
||||||
for (unsigned i = 0; i < facNodes_.size(); i++) {
|
for (unsigned i = 0; i < facNodes_.size(); i++) {
|
||||||
facNodes_[i]->factor()->printFactor();
|
facNodes_[i]->factor()->print();
|
||||||
cout << endl;
|
cout << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -412,7 +440,10 @@ FactorGraph::exportToUaiFormat (const char* fileName) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned i = 0; i < facNodes_.size(); i++) {
|
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 << " " ;
|
out << endl << params.size() << endl << " " ;
|
||||||
for (unsigned j = 0; j < params.size(); j++) {
|
for (unsigned j = 0; j < params.size(); j++) {
|
||||||
out << params[j] << " " ;
|
out << params[j] << " " ;
|
||||||
@ -446,7 +477,10 @@ FactorGraph::exportToLibDaiFormat (const char* fileName) const
|
|||||||
out << factorVars[j]->nrStates() << " " ;
|
out << factorVars[j]->nrStates() << " " ;
|
||||||
}
|
}
|
||||||
out << endl;
|
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;
|
out << params.size() << endl;
|
||||||
for (unsigned j = 0; j < params.size(); j++) {
|
for (unsigned j = 0; j < params.size(); j++) {
|
||||||
out << j << " " << params[j] << endl;
|
out << j << " " << params[j] << endl;
|
||||||
|
@ -4,13 +4,13 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "GraphicalModel.h"
|
#include "GraphicalModel.h"
|
||||||
#include "Shared.h"
|
|
||||||
#include "Distribution.h"
|
#include "Distribution.h"
|
||||||
#include "Factor.h"
|
#include "Factor.h"
|
||||||
|
#include "Horus.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
class BayesNet;
|
||||||
class FgFacNode;
|
class FgFacNode;
|
||||||
|
|
||||||
class FgVarNode : public VarNode
|
class FgVarNode : public VarNode
|
||||||
@ -18,42 +18,29 @@ class FgVarNode : public VarNode
|
|||||||
public:
|
public:
|
||||||
FgVarNode (VarId varId, unsigned nrStates) : VarNode (varId, nrStates) { }
|
FgVarNode (VarId varId, unsigned nrStates) : VarNode (varId, nrStates) { }
|
||||||
FgVarNode (const VarNode* v) : VarNode (v) { }
|
FgVarNode (const VarNode* v) : VarNode (v) { }
|
||||||
void addNeighbor (FgFacNode* fn)
|
|
||||||
{
|
void addNeighbor (FgFacNode* fn) { neighs_.push_back (fn); }
|
||||||
neighs_.push_back (fn);
|
const FgFacSet& neighbors (void) const { return neighs_; }
|
||||||
}
|
|
||||||
const vector<FgFacNode*>& neighbors (void) const
|
|
||||||
{
|
|
||||||
return neighs_;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DISALLOW_COPY_AND_ASSIGN (FgVarNode);
|
DISALLOW_COPY_AND_ASSIGN (FgVarNode);
|
||||||
// members
|
// members
|
||||||
vector<FgFacNode*> neighs_;
|
FgFacSet neighs_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class FgFacNode
|
class FgFacNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FgFacNode (Factor* factor)
|
FgFacNode (const FgFacNode* fn) {
|
||||||
{
|
factor_ = new Factor (*fn->factor());
|
||||||
factor_ = factor;
|
|
||||||
index_ = -1;
|
index_ = -1;
|
||||||
}
|
}
|
||||||
Factor* factor() const
|
FgFacNode (Factor* f) : factor_(new Factor(*f)), index_(-1) { }
|
||||||
{
|
Factor* factor() const { return factor_; }
|
||||||
return factor_;
|
void addNeighbor (FgVarNode* vn) { neighs_.push_back (vn); }
|
||||||
}
|
const FgVarSet& neighbors (void) const { return neighs_; }
|
||||||
void addNeighbor (FgVarNode* vn)
|
|
||||||
{
|
|
||||||
neighs_.push_back (vn);
|
|
||||||
}
|
|
||||||
const vector<FgVarNode*>& neighbors (void) const
|
|
||||||
{
|
|
||||||
return neighs_;
|
|
||||||
}
|
|
||||||
int getIndex (void) const
|
int getIndex (void) const
|
||||||
{
|
{
|
||||||
assert (index_ != -1);
|
assert (index_ != -1);
|
||||||
@ -67,7 +54,7 @@ class FgFacNode
|
|||||||
{
|
{
|
||||||
return factor_->getDistribution();
|
return factor_->getDistribution();
|
||||||
}
|
}
|
||||||
const ParamSet& getParameters (void) const
|
const Params& getParameters (void) const
|
||||||
{
|
{
|
||||||
return factor_->getParameters();
|
return factor_->getParameters();
|
||||||
}
|
}
|
||||||
@ -80,7 +67,16 @@ class FgFacNode
|
|||||||
|
|
||||||
Factor* factor_;
|
Factor* factor_;
|
||||||
int index_;
|
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:
|
public:
|
||||||
FactorGraph (void) {};
|
FactorGraph (void) {};
|
||||||
|
FactorGraph (const FactorGraph&);
|
||||||
FactorGraph (const BayesNet&);
|
FactorGraph (const BayesNet&);
|
||||||
~FactorGraph (void);
|
~FactorGraph (void);
|
||||||
|
|
||||||
@ -112,28 +109,29 @@ class FactorGraph : public GraphicalModel
|
|||||||
|
|
||||||
FgVarNode* getFgVarNode (VarId vid) const
|
FgVarNode* getFgVarNode (VarId vid) const
|
||||||
{
|
{
|
||||||
IndexMap::const_iterator it = indexMap_.find (vid);
|
IndexMap::const_iterator it = varMap_.find (vid);
|
||||||
if (it == indexMap_.end()) {
|
if (it == varMap_.end()) {
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
return varNodes_[it->second];
|
return varNodes_[it->second];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool orderFactorVariables;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
//DISALLOW_COPY_AND_ASSIGN (FactorGraph);
|
||||||
bool containsCycle (void) const;
|
bool containsCycle (void) const;
|
||||||
bool containsCycle (const FgVarNode*, const FgFacNode*,
|
bool containsCycle (const FgVarNode*, const FgFacNode*,
|
||||||
vector<bool>&, vector<bool>&) const;
|
vector<bool>&, vector<bool>&) const;
|
||||||
bool containsCycle (const FgFacNode*, const FgVarNode*,
|
bool containsCycle (const FgFacNode*, const FgVarNode*,
|
||||||
vector<bool>&, vector<bool>&) const;
|
vector<bool>&, vector<bool>&) const;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN (FactorGraph);
|
|
||||||
|
|
||||||
FgVarSet varNodes_;
|
FgVarSet varNodes_;
|
||||||
FgFacSet facNodes_;
|
FgFacSet facNodes_;
|
||||||
|
|
||||||
typedef unordered_map<unsigned, unsigned> IndexMap;
|
typedef unordered_map<unsigned, unsigned> IndexMap;
|
||||||
IndexMap indexMap_;
|
IndexMap varMap_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // HORUS_FACTORGRAPH_H
|
#endif // HORUS_FACTORGRAPH_H
|
||||||
|
@ -8,7 +8,8 @@
|
|||||||
#include "FgBpSolver.h"
|
#include "FgBpSolver.h"
|
||||||
#include "FactorGraph.h"
|
#include "FactorGraph.h"
|
||||||
#include "Factor.h"
|
#include "Factor.h"
|
||||||
#include "Shared.h"
|
#include "Indexer.h"
|
||||||
|
#include "Horus.h"
|
||||||
|
|
||||||
|
|
||||||
FgBpSolver::FgBpSolver (const FactorGraph& fg) : Solver (&fg)
|
FgBpSolver::FgBpSolver (const FactorGraph& fg) : Solver (&fg)
|
||||||
@ -40,20 +41,15 @@ FgBpSolver::runSolver (void)
|
|||||||
if (COLLECT_STATISTICS) {
|
if (COLLECT_STATISTICS) {
|
||||||
start = clock();
|
start = clock();
|
||||||
}
|
}
|
||||||
if (false) {
|
runLoopySolver();
|
||||||
//if (!BpOptions::useAlwaysLoopySolver && factorGraph_->isTree()) {
|
if (DL >= 2) {
|
||||||
runTreeSolver();
|
cout << endl;
|
||||||
} else {
|
if (nIters_ < BpOptions::maxIter) {
|
||||||
runLoopySolver();
|
cout << "Sum-Product converged in " ;
|
||||||
if (DL >= 2) {
|
cout << nIters_ << " iterations" << endl;
|
||||||
|
} else {
|
||||||
|
cout << "The maximum number of iterations was hit, terminating..." ;
|
||||||
cout << endl;
|
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();
|
unsigned size = factorGraph_->getVarNodes().size();
|
||||||
@ -73,32 +69,29 @@ FgBpSolver::runSolver (void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
ParamSet
|
Params
|
||||||
FgBpSolver::getPosterioriOf (VarId vid)
|
FgBpSolver::getPosterioriOf (VarId vid)
|
||||||
{
|
{
|
||||||
assert (factorGraph_->getFgVarNode (vid));
|
assert (factorGraph_->getFgVarNode (vid));
|
||||||
FgVarNode* var = factorGraph_->getFgVarNode (vid);
|
FgVarNode* var = factorGraph_->getFgVarNode (vid);
|
||||||
ParamSet probs;
|
Params probs;
|
||||||
|
|
||||||
if (var->hasEvidence()) {
|
if (var->hasEvidence()) {
|
||||||
probs.resize (var->nrStates(), Util::noEvidence());
|
probs.resize (var->nrStates(), Util::noEvidence());
|
||||||
probs[var->getEvidence()] = Util::withEvidence();
|
probs[var->getEvidence()] = Util::withEvidence();
|
||||||
} else {
|
} else {
|
||||||
probs.resize (var->nrStates(), Util::multIdenty());
|
probs.resize (var->nrStates(), Util::multIdenty());
|
||||||
const SpLinkSet& links = ninf(var)->getLinks();
|
const SpLinkSet& links = ninf(var)->getLinks();
|
||||||
switch (NSPACE) {
|
if (Globals::logDomain) {
|
||||||
case NumberSpace::NORMAL:
|
for (unsigned i = 0; i < links.size(); i++) {
|
||||||
for (unsigned i = 0; i < links.size(); i++) {
|
Util::add (probs, links[i]->getMessage());
|
||||||
Util::multiply (probs, links[i]->getMessage());
|
}
|
||||||
}
|
Util::normalize (probs);
|
||||||
Util::normalize (probs);
|
Util::fromLog (probs);
|
||||||
break;
|
} else {
|
||||||
case NumberSpace::LOGARITHM:
|
for (unsigned i = 0; i < links.size(); i++) {
|
||||||
for (unsigned i = 0; i < links.size(); i++) {
|
Util::multiply (probs, links[i]->getMessage());
|
||||||
Util::add (probs, links[i]->getMessage());
|
}
|
||||||
}
|
Util::normalize (probs);
|
||||||
Util::normalize (probs);
|
|
||||||
Util::fromLog (probs);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return probs;
|
return probs;
|
||||||
@ -106,66 +99,38 @@ FgBpSolver::getPosterioriOf (VarId vid)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
ParamSet
|
Params
|
||||||
FgBpSolver::getJointDistributionOf (const VarIdSet& jointVarIds)
|
FgBpSolver::getJointDistributionOf (const VarIds& jointVarIds)
|
||||||
{
|
{
|
||||||
unsigned msgSize = 1;
|
FgVarNode* vn = factorGraph_->getFgVarNode (jointVarIds[0]);
|
||||||
vector<unsigned> dsizes (jointVarIds.size());
|
const FgFacSet& factorNodes = vn->neighbors();
|
||||||
for (unsigned i = 0; i < jointVarIds.size(); i++) {
|
int idx = -1;
|
||||||
dsizes[i] = factorGraph_->getFgVarNode (jointVarIds[i])->nrStates();
|
for (unsigned i = 0; i < factorNodes.size(); i++) {
|
||||||
msgSize *= dsizes[i];
|
if (factorNodes[i]->factor()->contains (jointVarIds)) {
|
||||||
}
|
idx = i;
|
||||||
unsigned reps = 1;
|
break;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
if (idx == -1) {
|
||||||
|
return getJointByConditioning (jointVarIds);
|
||||||
|
} else {
|
||||||
|
Factor r (*factorNodes[idx]->factor());
|
||||||
bool
|
const SpLinkSet& links = ninf(factorNodes[idx])->getLinks();
|
||||||
FgBpSolver::readyToSendMessage (const SpLink* link) const
|
for (unsigned i = 0; i < links.size(); i++) {
|
||||||
{
|
Factor msg (links[i]->getVariable()->varId(),
|
||||||
const FgVarSet& neighbors = link->getFactor()->neighbors();
|
links[i]->getVariable()->nrStates(),
|
||||||
for (unsigned i = 0; i < neighbors.size(); i++) {
|
getVar2FactorMsg (links[i]));
|
||||||
if (neighbors[i] != link->getVariable()) {
|
r.multiply (msg);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
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;
|
bool converged = true;
|
||||||
if (BpOptions::schedule == BpOptions::Schedule::MAX_RESIDUAL) {
|
if (BpOptions::schedule == BpOptions::Schedule::MAX_RESIDUAL) {
|
||||||
Param maxResidual = (*(sortedOrder_.begin()))->getResidual();
|
double maxResidual = (*(sortedOrder_.begin()))->getResidual();
|
||||||
if (maxResidual > BpOptions::accuracy) {
|
if (maxResidual > BpOptions::accuracy) {
|
||||||
converged = false;
|
converged = false;
|
||||||
} else {
|
} else {
|
||||||
@ -374,40 +339,39 @@ FgBpSolver::calculateFactor2VariableMsg (SpLink* link) const
|
|||||||
msgSize *= links[i]->getVariable()->nrStates();
|
msgSize *= links[i]->getVariable()->nrStates();
|
||||||
}
|
}
|
||||||
unsigned repetitions = 1;
|
unsigned repetitions = 1;
|
||||||
ParamSet msgProduct (msgSize, Util::multIdenty());
|
Params msgProduct (msgSize, Util::multIdenty());
|
||||||
switch (NSPACE) {
|
if (Globals::logDomain) {
|
||||||
case NumberSpace::NORMAL:
|
for (int i = links.size() - 1; i >= 0; i--) {
|
||||||
for (int i = links.size() - 1; i >= 0; i--) {
|
if (links[i]->getVariable() != dst) {
|
||||||
if (links[i]->getVariable() != dst) {
|
Util::add (msgProduct, getVar2FactorMsg (links[i]), repetitions);
|
||||||
if (DL >= 5) {
|
repetitions *= links[i]->getVariable()->nrStates();
|
||||||
cout << " message from " << links[i]->getVariable()->label();
|
} else {
|
||||||
cout << ": " << endl;
|
unsigned ds = links[i]->getVariable()->nrStates();
|
||||||
}
|
Util::add (msgProduct, Params (ds, 1.0), repetitions);
|
||||||
Util::multiply (msgProduct, getVar2FactorMsg (links[i]), repetitions);
|
repetitions *= ds;
|
||||||
repetitions *= links[i]->getVariable()->nrStates();
|
|
||||||
} else {
|
|
||||||
unsigned ds = links[i]->getVariable()->nrStates();
|
|
||||||
Util::multiply (msgProduct, ParamSet (ds, 1.0), repetitions);
|
|
||||||
repetitions *= ds;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
case NumberSpace::LOGARITHM:
|
} else {
|
||||||
for (int i = links.size() - 1; i >= 0; i--) {
|
for (int i = links.size() - 1; i >= 0; i--) {
|
||||||
if (links[i]->getVariable() != dst) {
|
if (links[i]->getVariable() != dst) {
|
||||||
Util::add (msgProduct, getVar2FactorMsg (links[i]), repetitions);
|
if (DL >= 5) {
|
||||||
repetitions *= links[i]->getVariable()->nrStates();
|
cout << " message from " << links[i]->getVariable()->label();
|
||||||
} else {
|
cout << ": " << endl;
|
||||||
unsigned ds = links[i]->getVariable()->nrStates();
|
|
||||||
Util::add (msgProduct, ParamSet (ds, 1.0), repetitions);
|
|
||||||
repetitions *= ds;
|
|
||||||
}
|
}
|
||||||
|
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(),
|
Factor result (src->factor()->getVarIds(),
|
||||||
src->factor()->getRanges(),
|
src->factor()->getRanges(),
|
||||||
msgProduct);
|
msgProduct);
|
||||||
result.multiplyByFactor (*(src->factor()));
|
result.multiply (*(src->factor()));
|
||||||
if (DL >= 5) {
|
if (DL >= 5) {
|
||||||
cout << " message product: " ;
|
cout << " message product: " ;
|
||||||
cout << Util::parametersToString (msgProduct) << endl;
|
cout << Util::parametersToString (msgProduct) << endl;
|
||||||
@ -416,13 +380,13 @@ FgBpSolver::calculateFactor2VariableMsg (SpLink* link) const
|
|||||||
cout << " factor product: " ;
|
cout << " factor product: " ;
|
||||||
cout << Util::parametersToString (result.getParameters()) << endl;
|
cout << Util::parametersToString (result.getParameters()) << endl;
|
||||||
}
|
}
|
||||||
result.removeAllVariablesExcept (dst->varId());
|
result.sumOutAllExcept (dst->varId());
|
||||||
if (DL >= 5) {
|
if (DL >= 5) {
|
||||||
cout << " marginalized: " ;
|
cout << " marginalized: " ;
|
||||||
cout << Util::parametersToString (result.getParameters()) << endl;
|
cout << Util::parametersToString (result.getParameters()) << endl;
|
||||||
}
|
}
|
||||||
const ParamSet& resultParams = result.getParameters();
|
const Params& resultParams = result.getParameters();
|
||||||
ParamSet& message = link->getNextMessage();
|
Params& message = link->getNextMessage();
|
||||||
for (unsigned i = 0; i < resultParams.size(); i++) {
|
for (unsigned i = 0; i < resultParams.size(); i++) {
|
||||||
message[i] = resultParams[i];
|
message[i] = resultParams[i];
|
||||||
}
|
}
|
||||||
@ -433,17 +397,16 @@ FgBpSolver::calculateFactor2VariableMsg (SpLink* link) const
|
|||||||
cout << " next msg: " ;
|
cout << " next msg: " ;
|
||||||
cout << Util::parametersToString (message) << endl;
|
cout << Util::parametersToString (message) << endl;
|
||||||
}
|
}
|
||||||
result.freeDistribution();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ParamSet
|
Params
|
||||||
FgBpSolver::getVar2FactorMsg (const SpLink* link) const
|
FgBpSolver::getVar2FactorMsg (const SpLink* link) const
|
||||||
{
|
{
|
||||||
const FgVarNode* src = link->getVariable();
|
const FgVarNode* src = link->getVariable();
|
||||||
const FgFacNode* dst = link->getFactor();
|
const FgFacNode* dst = link->getFactor();
|
||||||
ParamSet msg;
|
Params msg;
|
||||||
if (src->hasEvidence()) {
|
if (src->hasEvidence()) {
|
||||||
msg.resize (src->nrStates(), Util::noEvidence());
|
msg.resize (src->nrStates(), Util::noEvidence());
|
||||||
msg[src->getEvidence()] = Util::withEvidence();
|
msg[src->getEvidence()] = Util::withEvidence();
|
||||||
@ -457,23 +420,21 @@ FgBpSolver::getVar2FactorMsg (const SpLink* link) const
|
|||||||
cout << Util::parametersToString (msg);
|
cout << Util::parametersToString (msg);
|
||||||
}
|
}
|
||||||
const SpLinkSet& links = ninf (src)->getLinks();
|
const SpLinkSet& links = ninf (src)->getLinks();
|
||||||
switch (NSPACE) {
|
if (Globals::logDomain) {
|
||||||
case NumberSpace::NORMAL:
|
for (unsigned i = 0; i < links.size(); i++) {
|
||||||
for (unsigned i = 0; i < links.size(); i++) {
|
if (links[i]->getFactor() != dst) {
|
||||||
if (links[i]->getFactor() != dst) {
|
Util::add (msg, links[i]->getMessage());
|
||||||
Util::multiply (msg, links[i]->getMessage());
|
}
|
||||||
if (DL >= 5) {
|
}
|
||||||
cout << " x " << Util::parametersToString (links[i]->getMessage());
|
} else {
|
||||||
}
|
for (unsigned i = 0; i < links.size(); i++) {
|
||||||
}
|
if (links[i]->getFactor() != dst) {
|
||||||
}
|
Util::multiply (msg, links[i]->getMessage());
|
||||||
break;
|
if (DL >= 5) {
|
||||||
case NumberSpace::LOGARITHM:
|
cout << " x " << Util::parametersToString (links[i]->getMessage());
|
||||||
for (unsigned i = 0; i < links.size(); i++) {
|
|
||||||
if (links[i]->getFactor() != dst) {
|
|
||||||
Util::add (msg, links[i]->getMessage());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (DL >= 5) {
|
if (DL >= 5) {
|
||||||
cout << " = " << Util::parametersToString (msg);
|
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
|
void
|
||||||
FgBpSolver::printLinkInformation (void) const
|
FgBpSolver::printLinkInformation (void) const
|
||||||
{
|
{
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include "Solver.h"
|
#include "Solver.h"
|
||||||
#include "Factor.h"
|
#include "Factor.h"
|
||||||
#include "FactorGraph.h"
|
#include "FactorGraph.h"
|
||||||
|
#include "Util.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
@ -52,8 +53,8 @@ class SpLink
|
|||||||
|
|
||||||
FgFacNode* getFactor (void) const { return fac_; }
|
FgFacNode* getFactor (void) const { return fac_; }
|
||||||
FgVarNode* getVariable (void) const { return var_; }
|
FgVarNode* getVariable (void) const { return var_; }
|
||||||
const ParamSet& getMessage (void) const { return *currMsg_; }
|
const Params& getMessage (void) const { return *currMsg_; }
|
||||||
ParamSet& getNextMessage (void) { return *nextMsg_; }
|
Params& getNextMessage (void) { return *nextMsg_; }
|
||||||
bool messageWasSended (void) const { return msgSended_; }
|
bool messageWasSended (void) const { return msgSended_; }
|
||||||
double getResidual (void) const { return residual_; }
|
double getResidual (void) const { return residual_; }
|
||||||
void clearResidual (void) { residual_ = 0.0; }
|
void clearResidual (void) { residual_ = 0.0; }
|
||||||
@ -61,10 +62,10 @@ class SpLink
|
|||||||
protected:
|
protected:
|
||||||
FgFacNode* fac_;
|
FgFacNode* fac_;
|
||||||
FgVarNode* var_;
|
FgVarNode* var_;
|
||||||
ParamSet v1_;
|
Params v1_;
|
||||||
ParamSet v2_;
|
Params v2_;
|
||||||
ParamSet* currMsg_;
|
Params* currMsg_;
|
||||||
ParamSet* nextMsg_;
|
Params* nextMsg_;
|
||||||
bool msgSended_;
|
bool msgSended_;
|
||||||
double residual_;
|
double residual_;
|
||||||
};
|
};
|
||||||
@ -91,15 +92,16 @@ class FgBpSolver : public Solver
|
|||||||
virtual ~FgBpSolver (void);
|
virtual ~FgBpSolver (void);
|
||||||
|
|
||||||
void runSolver (void);
|
void runSolver (void);
|
||||||
virtual ParamSet getPosterioriOf (VarId);
|
virtual Params getPosterioriOf (VarId);
|
||||||
virtual ParamSet getJointDistributionOf (const VarIdSet&);
|
virtual Params getJointDistributionOf (const VarIds&);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void initializeSolver (void);
|
virtual void initializeSolver (void);
|
||||||
virtual void createLinks (void);
|
virtual void createLinks (void);
|
||||||
virtual void maxResidualSchedule (void);
|
virtual void maxResidualSchedule (void);
|
||||||
virtual void calculateFactor2VariableMsg (SpLink*) const;
|
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;
|
virtual void printLinkInformation (void) const;
|
||||||
|
|
||||||
void calculateAndUpdateMessage (SpLink* link, bool calcResidual = true)
|
void calculateAndUpdateMessage (SpLink* link, bool calcResidual = true)
|
||||||
@ -163,8 +165,6 @@ class FgBpSolver : public Solver
|
|||||||
SpLinkMap linkMap_;
|
SpLinkMap linkMap_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void runTreeSolver (void);
|
|
||||||
bool readyToSendMessage (const SpLink*) const;
|
|
||||||
void runLoopySolver (void);
|
void runLoopySolver (void);
|
||||||
bool converged (void);
|
bool converged (void);
|
||||||
|
|
||||||
|
703
packages/CLPBN/clpbn/bp/FoveSolver.cpp
Normal file
703
packages/CLPBN/clpbn/bp/FoveSolver.cpp
Normal file
@ -0,0 +1,703 @@
|
|||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
#include "FoveSolver.h"
|
||||||
|
#include "Histogram.h"
|
||||||
|
#include "Util.h"
|
||||||
|
|
||||||
|
|
||||||
|
vector<LiftedOperator*>
|
||||||
|
LiftedOperator::getValidOps (ParfactorList& pfList, const Grounds& query)
|
||||||
|
{
|
||||||
|
vector<LiftedOperator*> validOps;
|
||||||
|
vector<SumOutOperator*> sumOutOps;
|
||||||
|
vector<CountingOperator*> countOps;
|
||||||
|
vector<GroundOperator*> groundOps;
|
||||||
|
|
||||||
|
sumOutOps = SumOutOperator::getValidOps (pfList, query);
|
||||||
|
countOps = CountingOperator::getValidOps (pfList);
|
||||||
|
groundOps = GroundOperator::getValidOps (pfList);
|
||||||
|
|
||||||
|
validOps.insert (validOps.end(), sumOutOps.begin(), sumOutOps.end());
|
||||||
|
validOps.insert (validOps.end(), countOps.begin(), countOps.end());
|
||||||
|
validOps.insert (validOps.end(), groundOps.begin(), groundOps.end());
|
||||||
|
return validOps;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
LiftedOperator::printValidOps (ParfactorList& pfList, const Grounds& query)
|
||||||
|
{
|
||||||
|
vector<LiftedOperator*> validOps;
|
||||||
|
validOps = LiftedOperator::getValidOps (pfList, query);
|
||||||
|
for (unsigned i = 0; i < validOps.size(); i++) {
|
||||||
|
cout << "-> " << validOps[i]->toString() << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
unsigned
|
||||||
|
SumOutOperator::getCost (void)
|
||||||
|
{
|
||||||
|
TinySet<unsigned> groupSet;
|
||||||
|
ParfactorList::const_iterator pfIter = pfList_.begin();
|
||||||
|
while (pfIter != pfList_.end()) {
|
||||||
|
if ((*pfIter)->containsGroup (group_)) {
|
||||||
|
vector<unsigned> groups = (*pfIter)->getAllGroups();
|
||||||
|
groupSet |= TinySet<unsigned> (groups);
|
||||||
|
}
|
||||||
|
++ pfIter;
|
||||||
|
}
|
||||||
|
unsigned cost = 1;
|
||||||
|
for (unsigned i = 0; i < groupSet.size(); i++) {
|
||||||
|
pfIter = pfList_.begin();
|
||||||
|
while (pfIter != pfList_.end()) {
|
||||||
|
if ((*pfIter)->containsGroup (groupSet[i])) {
|
||||||
|
int idx = (*pfIter)->indexOfFormulaWithGroup (groupSet[i]);
|
||||||
|
cost *= (*pfIter)->range (idx);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++ pfIter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cost;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
SumOutOperator::apply (void)
|
||||||
|
{
|
||||||
|
vector<ParfactorList::iterator> iters
|
||||||
|
= parfactorsWithGroup (pfList_, group_);
|
||||||
|
Parfactor* product = *(iters[0]);
|
||||||
|
pfList_.remove (iters[0]);
|
||||||
|
for (unsigned i = 1; i < iters.size(); i++) {
|
||||||
|
product->multiply (**(iters[i]));
|
||||||
|
delete *(iters[i]);
|
||||||
|
pfList_.remove (iters[i]);
|
||||||
|
}
|
||||||
|
if (product->nrFormulas() == 1) {
|
||||||
|
delete product;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int fIdx = product->indexOfFormulaWithGroup (group_);
|
||||||
|
LogVarSet excl = product->exclusiveLogVars (fIdx);
|
||||||
|
if (product->constr()->isCountNormalized (excl)) {
|
||||||
|
product->sumOut (fIdx);
|
||||||
|
pfList_.addShattered (product);
|
||||||
|
} else {
|
||||||
|
Parfactors pfs = FoveSolver::countNormalize (product, excl);
|
||||||
|
for (unsigned i = 0; i < pfs.size(); i++) {
|
||||||
|
pfs[i]->sumOut (fIdx);
|
||||||
|
pfList_.add (pfs[i]);
|
||||||
|
}
|
||||||
|
delete product;
|
||||||
|
pfList_.shatter();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
vector<SumOutOperator*>
|
||||||
|
SumOutOperator::getValidOps (ParfactorList& pfList, const Grounds& query)
|
||||||
|
{
|
||||||
|
vector<SumOutOperator*> validOps;
|
||||||
|
set<unsigned> allGroups;
|
||||||
|
ParfactorList::const_iterator it = pfList.begin();
|
||||||
|
while (it != pfList.end()) {
|
||||||
|
assert (*it);
|
||||||
|
const ProbFormulas& formulas = (*it)->formulas();
|
||||||
|
for (unsigned i = 0; i < formulas.size(); i++) {
|
||||||
|
allGroups.insert (formulas[i].group());
|
||||||
|
}
|
||||||
|
++ it;
|
||||||
|
}
|
||||||
|
set<unsigned>::const_iterator groupIt = allGroups.begin();
|
||||||
|
while (groupIt != allGroups.end()) {
|
||||||
|
if (validOp (*groupIt, pfList, query)) {
|
||||||
|
validOps.push_back (new SumOutOperator (*groupIt, pfList));
|
||||||
|
}
|
||||||
|
++ groupIt;
|
||||||
|
}
|
||||||
|
return validOps;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
string
|
||||||
|
SumOutOperator::toString (void)
|
||||||
|
{
|
||||||
|
stringstream ss;
|
||||||
|
vector<ParfactorList::iterator> pfIters;
|
||||||
|
pfIters = parfactorsWithGroup (pfList_, group_);
|
||||||
|
int idx = (*pfIters[0])->indexOfFormulaWithGroup (group_);
|
||||||
|
ProbFormula f = (*pfIters[0])->formula (idx);
|
||||||
|
TupleSet tupleSet = (*pfIters[0])->constr()->tupleSet (f.logVars());
|
||||||
|
ss << "sum out " << f.functor() << "/" << f.arity();
|
||||||
|
ss << "|" << tupleSet << " (group " << group_ << ")";
|
||||||
|
ss << " [cost=" << getCost() << "]" << endl;
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
SumOutOperator::validOp (
|
||||||
|
unsigned group,
|
||||||
|
ParfactorList& pfList,
|
||||||
|
const Grounds& query)
|
||||||
|
{
|
||||||
|
vector<ParfactorList::iterator> pfIters;
|
||||||
|
pfIters = parfactorsWithGroup (pfList, group);
|
||||||
|
if (isToEliminate (*pfIters[0], group, query) == false) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
unordered_map<unsigned, unsigned> groupToRange;
|
||||||
|
for (unsigned i = 0; i < pfIters.size(); i++) {
|
||||||
|
int fIdx = (*pfIters[i])->indexOfFormulaWithGroup (group);
|
||||||
|
if ((*pfIters[i])->formulas()[fIdx].contains (
|
||||||
|
(*pfIters[i])->elimLogVars()) == false) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
vector<unsigned> ranges = (*pfIters[i])->ranges();
|
||||||
|
vector<unsigned> groups = (*pfIters[i])->getAllGroups();
|
||||||
|
for (unsigned i = 0; i < groups.size(); i++) {
|
||||||
|
unordered_map<unsigned, unsigned>::iterator it;
|
||||||
|
it = groupToRange.find (groups[i]);
|
||||||
|
if (it == groupToRange.end()) {
|
||||||
|
groupToRange.insert (make_pair (groups[i], ranges[i]));
|
||||||
|
} else {
|
||||||
|
if (it->second != ranges[i]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
vector<ParfactorList::iterator>
|
||||||
|
SumOutOperator::parfactorsWithGroup (
|
||||||
|
ParfactorList& pfList,
|
||||||
|
unsigned group)
|
||||||
|
{
|
||||||
|
vector<ParfactorList::iterator> iters;
|
||||||
|
ParfactorList::iterator pflIt = pfList.begin();
|
||||||
|
while (pflIt != pfList.end()) {
|
||||||
|
if ((*pflIt)->containsGroup (group)) {
|
||||||
|
iters.push_back (pflIt);
|
||||||
|
}
|
||||||
|
++ pflIt;
|
||||||
|
}
|
||||||
|
return iters;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
SumOutOperator::isToEliminate (
|
||||||
|
Parfactor* g,
|
||||||
|
unsigned group,
|
||||||
|
const Grounds& query)
|
||||||
|
{
|
||||||
|
int fIdx = g->indexOfFormulaWithGroup (group);
|
||||||
|
const ProbFormula& formula = g->formula (fIdx);
|
||||||
|
bool toElim = true;
|
||||||
|
for (unsigned i = 0; i < query.size(); i++) {
|
||||||
|
if (formula.functor() == query[i].functor() &&
|
||||||
|
formula.arity() == query[i].arity()) {
|
||||||
|
g->constr()->moveToTop (formula.logVars());
|
||||||
|
if (g->constr()->containsTuple (query[i].args())) {
|
||||||
|
toElim = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return toElim;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
unsigned
|
||||||
|
CountingOperator::getCost (void)
|
||||||
|
{
|
||||||
|
unsigned cost = 0;
|
||||||
|
int fIdx = (*pfIter_)->indexOfFormulaWithLogVar (X_);
|
||||||
|
unsigned range = (*pfIter_)->range (fIdx);
|
||||||
|
unsigned size = (*pfIter_)->size() / range;
|
||||||
|
TinySet<unsigned> counts;
|
||||||
|
counts = (*pfIter_)->constr()->getConditionalCounts (X_);
|
||||||
|
for (unsigned i = 0; i < counts.size(); i++) {
|
||||||
|
cost += size * HistogramSet::nrHistograms (counts[i], range);
|
||||||
|
}
|
||||||
|
return cost;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
CountingOperator::apply (void)
|
||||||
|
{
|
||||||
|
if ((*pfIter_)->constr()->isCountNormalized (X_)) {
|
||||||
|
(*pfIter_)->countConvert (X_);
|
||||||
|
} else {
|
||||||
|
Parfactors pfs = FoveSolver::countNormalize (*pfIter_, X_);
|
||||||
|
for (unsigned i = 0; i < pfs.size(); i++) {
|
||||||
|
unsigned condCount = pfs[i]->constr()->getConditionalCount (X_);
|
||||||
|
bool cartProduct = pfs[i]->constr()->isCarteesianProduct (
|
||||||
|
(*pfIter_)->countedLogVars() | X_);
|
||||||
|
if (condCount > 1 && cartProduct) {
|
||||||
|
pfs[i]->countConvert (X_);
|
||||||
|
}
|
||||||
|
pfList_.add (pfs[i]);
|
||||||
|
}
|
||||||
|
pfList_.deleteAndRemove (pfIter_);
|
||||||
|
pfList_.shatter();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
vector<CountingOperator*>
|
||||||
|
CountingOperator::getValidOps (ParfactorList& pfList)
|
||||||
|
{
|
||||||
|
vector<CountingOperator*> validOps;
|
||||||
|
ParfactorList::iterator it = pfList.begin();
|
||||||
|
while (it != pfList.end()) {
|
||||||
|
LogVarSet candidates = (*it)->uncountedLogVars();
|
||||||
|
for (unsigned i = 0; i < candidates.size(); i++) {
|
||||||
|
if (validOp (*it, candidates[i])) {
|
||||||
|
validOps.push_back (new CountingOperator (
|
||||||
|
it, candidates[i], pfList));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
++ it;
|
||||||
|
}
|
||||||
|
return validOps;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
string
|
||||||
|
CountingOperator::toString (void)
|
||||||
|
{
|
||||||
|
stringstream ss;
|
||||||
|
ss << "count convert " << X_ << " in " ;
|
||||||
|
ss << (*pfIter_)->getHeaderString();
|
||||||
|
ss << " [cost=" << getCost() << "]" << endl;
|
||||||
|
Parfactors pfs = FoveSolver::countNormalize (*pfIter_, X_);
|
||||||
|
if ((*pfIter_)->constr()->isCountNormalized (X_) == false) {
|
||||||
|
for (unsigned i = 0; i < pfs.size(); i++) {
|
||||||
|
ss << " º " << pfs[i]->getHeaderString() << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
CountingOperator::validOp (Parfactor* g, LogVar X)
|
||||||
|
{
|
||||||
|
if (g->nrFormulas (X) != 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
int fIdx = g->indexOfFormulaWithLogVar (X);
|
||||||
|
if (g->formulas()[fIdx].isCounting()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool countNormalized = g->constr()->isCountNormalized (X);
|
||||||
|
if (countNormalized) {
|
||||||
|
unsigned condCount = g->constr()->getConditionalCount (X);
|
||||||
|
bool cartProduct = g->constr()->isCarteesianProduct (
|
||||||
|
g->countedLogVars() | X);
|
||||||
|
if (condCount == 1 || cartProduct == false) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
unsigned
|
||||||
|
GroundOperator::getCost (void)
|
||||||
|
{
|
||||||
|
unsigned cost = 0;
|
||||||
|
bool isCountingLv = (*pfIter_)->countedLogVars().contains (X_);
|
||||||
|
if (isCountingLv) {
|
||||||
|
int fIdx = (*pfIter_)->indexOfFormulaWithLogVar (X_);
|
||||||
|
unsigned currSize = (*pfIter_)->size();
|
||||||
|
unsigned nrHists = (*pfIter_)->range (fIdx);
|
||||||
|
unsigned range = (*pfIter_)->formula(fIdx).range();
|
||||||
|
unsigned nrSymbols = (*pfIter_)->constr()->getConditionalCount (X_);
|
||||||
|
cost = (currSize / nrHists) * (std::pow (range, nrSymbols));
|
||||||
|
} else {
|
||||||
|
cost = (*pfIter_)->constr()->nrSymbols (X_) * (*pfIter_)->size();
|
||||||
|
}
|
||||||
|
return cost;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
GroundOperator::apply (void)
|
||||||
|
{
|
||||||
|
bool countedLv = (*pfIter_)->countedLogVars().contains (X_);
|
||||||
|
if (countedLv) {
|
||||||
|
(*pfIter_)->fullExpand (X_);
|
||||||
|
(*pfIter_)->setNewGroups();
|
||||||
|
pfList_.shatter();
|
||||||
|
} else {
|
||||||
|
ConstraintTrees cts = (*pfIter_)->constr()->ground (X_);
|
||||||
|
for (unsigned i = 0; i < cts.size(); i++) {
|
||||||
|
Parfactor* newPf = new Parfactor (*pfIter_, cts[i]);
|
||||||
|
pfList_.add (newPf);
|
||||||
|
}
|
||||||
|
pfList_.deleteAndRemove (pfIter_);
|
||||||
|
pfList_.shatter();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
vector<GroundOperator*>
|
||||||
|
GroundOperator::getValidOps (ParfactorList& pfList)
|
||||||
|
{
|
||||||
|
vector<GroundOperator*> validOps;
|
||||||
|
ParfactorList::iterator pfIter = pfList.begin();
|
||||||
|
while (pfIter != pfList.end()) {
|
||||||
|
LogVarSet set = (*pfIter)->logVarSet();
|
||||||
|
for (unsigned i = 0; i < set.size(); i++) {
|
||||||
|
if ((*pfIter)->constr()->isSingleton (set[i]) == false) {
|
||||||
|
validOps.push_back (new GroundOperator (pfIter, set[i], pfList));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
++ pfIter;
|
||||||
|
}
|
||||||
|
return validOps;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
string
|
||||||
|
GroundOperator::toString (void)
|
||||||
|
{
|
||||||
|
stringstream ss;
|
||||||
|
((*pfIter_)->countedLogVars().contains (X_))
|
||||||
|
? ss << "full expanding "
|
||||||
|
: ss << "grounding " ;
|
||||||
|
ss << X_ << " in " << (*pfIter_)->getHeaderString();
|
||||||
|
ss << " [cost=" << getCost() << "]" << endl;
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
FoveSolver::FoveSolver (const ParfactorList* pfList)
|
||||||
|
{
|
||||||
|
for (ParfactorList::const_iterator it = pfList->begin();
|
||||||
|
it != pfList->end();
|
||||||
|
it ++) {
|
||||||
|
pfList_.addShattered (new Parfactor (**it));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Params
|
||||||
|
FoveSolver::getPosterioriOf (const Ground& query)
|
||||||
|
{
|
||||||
|
return getJointDistributionOf ({query});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Params
|
||||||
|
FoveSolver::getJointDistributionOf (const Grounds& query)
|
||||||
|
{
|
||||||
|
shatterAgainstQuery (query);
|
||||||
|
runSolver (query);
|
||||||
|
(*pfList_.begin())->normalize();
|
||||||
|
Params params = (*pfList_.begin())->params();
|
||||||
|
if (Globals::logDomain) {
|
||||||
|
Util::fromLog (params);
|
||||||
|
}
|
||||||
|
delete *pfList_.begin();
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
FoveSolver::absorveEvidence (
|
||||||
|
ParfactorList& pfList,
|
||||||
|
const ObservedFormulas& obsFormulas)
|
||||||
|
{
|
||||||
|
ParfactorList::iterator it = pfList.begin();
|
||||||
|
while (it != pfList.end()) {
|
||||||
|
bool increment = true;
|
||||||
|
for (unsigned i = 0; i < obsFormulas.size(); i++) {
|
||||||
|
if (absorved (pfList, it, obsFormulas[i])) {
|
||||||
|
it = pfList.deleteAndRemove (it);
|
||||||
|
increment = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (increment) {
|
||||||
|
++ it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pfList.shatter();
|
||||||
|
if (obsFormulas.empty() == false) {
|
||||||
|
cout << "*******************************************************" << endl;
|
||||||
|
cout << "AFTER EVIDENCE ABSORVED" << endl;
|
||||||
|
for (unsigned i = 0; i < obsFormulas.size(); i++) {
|
||||||
|
cout << " -> " << *obsFormulas[i] << endl;
|
||||||
|
}
|
||||||
|
cout << "*******************************************************" << endl;
|
||||||
|
}
|
||||||
|
pfList.print();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Parfactors
|
||||||
|
FoveSolver::countNormalize (
|
||||||
|
Parfactor* g,
|
||||||
|
const LogVarSet& set)
|
||||||
|
{
|
||||||
|
if (set.empty()) {
|
||||||
|
assert (false); // TODO
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
Parfactors normPfs;
|
||||||
|
ConstraintTrees normCts = g->constr()->countNormalize (set);
|
||||||
|
for (unsigned i = 0; i < normCts.size(); i++) {
|
||||||
|
normPfs.push_back (new Parfactor (g, normCts[i]));
|
||||||
|
}
|
||||||
|
return normPfs;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
FoveSolver::runSolver (const Grounds& query)
|
||||||
|
{
|
||||||
|
while (true) {
|
||||||
|
cout << "---------------------------------------------------" << endl;
|
||||||
|
pfList_.print();
|
||||||
|
LiftedOperator::printValidOps (pfList_, query);
|
||||||
|
LiftedOperator* op = getBestOperation (query);
|
||||||
|
if (op == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
cout << "best operation: " << op->toString() << endl;
|
||||||
|
op->apply();
|
||||||
|
}
|
||||||
|
if (pfList_.size() > 1) {
|
||||||
|
ParfactorList::iterator pfIter = pfList_.begin();
|
||||||
|
pfIter ++;
|
||||||
|
while (pfIter != pfList_.end()) {
|
||||||
|
(*pfList_.begin())->multiply (**pfIter);
|
||||||
|
++ pfIter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(*pfList_.begin())->reorderAccordingGrounds (query);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
FoveSolver::allEliminated (const Grounds&)
|
||||||
|
{
|
||||||
|
ParfactorList::iterator pfIter = pfList_.begin();
|
||||||
|
while (pfIter != pfList_.end()) {
|
||||||
|
const ProbFormulas formulas = (*pfIter)->formulas();
|
||||||
|
for (unsigned i = 0; i < formulas.size(); i++) {
|
||||||
|
//bool toElim = false;
|
||||||
|
//for (unsigned j = 0; j < queries.size(); j++) {
|
||||||
|
// if ((*pfIter)->containsGround (queries[i]) == false) {
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
++ pfIter;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
LiftedOperator*
|
||||||
|
FoveSolver::getBestOperation (const Grounds& query)
|
||||||
|
{
|
||||||
|
unsigned bestCost;
|
||||||
|
LiftedOperator* bestOp = 0;
|
||||||
|
vector<LiftedOperator*> validOps;
|
||||||
|
validOps = LiftedOperator::getValidOps (pfList_, query);
|
||||||
|
for (unsigned i = 0; i < validOps.size(); i++) {
|
||||||
|
unsigned cost = validOps[i]->getCost();
|
||||||
|
if ((bestOp == 0) || (cost < bestCost)) {
|
||||||
|
bestOp = validOps[i];
|
||||||
|
bestCost = cost;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return bestOp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
FoveSolver::shatterAgainstQuery (const Grounds& query)
|
||||||
|
{
|
||||||
|
// return;
|
||||||
|
for (unsigned i = 0; i < query.size(); i++) {
|
||||||
|
if (query[i].isAtom()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ParfactorList pfListCopy = pfList_;
|
||||||
|
pfList_.clear();
|
||||||
|
for (ParfactorList::iterator it = pfListCopy.begin();
|
||||||
|
it != pfListCopy.end(); ++ it) {
|
||||||
|
Parfactor* pf = *it;
|
||||||
|
if (pf->containsGround (query[i])) {
|
||||||
|
std::pair<ConstraintTree*, ConstraintTree*> split =
|
||||||
|
pf->constr()->split (query[i].args(), query[i].arity());
|
||||||
|
ConstraintTree* commCt = split.first;
|
||||||
|
ConstraintTree* exclCt = split.second;
|
||||||
|
pfList_.add (new Parfactor (pf, commCt));
|
||||||
|
if (exclCt->empty() == false) {
|
||||||
|
pfList_.add (new Parfactor (pf, exclCt));
|
||||||
|
} else {
|
||||||
|
delete exclCt;
|
||||||
|
}
|
||||||
|
delete pf;
|
||||||
|
} else {
|
||||||
|
pfList_.add (pf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pfList_.shatter();
|
||||||
|
}
|
||||||
|
cout << endl;
|
||||||
|
cout << "*******************************************************" << endl;
|
||||||
|
cout << "SHATTERED AGAINST THE QUERY" << endl;
|
||||||
|
for (unsigned i = 0; i < query.size(); i++) {
|
||||||
|
cout << " -> " << query[i] << endl;
|
||||||
|
}
|
||||||
|
cout << "*******************************************************" << endl;
|
||||||
|
pfList_.print();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
FoveSolver::absorved (
|
||||||
|
ParfactorList& pfList,
|
||||||
|
ParfactorList::iterator pfIter,
|
||||||
|
const ObservedFormula* obsFormula)
|
||||||
|
{
|
||||||
|
Parfactors absorvedPfs;
|
||||||
|
Parfactor* g = *pfIter;
|
||||||
|
const ProbFormulas& formulas = g->formulas();
|
||||||
|
for (unsigned i = 0; i < formulas.size(); i++) {
|
||||||
|
if (obsFormula->functor() == formulas[i].functor() &&
|
||||||
|
obsFormula->arity() == formulas[i].arity()) {
|
||||||
|
|
||||||
|
if (obsFormula->isAtom()) {
|
||||||
|
if (formulas.size() > 1) {
|
||||||
|
g->absorveEvidence (i, obsFormula->evidence());
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g->constr()->moveToTop (formulas[i].logVars());
|
||||||
|
std::pair<ConstraintTree*, ConstraintTree*> res
|
||||||
|
= g->constr()->split (obsFormula->constr(), formulas[i].arity());
|
||||||
|
ConstraintTree* commCt = res.first;
|
||||||
|
ConstraintTree* exclCt = res.second;
|
||||||
|
|
||||||
|
if (commCt->empty()) {
|
||||||
|
delete commCt;
|
||||||
|
delete exclCt;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exclCt->empty() == false) {
|
||||||
|
pfList.add (new Parfactor (g, exclCt));
|
||||||
|
} else {
|
||||||
|
delete exclCt;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (formulas.size() > 1) {
|
||||||
|
LogVarSet excl = g->exclusiveLogVars (i);
|
||||||
|
Parfactors countNormPfs = countNormalize (g, excl);
|
||||||
|
for (unsigned j = 0; j < countNormPfs.size(); j++) {
|
||||||
|
countNormPfs[j]->absorveEvidence (i, obsFormula->evidence());
|
||||||
|
absorvedPfs.push_back (countNormPfs[j]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
delete commCt;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
FoveSolver::proper (
|
||||||
|
const ProbFormula& f1,
|
||||||
|
ConstraintTree* c1,
|
||||||
|
const ProbFormula& f2,
|
||||||
|
ConstraintTree* c2)
|
||||||
|
{
|
||||||
|
return disjoint (f1, c1, f2, c2)
|
||||||
|
|| identical (f1, c1, f2, c2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
FoveSolver::identical (
|
||||||
|
const ProbFormula& f1,
|
||||||
|
ConstraintTree* c1,
|
||||||
|
const ProbFormula& f2,
|
||||||
|
ConstraintTree* c2)
|
||||||
|
{
|
||||||
|
if (f1.sameSkeletonAs (f2) == false) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
c1->moveToTop (f1.logVars());
|
||||||
|
c2->moveToTop (f2.logVars());
|
||||||
|
return ConstraintTree::identical (
|
||||||
|
c1, c2, f1.logVars().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
FoveSolver::disjoint (
|
||||||
|
const ProbFormula& f1,
|
||||||
|
ConstraintTree* c1,
|
||||||
|
const ProbFormula& f2,
|
||||||
|
ConstraintTree* c2)
|
||||||
|
{
|
||||||
|
if (f1.sameSkeletonAs (f2) == false) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
c1->moveToTop (f1.logVars());
|
||||||
|
c2->moveToTop (f2.logVars());
|
||||||
|
return ConstraintTree::overlap (
|
||||||
|
c1, c2, f1.arity()) == false;
|
||||||
|
}
|
||||||
|
|
132
packages/CLPBN/clpbn/bp/FoveSolver.h
Normal file
132
packages/CLPBN/clpbn/bp/FoveSolver.h
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
#ifndef HORUS_FOVESOLVER_H
|
||||||
|
#define HORUS_FOVESOLVER_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "ParfactorList.h"
|
||||||
|
|
||||||
|
|
||||||
|
class LiftedOperator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual unsigned getCost (void) = 0;
|
||||||
|
virtual void apply (void) = 0;
|
||||||
|
virtual string toString (void) = 0;
|
||||||
|
static vector<LiftedOperator*> getValidOps (
|
||||||
|
ParfactorList&, const Grounds&);
|
||||||
|
static void printValidOps (ParfactorList&, const Grounds&);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class SumOutOperator : public LiftedOperator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SumOutOperator (unsigned group, ParfactorList& pfList)
|
||||||
|
: group_(group), pfList_(pfList) { }
|
||||||
|
unsigned getCost (void);
|
||||||
|
void apply (void);
|
||||||
|
static vector<SumOutOperator*> getValidOps (
|
||||||
|
ParfactorList&, const Grounds&);
|
||||||
|
string toString (void);
|
||||||
|
private:
|
||||||
|
static bool validOp (unsigned, ParfactorList&, const Grounds&);
|
||||||
|
static vector<ParfactorList::iterator> parfactorsWithGroup (
|
||||||
|
ParfactorList& pfList, unsigned group);
|
||||||
|
static bool isToEliminate (Parfactor*, unsigned, const Grounds&);
|
||||||
|
unsigned group_;
|
||||||
|
ParfactorList& pfList_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class CountingOperator : public LiftedOperator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CountingOperator (
|
||||||
|
ParfactorList::iterator pfIter,
|
||||||
|
LogVar X,
|
||||||
|
ParfactorList& pfList)
|
||||||
|
: pfIter_(pfIter), X_(X), pfList_(pfList) { }
|
||||||
|
unsigned getCost (void);
|
||||||
|
void apply (void);
|
||||||
|
static vector<CountingOperator*> getValidOps (ParfactorList&);
|
||||||
|
string toString (void);
|
||||||
|
private:
|
||||||
|
static bool validOp (Parfactor*, LogVar);
|
||||||
|
ParfactorList::iterator pfIter_;
|
||||||
|
LogVar X_;
|
||||||
|
ParfactorList& pfList_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class GroundOperator : public LiftedOperator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GroundOperator (
|
||||||
|
ParfactorList::iterator pfIter,
|
||||||
|
LogVar X,
|
||||||
|
ParfactorList& pfList)
|
||||||
|
: pfIter_(pfIter), X_(X), pfList_(pfList) { }
|
||||||
|
unsigned getCost (void);
|
||||||
|
void apply (void);
|
||||||
|
static vector<GroundOperator*> getValidOps (ParfactorList&);
|
||||||
|
string toString (void);
|
||||||
|
private:
|
||||||
|
ParfactorList::iterator pfIter_;
|
||||||
|
LogVar X_;
|
||||||
|
ParfactorList& pfList_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class FoveSolver
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FoveSolver (const ParfactorList*);
|
||||||
|
|
||||||
|
Params getPosterioriOf (const Ground&);
|
||||||
|
Params getJointDistributionOf (const Grounds&);
|
||||||
|
|
||||||
|
static void absorveEvidence (
|
||||||
|
ParfactorList& pfList,
|
||||||
|
const ObservedFormulas& obsFormulas);
|
||||||
|
|
||||||
|
static Parfactors countNormalize (Parfactor*, const LogVarSet&);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void runSolver (const Grounds&);
|
||||||
|
bool allEliminated (const Grounds&);
|
||||||
|
LiftedOperator* getBestOperation (const Grounds&);
|
||||||
|
void shatterAgainstQuery (const Grounds&);
|
||||||
|
|
||||||
|
static bool absorved (
|
||||||
|
ParfactorList& pfList,
|
||||||
|
ParfactorList::iterator pfIter,
|
||||||
|
const ObservedFormula*);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
static bool proper (
|
||||||
|
const ProbFormula&,
|
||||||
|
ConstraintTree*,
|
||||||
|
const ProbFormula&,
|
||||||
|
ConstraintTree*);
|
||||||
|
|
||||||
|
static bool identical (
|
||||||
|
const ProbFormula&,
|
||||||
|
ConstraintTree*,
|
||||||
|
const ProbFormula&,
|
||||||
|
ConstraintTree*);
|
||||||
|
|
||||||
|
static bool disjoint (
|
||||||
|
const ProbFormula&,
|
||||||
|
ConstraintTree*,
|
||||||
|
const ProbFormula&,
|
||||||
|
ConstraintTree*);
|
||||||
|
|
||||||
|
ParfactorList pfList_;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // HORUS_FOVESOLVER_H
|
||||||
|
|
@ -1,11 +1,15 @@
|
|||||||
#ifndef HORUS_GRAPHICALMODEL_H
|
#ifndef HORUS_GRAPHICALMODEL_H
|
||||||
#define HORUS_GRAPHICALMODEL_H
|
#define HORUS_GRAPHICALMODEL_H
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
#include "VarNode.h"
|
#include "VarNode.h"
|
||||||
#include "Shared.h"
|
#include "Distribution.h"
|
||||||
|
#include "Horus.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
|
||||||
struct VariableInfo
|
struct VariableInfo
|
||||||
{
|
{
|
||||||
VariableInfo (string l, const States& sts)
|
VariableInfo (string l, const States& sts)
|
||||||
@ -45,9 +49,18 @@ class GraphicalModel
|
|||||||
{
|
{
|
||||||
varsInfo_.clear();
|
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:
|
private:
|
||||||
static unordered_map<VarId,VariableInfo> varsInfo_;
|
static unordered_map<VarId,VariableInfo> varsInfo_;
|
||||||
|
static unordered_map<unsigned,Distribution*> distsInfo_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // HORUS_GRAPHICALMODEL_H
|
#endif // HORUS_GRAPHICALMODEL_H
|
||||||
|
126
packages/CLPBN/clpbn/bp/Histogram.cpp
Normal file
126
packages/CLPBN/clpbn/bp/Histogram.cpp
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <numeric>
|
||||||
|
|
||||||
|
#include "Histogram.h"
|
||||||
|
#include "Util.h"
|
||||||
|
|
||||||
|
|
||||||
|
HistogramSet::HistogramSet (unsigned size, unsigned range)
|
||||||
|
{
|
||||||
|
size_ = size;
|
||||||
|
hist_.resize (range, 0);
|
||||||
|
hist_[0] = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
HistogramSet::nextHistogram (void)
|
||||||
|
{
|
||||||
|
for (int i = hist_.size() - 2; i >= 0; i--) {
|
||||||
|
if (hist_[i] > 0) {
|
||||||
|
hist_[i] --;
|
||||||
|
hist_[i + 1] = maxCount (i + 1);
|
||||||
|
clearAfter (i + 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert (std::accumulate (hist_.begin(), hist_.end(), 0) == (int)size_);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
unsigned
|
||||||
|
HistogramSet::operator[] (unsigned idx) const
|
||||||
|
{
|
||||||
|
assert (idx < hist_.size());
|
||||||
|
return hist_[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
unsigned
|
||||||
|
HistogramSet::nrHistograms (void) const
|
||||||
|
{
|
||||||
|
return Util::nrCombinations (size_ + hist_.size() - 1, hist_.size() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
HistogramSet::reset (void)
|
||||||
|
{
|
||||||
|
std::fill (hist_.begin() + 1, hist_.end(), 0);
|
||||||
|
hist_[0] = size_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
vector<Histogram>
|
||||||
|
HistogramSet::getHistograms (unsigned N, unsigned R)
|
||||||
|
{
|
||||||
|
HistogramSet hs (N, R);
|
||||||
|
unsigned H = hs.nrHistograms();
|
||||||
|
vector<Histogram> histograms;
|
||||||
|
histograms.reserve (H);
|
||||||
|
for (unsigned i = 0; i < H; i++) {
|
||||||
|
histograms.push_back (hs.hist_);
|
||||||
|
hs.nextHistogram();
|
||||||
|
}
|
||||||
|
return histograms;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
unsigned
|
||||||
|
HistogramSet::nrHistograms (unsigned N, unsigned R)
|
||||||
|
{
|
||||||
|
return Util::nrCombinations (N + R - 1, R - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
unsigned
|
||||||
|
HistogramSet::findIndex (
|
||||||
|
const Histogram& hist,
|
||||||
|
const vector<Histogram>& histograms)
|
||||||
|
{
|
||||||
|
vector<Histogram>::const_iterator it = std::lower_bound (
|
||||||
|
histograms.begin(),
|
||||||
|
histograms.end(),
|
||||||
|
hist,
|
||||||
|
std::greater<Histogram>());
|
||||||
|
assert (it != histograms.end() && *it == hist);
|
||||||
|
return std::distance (histograms.begin(), it);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ostream& operator<< (ostream &os, const HistogramSet& hs)
|
||||||
|
{
|
||||||
|
os << "#" << hs.hist_;
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
unsigned
|
||||||
|
HistogramSet::maxCount (unsigned idx) const
|
||||||
|
{
|
||||||
|
unsigned sum = 0;
|
||||||
|
for (unsigned i = 0; i < idx; i++) {
|
||||||
|
sum += hist_[i];
|
||||||
|
}
|
||||||
|
return size_ - sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
HistogramSet::clearAfter (unsigned idx)
|
||||||
|
{
|
||||||
|
std::fill (hist_.begin() + idx + 1, hist_.end(), 0);
|
||||||
|
}
|
||||||
|
|
44
packages/CLPBN/clpbn/bp/Histogram.h
Normal file
44
packages/CLPBN/clpbn/bp/Histogram.h
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
#ifndef HORUS_HISTOGRAM_H
|
||||||
|
#define HORUS_HISTOGRAM_H
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <ostream>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
typedef vector<unsigned> Histogram;
|
||||||
|
|
||||||
|
class HistogramSet
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HistogramSet (unsigned, unsigned);
|
||||||
|
|
||||||
|
void nextHistogram (void);
|
||||||
|
|
||||||
|
unsigned operator[] (unsigned idx) const;
|
||||||
|
|
||||||
|
unsigned nrHistograms (void) const;
|
||||||
|
|
||||||
|
void reset (void);
|
||||||
|
|
||||||
|
static vector<Histogram> getHistograms (unsigned ,unsigned);
|
||||||
|
|
||||||
|
static unsigned nrHistograms (unsigned, unsigned);
|
||||||
|
|
||||||
|
static unsigned findIndex (
|
||||||
|
const Histogram&,
|
||||||
|
const vector<Histogram>&);
|
||||||
|
|
||||||
|
friend std::ostream& operator<< (ostream &os, const HistogramSet& hs);
|
||||||
|
|
||||||
|
private:
|
||||||
|
unsigned maxCount (unsigned) const;
|
||||||
|
|
||||||
|
void clearAfter (unsigned);
|
||||||
|
|
||||||
|
unsigned size_;
|
||||||
|
Histogram hist_;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // HORUS_HISTOGRAM_H
|
||||||
|
|
88
packages/CLPBN/clpbn/bp/Horus.h
Normal file
88
packages/CLPBN/clpbn/bp/Horus.h
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
#ifndef HORUS_HORUS_H
|
||||||
|
#define HORUS_HORUS_H
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
#include <cassert>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <vector>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
|
||||||
|
TypeName(const TypeName&); \
|
||||||
|
void operator=(const TypeName&)
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
class VarNode;
|
||||||
|
class BayesNode;
|
||||||
|
class FgVarNode;
|
||||||
|
class FgFacNode;
|
||||||
|
class Factor;
|
||||||
|
|
||||||
|
typedef vector<double> Params;
|
||||||
|
typedef unsigned VarId;
|
||||||
|
typedef vector<VarId> VarIds;
|
||||||
|
typedef vector<VarNode*> VarNodes;
|
||||||
|
typedef vector<BayesNode*> BnNodeSet;
|
||||||
|
typedef vector<FgVarNode*> FgVarSet;
|
||||||
|
typedef vector<FgFacNode*> FgFacSet;
|
||||||
|
typedef vector<Factor*> FactorSet;
|
||||||
|
typedef vector<string> States;
|
||||||
|
typedef vector<unsigned> Ranges;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Globals {
|
||||||
|
extern bool logDomain;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// level of debug information
|
||||||
|
static const unsigned DL = 1;
|
||||||
|
|
||||||
|
static const int NO_EVIDENCE = -1;
|
||||||
|
|
||||||
|
// number of digits to show when printing a parameter
|
||||||
|
static const unsigned PRECISION = 5;
|
||||||
|
|
||||||
|
static const bool COLLECT_STATISTICS = false;
|
||||||
|
|
||||||
|
static const bool EXPORT_TO_GRAPHVIZ = false;
|
||||||
|
static const unsigned EXPORT_MINIMAL_SIZE = 100;
|
||||||
|
|
||||||
|
static const double INF = -numeric_limits<double>::infinity();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace InfAlgorithms {
|
||||||
|
enum InfAlgs
|
||||||
|
{
|
||||||
|
VE, // variable elimination
|
||||||
|
BN_BP, // bayesian network belief propagation
|
||||||
|
FG_BP, // factor graph belief propagation
|
||||||
|
CBP // counting bp solver
|
||||||
|
};
|
||||||
|
extern InfAlgs infAlgorithm;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
namespace BpOptions
|
||||||
|
{
|
||||||
|
enum Schedule {
|
||||||
|
SEQ_FIXED,
|
||||||
|
SEQ_RANDOM,
|
||||||
|
PARALLEL,
|
||||||
|
MAX_RESIDUAL
|
||||||
|
};
|
||||||
|
extern Schedule schedule;
|
||||||
|
extern double accuracy;
|
||||||
|
extern unsigned maxIter;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // HORUS_HORUS_H
|
||||||
|
|
@ -10,7 +10,9 @@
|
|||||||
#include "FgBpSolver.h"
|
#include "FgBpSolver.h"
|
||||||
#include "CbpSolver.h"
|
#include "CbpSolver.h"
|
||||||
|
|
||||||
#include "StatesIndexer.h"
|
//#include "TinySet.h"
|
||||||
|
#include "LiftedUtils.h"
|
||||||
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
@ -22,9 +24,38 @@ const string USAGE = "usage: \
|
|||||||
./hcli FILE [VARIABLE | OBSERVED_VARIABLE=EVIDENCE]..." ;
|
./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
|
int
|
||||||
main (int argc, const char* argv[])
|
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]) {
|
if (!argv[1]) {
|
||||||
cerr << "error: no graphical model specified" << endl;
|
cerr << "error: no graphical model specified" << endl;
|
||||||
cerr << USAGE << endl;
|
cerr << USAGE << endl;
|
||||||
@ -121,7 +152,6 @@ processArguments (BayesNet& bn, int argc, const char* argv[])
|
|||||||
break;
|
break;
|
||||||
case InfAlgorithms::FG_BP:
|
case InfAlgorithms::FG_BP:
|
||||||
fg = new FactorGraph (bn);
|
fg = new FactorGraph (bn);
|
||||||
fg->printGraphicalModel();
|
|
||||||
solver = new FgBpSolver (*fg);
|
solver = new FgBpSolver (*fg);
|
||||||
break;
|
break;
|
||||||
case InfAlgorithms::CBP:
|
case InfAlgorithms::CBP:
|
||||||
@ -230,6 +260,9 @@ processArguments (FactorGraph& fg, int argc, const char* argv[])
|
|||||||
break;
|
break;
|
||||||
case InfAlgorithms::BN_BP:
|
case InfAlgorithms::BN_BP:
|
||||||
case InfAlgorithms::FG_BP:
|
case InfAlgorithms::FG_BP:
|
||||||
|
//cout << "here!" << endl;
|
||||||
|
//fg.printGraphicalModel();
|
||||||
|
//fg.exportToLibDaiFormat ("net.fg");
|
||||||
solver = new FgBpSolver (fg);
|
solver = new FgBpSolver (fg);
|
||||||
break;
|
break;
|
||||||
case InfAlgorithms::CBP:
|
case InfAlgorithms::CBP:
|
||||||
@ -247,7 +280,7 @@ processArguments (FactorGraph& fg, int argc, const char* argv[])
|
|||||||
void
|
void
|
||||||
runSolver (Solver* solver, const VarNodes& queryVars)
|
runSolver (Solver* solver, const VarNodes& queryVars)
|
||||||
{
|
{
|
||||||
VarIdSet vids;
|
VarIds vids;
|
||||||
for (unsigned i = 0; i < queryVars.size(); i++) {
|
for (unsigned i = 0; i < queryVars.size(); i++) {
|
||||||
vids.push_back (queryVars[i]->varId());
|
vids.push_back (queryVars[i]->varId());
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@ -13,12 +14,169 @@
|
|||||||
#include "FgBpSolver.h"
|
#include "FgBpSolver.h"
|
||||||
#include "CbpSolver.h"
|
#include "CbpSolver.h"
|
||||||
#include "ElimGraph.h"
|
#include "ElimGraph.h"
|
||||||
|
#include "FoveSolver.h"
|
||||||
|
#include "ParfactorList.h"
|
||||||
|
|
||||||
|
|
||||||
using namespace std;
|
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
|
int
|
||||||
createNetwork (void)
|
createGroundNetwork (void)
|
||||||
{
|
{
|
||||||
Statistics::incrementPrimaryNetworksCounting();
|
Statistics::incrementPrimaryNetworksCounting();
|
||||||
// cout << "creating network number " ;
|
// cout << "creating network number " ;
|
||||||
@ -29,15 +187,15 @@ createNetwork (void)
|
|||||||
BayesNet* bn = new BayesNet();
|
BayesNet* bn = new BayesNet();
|
||||||
YAP_Term varList = YAP_ARG1;
|
YAP_Term varList = YAP_ARG1;
|
||||||
BnNodeSet nodes;
|
BnNodeSet nodes;
|
||||||
vector<VarIdSet> parents;
|
vector<VarIds> parents;
|
||||||
while (varList != YAP_TermNil()) {
|
while (varList != YAP_TermNil()) {
|
||||||
YAP_Term var = YAP_HeadOfTerm (varList);
|
YAP_Term var = YAP_HeadOfTerm (varList);
|
||||||
VarId vid = (VarId) YAP_IntOfTerm (YAP_ArgOfTerm (1, var));
|
VarId vid = (VarId) YAP_IntOfTerm (YAP_ArgOfTerm (1, var));
|
||||||
unsigned dsize = (unsigned) YAP_IntOfTerm (YAP_ArgOfTerm (2, var));
|
unsigned dsize = (unsigned) YAP_IntOfTerm (YAP_ArgOfTerm (2, var));
|
||||||
int evidence = (int) YAP_IntOfTerm (YAP_ArgOfTerm (3, var));
|
int evidence = (int) YAP_IntOfTerm (YAP_ArgOfTerm (3, var));
|
||||||
YAP_Term parentL = YAP_ArgOfTerm (4, var);
|
YAP_Term parentL = YAP_ArgOfTerm (4, var);
|
||||||
unsigned distId = (unsigned) YAP_IntOfTerm (YAP_ArgOfTerm (5, var));
|
unsigned distId = (unsigned) YAP_IntOfTerm (YAP_ArgOfTerm (5, var));
|
||||||
parents.push_back (VarIdSet());
|
parents.push_back (VarIds());
|
||||||
while (parentL != YAP_TermNil()) {
|
while (parentL != YAP_TermNil()) {
|
||||||
unsigned parentId = (unsigned) YAP_IntOfTerm (YAP_HeadOfTerm (parentL));
|
unsigned parentId = (unsigned) YAP_IntOfTerm (YAP_HeadOfTerm (parentL));
|
||||||
parents.back().push_back (parentId);
|
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
|
int
|
||||||
setExtraVarsInfo (void)
|
setExtraVarsInfo (void)
|
||||||
{
|
{
|
||||||
@ -94,124 +457,7 @@ setExtraVarsInfo (void)
|
|||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
setParameters (void)
|
setHorusFlag (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)
|
|
||||||
{
|
{
|
||||||
string key ((char*) YAP_AtomName (YAP_AtomOfTerm (YAP_ARG1)));
|
string key ((char*) YAP_AtomName (YAP_AtomOfTerm (YAP_ARG1)));
|
||||||
if (key == "inf_alg") {
|
if (key == "inf_alg") {
|
||||||
@ -263,12 +509,23 @@ setSolverParameter (void)
|
|||||||
BpOptions::accuracy = (double) YAP_FloatOfTerm (YAP_ARG2);
|
BpOptions::accuracy = (double) YAP_FloatOfTerm (YAP_ARG2);
|
||||||
} else if (key == "max_iter") {
|
} else if (key == "max_iter") {
|
||||||
BpOptions::maxIter = (int) YAP_IntOfTerm (YAP_ARG2);
|
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)));
|
string value ((char*) YAP_AtomName (YAP_AtomOfTerm (YAP_ARG2)));
|
||||||
if (value == "true") {
|
if ( value == "true") {
|
||||||
BpOptions::useAlwaysLoopySolver = true;
|
Globals::logDomain = true;
|
||||||
} else if (value == "false") {
|
} 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 {
|
} else {
|
||||||
cerr << "warning: invalid value `" << value << "' " ;
|
cerr << "warning: invalid value `" << value << "' " ;
|
||||||
cerr << "for `" << key << "'" << endl;
|
cerr << "for `" << key << "'" << endl;
|
||||||
@ -283,14 +540,6 @@ setSolverParameter (void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
int useLogSpace (void)
|
|
||||||
{
|
|
||||||
NSPACE = NumberSpace::LOGARITHM;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
freeBayesNetwork (void)
|
freeBayesNetwork (void)
|
||||||
{
|
{
|
||||||
@ -303,15 +552,27 @@ freeBayesNetwork (void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
freeParfactorGraph (void)
|
||||||
|
{
|
||||||
|
delete (ParfactorList*) YAP_IntOfTerm (YAP_ARG1);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
extern "C" void
|
extern "C" void
|
||||||
init_predicates (void)
|
init_predicates (void)
|
||||||
{
|
{
|
||||||
YAP_UserCPredicate ("create_network", createNetwork, 2);
|
YAP_UserCPredicate ("create_lifted_network", createLiftedNetwork, 3);
|
||||||
YAP_UserCPredicate ("set_extra_vars_info", setExtraVarsInfo, 2);
|
YAP_UserCPredicate ("create_ground_network", createGroundNetwork, 2);
|
||||||
YAP_UserCPredicate ("set_parameters", setParameters, 2);
|
YAP_UserCPredicate ("set_parfactor_graph_params", setParfactorGraphParams, 2);
|
||||||
YAP_UserCPredicate ("run_solver", runSolver, 3);
|
YAP_UserCPredicate ("set_bayes_net_params", setBayesNetParams, 2);
|
||||||
YAP_UserCPredicate ("set_solver_parameter", setSolverParameter, 2);
|
YAP_UserCPredicate ("run_lifted_solver", runLiftedSolver, 3);
|
||||||
YAP_UserCPredicate ("use_log_space", useLogSpace, 0);
|
YAP_UserCPredicate ("run_other_solvers", runOtherSolvers, 3);
|
||||||
YAP_UserCPredicate ("free_bayesian_network", freeBayesNetwork, 1);
|
YAP_UserCPredicate ("set_extra_vars_info", setExtraVarsInfo, 2);
|
||||||
|
YAP_UserCPredicate ("set_horus_flag", setHorusFlag, 2);
|
||||||
|
YAP_UserCPredicate ("free_bayesian_network", freeBayesNetwork, 1);
|
||||||
|
YAP_UserCPredicate ("free_parfactor_graph", freeParfactorGraph, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
301
packages/CLPBN/clpbn/bp/Indexer.h
Normal file
301
packages/CLPBN/clpbn/bp/Indexer.h
Normal file
@ -0,0 +1,301 @@
|
|||||||
|
#ifndef HORUS_STATESINDEXER_H
|
||||||
|
#define HORUS_STATESINDEXER_H
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <numeric>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
#include <iomanip>
|
||||||
|
|
||||||
|
#include "VarNode.h"
|
||||||
|
#include "Util.h"
|
||||||
|
|
||||||
|
|
||||||
|
class StatesIndexer {
|
||||||
|
public:
|
||||||
|
|
||||||
|
StatesIndexer (const Ranges& ranges, bool calcOffsets = true)
|
||||||
|
{
|
||||||
|
size_ = 1;
|
||||||
|
indices_.resize (ranges.size(), 0);
|
||||||
|
ranges_ = ranges;
|
||||||
|
for (unsigned i = 0; i < ranges.size(); i++) {
|
||||||
|
size_ *= ranges[i];
|
||||||
|
}
|
||||||
|
li_ = 0;
|
||||||
|
if (calcOffsets) {
|
||||||
|
calculateOffsets();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StatesIndexer (const VarNodes& vars, bool calcOffsets = true)
|
||||||
|
{
|
||||||
|
size_ = 1;
|
||||||
|
indices_.resize (vars.size(), 0);
|
||||||
|
ranges_.reserve (vars.size());
|
||||||
|
for (unsigned i = 0; i < vars.size(); i++) {
|
||||||
|
ranges_.push_back (vars[i]->nrStates());
|
||||||
|
size_ *= vars[i]->nrStates();
|
||||||
|
}
|
||||||
|
li_ = 0;
|
||||||
|
if (calcOffsets) {
|
||||||
|
calculateOffsets();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void increment (void)
|
||||||
|
{
|
||||||
|
for (int i = ranges_.size() - 1; i >= 0; i--) {
|
||||||
|
indices_[i] ++;
|
||||||
|
if (indices_[i] != ranges_[i]) {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
indices_[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
li_ ++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void increment (unsigned dim)
|
||||||
|
{
|
||||||
|
assert (dim < ranges_.size());
|
||||||
|
assert (ranges_.size() == offsets_.size());
|
||||||
|
assert (indices_[dim] < ranges_[dim]);
|
||||||
|
indices_[dim] ++;
|
||||||
|
li_ += offsets_[dim];
|
||||||
|
}
|
||||||
|
|
||||||
|
void incrementExcluding (unsigned skipDim)
|
||||||
|
{
|
||||||
|
assert (ranges_.size() == offsets_.size());
|
||||||
|
for (int i = ranges_.size() - 1; i >= 0; i--) {
|
||||||
|
if (i != (int)skipDim) {
|
||||||
|
indices_[i] ++;
|
||||||
|
li_ += offsets_[i];
|
||||||
|
if (indices_[i] != ranges_[i]) {
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
indices_[i] = 0;
|
||||||
|
li_ -= offsets_[i] * ranges_[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
li_ = size_;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned linearIndex (void) const
|
||||||
|
{
|
||||||
|
return li_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const vector<unsigned>& indices (void) const
|
||||||
|
{
|
||||||
|
return indices_;
|
||||||
|
}
|
||||||
|
|
||||||
|
StatesIndexer& operator ++ (void)
|
||||||
|
{
|
||||||
|
increment();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
operator unsigned (void) const
|
||||||
|
{
|
||||||
|
return li_;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned operator[] (unsigned dim) const
|
||||||
|
{
|
||||||
|
assert (valid());
|
||||||
|
assert (dim < ranges_.size());
|
||||||
|
return indices_[dim];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool valid (void) const
|
||||||
|
{
|
||||||
|
return li_ < size_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset (void)
|
||||||
|
{
|
||||||
|
std::fill (indices_.begin(), indices_.end(), 0);
|
||||||
|
li_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset (unsigned dim)
|
||||||
|
{
|
||||||
|
indices_[dim] = 0;
|
||||||
|
li_ -= offsets_[dim] * ranges_[dim];
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned size (void) const
|
||||||
|
{
|
||||||
|
return size_ ;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend ostream& operator<< (ostream &out, const StatesIndexer& idx)
|
||||||
|
{
|
||||||
|
out << "(" << std::setw (2) << std::setfill('0') << idx.li_ << ") " ;
|
||||||
|
out << idx.indices_;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void calculateOffsets (void)
|
||||||
|
{
|
||||||
|
unsigned prod = 1;
|
||||||
|
offsets_.resize (ranges_.size());
|
||||||
|
for (int i = ranges_.size() - 1; i >= 0; i--) {
|
||||||
|
offsets_[i] = prod;
|
||||||
|
prod *= ranges_[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned li_;
|
||||||
|
unsigned size_;
|
||||||
|
vector<unsigned> indices_;
|
||||||
|
vector<unsigned> ranges_;
|
||||||
|
vector<unsigned> offsets_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class MapIndexer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MapIndexer (const Ranges& ranges, const vector<bool>& mapDims)
|
||||||
|
{
|
||||||
|
assert (ranges.size() == mapDims.size());
|
||||||
|
unsigned prod = 1;
|
||||||
|
offsets_.resize (ranges.size());
|
||||||
|
for (int i = ranges.size() - 1; i >= 0; i--) {
|
||||||
|
if (mapDims[i]) {
|
||||||
|
offsets_[i] = prod;
|
||||||
|
prod *= ranges[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
indices_.resize (ranges.size(), 0);
|
||||||
|
ranges_ = ranges;
|
||||||
|
index_ = 0;
|
||||||
|
valid_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
MapIndexer (const Ranges& ranges, unsigned ignoreDim)
|
||||||
|
{
|
||||||
|
unsigned prod = 1;
|
||||||
|
offsets_.resize (ranges.size());
|
||||||
|
for (int i = ranges.size() - 1; i >= 0; i--) {
|
||||||
|
if (i != (int)ignoreDim) {
|
||||||
|
offsets_[i] = prod;
|
||||||
|
prod *= ranges[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
indices_.resize (ranges.size(), 0);
|
||||||
|
ranges_ = ranges;
|
||||||
|
index_ = 0;
|
||||||
|
valid_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
MapIndexer (
|
||||||
|
const VarIds& loopVids,
|
||||||
|
const Ranges& loopRanges,
|
||||||
|
const VarIds& mapVids,
|
||||||
|
const Ranges& mapRanges)
|
||||||
|
{
|
||||||
|
unsigned prod = 1;
|
||||||
|
vector<unsigned> offsets (mapRanges.size());
|
||||||
|
for (int i = mapRanges.size() - 1; i >= 0; i--) {
|
||||||
|
offsets[i] = prod;
|
||||||
|
prod *= mapRanges[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
offsets_.reserve (loopVids.size());
|
||||||
|
for (unsigned i = 0; i < loopVids.size(); i++) {
|
||||||
|
VarIds::const_iterator it =
|
||||||
|
std::find (mapVids.begin(), mapVids.end(), loopVids[i]);
|
||||||
|
if (it != mapVids.end()) {
|
||||||
|
offsets_.push_back (offsets[it - mapVids.begin()]);
|
||||||
|
} else {
|
||||||
|
offsets_.push_back (0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
indices_.resize (loopVids.size(), 0);
|
||||||
|
ranges_ = loopRanges;
|
||||||
|
index_ = 0;
|
||||||
|
size_ = prod;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
MapIndexer& operator ++ (void)
|
||||||
|
{
|
||||||
|
assert (valid_);
|
||||||
|
for (int i = ranges_.size() - 1; i >= 0; i--) {
|
||||||
|
indices_[i] ++;
|
||||||
|
index_ += offsets_[i];
|
||||||
|
if (indices_[i] != ranges_[i]) {
|
||||||
|
return *this;
|
||||||
|
} else {
|
||||||
|
indices_[i] = 0;
|
||||||
|
index_ -= offsets_[i] * ranges_[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
valid_ = false;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned mappedIndex (void) const
|
||||||
|
{
|
||||||
|
return index_;
|
||||||
|
}
|
||||||
|
|
||||||
|
operator unsigned (void) const
|
||||||
|
{
|
||||||
|
return index_;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned operator[] (unsigned dim) const
|
||||||
|
{
|
||||||
|
assert (valid());
|
||||||
|
assert (dim < ranges_.size());
|
||||||
|
return indices_[dim];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool valid (void) const
|
||||||
|
{
|
||||||
|
return valid_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset (void)
|
||||||
|
{
|
||||||
|
std::fill (indices_.begin(), indices_.end(), 0);
|
||||||
|
index_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend ostream& operator<< (ostream &out, const MapIndexer& idx)
|
||||||
|
{
|
||||||
|
out << "(" << std::setw (2) << std::setfill('0') << idx.index_ << ") " ;
|
||||||
|
out << idx.indices_;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
MapIndexer (const Ranges& ranges) :
|
||||||
|
ranges_(ranges),
|
||||||
|
indices_(ranges.size(), 0),
|
||||||
|
offsets_(ranges.size())
|
||||||
|
{
|
||||||
|
index_ = 0;
|
||||||
|
}
|
||||||
|
unsigned index_;
|
||||||
|
bool valid_;
|
||||||
|
vector<unsigned> ranges_;
|
||||||
|
vector<unsigned> indices_;
|
||||||
|
vector<unsigned> offsets_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // HORUS_STATESINDEXER_H
|
||||||
|
|
120
packages/CLPBN/clpbn/bp/LiftedUtils.cpp
Normal file
120
packages/CLPBN/clpbn/bp/LiftedUtils.cpp
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
#include "LiftedUtils.h"
|
||||||
|
#include "ConstraintTree.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace LiftedUtils {
|
||||||
|
|
||||||
|
|
||||||
|
unordered_map<string, unsigned> symbolDict;
|
||||||
|
|
||||||
|
|
||||||
|
Symbol
|
||||||
|
getSymbol (const string& symbolName)
|
||||||
|
{
|
||||||
|
unordered_map<string, unsigned>::iterator it
|
||||||
|
= symbolDict.find (symbolName);
|
||||||
|
if (it != symbolDict.end()) {
|
||||||
|
return it->second;
|
||||||
|
} else {
|
||||||
|
symbolDict[symbolName] = symbolDict.size() - 1;
|
||||||
|
return symbolDict.size() - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
printSymbolDictionary (void)
|
||||||
|
{
|
||||||
|
unordered_map<string, unsigned>::const_iterator it
|
||||||
|
= symbolDict.begin();
|
||||||
|
while (it != symbolDict.end()) {
|
||||||
|
cout << it->first << " -> " << it->second << endl;
|
||||||
|
it ++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ostream& operator<< (ostream &os, const Symbol& s)
|
||||||
|
{
|
||||||
|
unordered_map<string, unsigned>::const_iterator it
|
||||||
|
= LiftedUtils::symbolDict.begin();
|
||||||
|
while (it != LiftedUtils::symbolDict.end() && it->second != s) {
|
||||||
|
it ++;
|
||||||
|
}
|
||||||
|
assert (it != LiftedUtils::symbolDict.end());
|
||||||
|
os << it->first;
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ostream& operator<< (ostream &os, const LogVar& X)
|
||||||
|
{
|
||||||
|
const string labels[] = {
|
||||||
|
"A", "B", "C", "D", "E", "F",
|
||||||
|
"G", "H", "I", "J", "K", "M" };
|
||||||
|
(X >= 12) ? os << "X_" << X.id_ : os << labels[X];
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ostream& operator<< (ostream &os, const Tuple& t)
|
||||||
|
{
|
||||||
|
os << "(" ;
|
||||||
|
for (unsigned i = 0; i < t.size(); i++) {
|
||||||
|
os << ((i != 0) ? "," : "") << t[i];
|
||||||
|
}
|
||||||
|
os << ")" ;
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ostream& operator<< (ostream &os, const Ground& gr)
|
||||||
|
{
|
||||||
|
os << gr.functor();
|
||||||
|
os << "(" ;
|
||||||
|
for (unsigned i = 0; i < gr.args().size(); i++) {
|
||||||
|
if (i != 0) os << ", " ;
|
||||||
|
os << gr.args()[i];
|
||||||
|
}
|
||||||
|
os << ")" ;
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ObservedFormula::addTuple (const Tuple& t)
|
||||||
|
{
|
||||||
|
if (constr_ == 0) {
|
||||||
|
LogVars lvs (arity_);
|
||||||
|
for (unsigned i = 0; i < arity_; i++) {
|
||||||
|
lvs[i] = i;
|
||||||
|
}
|
||||||
|
constr_ = new ConstraintTree (lvs);
|
||||||
|
}
|
||||||
|
constr_->addTuple (t);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ostream& operator<< (ostream &os, const ObservedFormula of)
|
||||||
|
{
|
||||||
|
os << of.functor_ << "/" << of.arity_;
|
||||||
|
os << "|" << of.constr_->tupleSet();
|
||||||
|
os << " [evidence=" << of.evidence_ << "]";
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
161
packages/CLPBN/clpbn/bp/LiftedUtils.h
Normal file
161
packages/CLPBN/clpbn/bp/LiftedUtils.h
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
#ifndef HORUS_LIFTEDUTILS_H
|
||||||
|
#define HORUS_LIFTEDUTILS_H
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
|
||||||
|
#include "TinySet.h"
|
||||||
|
#include "Util.h"
|
||||||
|
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
|
||||||
|
class Symbol
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Symbol (void) : id_(numeric_limits<unsigned>::max()) { }
|
||||||
|
Symbol (unsigned id) : id_(id) { }
|
||||||
|
operator unsigned (void) const { return id_; }
|
||||||
|
bool valid (void) const { return id_ != numeric_limits<unsigned>::max(); }
|
||||||
|
static Symbol invalid (void) { return Symbol(); }
|
||||||
|
friend ostream& operator<< (ostream &os, const Symbol& s);
|
||||||
|
private:
|
||||||
|
unsigned id_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class LogVar
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
LogVar (void) : id_(numeric_limits<unsigned>::max()) { }
|
||||||
|
LogVar (unsigned id) : id_(id) { }
|
||||||
|
operator unsigned (void) const { return id_; }
|
||||||
|
|
||||||
|
LogVar& operator++ (void)
|
||||||
|
{
|
||||||
|
assert (valid());
|
||||||
|
id_ ++;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool valid (void) const
|
||||||
|
{
|
||||||
|
return id_ != numeric_limits<unsigned>::max();
|
||||||
|
}
|
||||||
|
|
||||||
|
friend ostream& operator<< (ostream &os, const LogVar& X);
|
||||||
|
private:
|
||||||
|
unsigned id_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
namespace std {
|
||||||
|
template <> struct hash<Symbol> {
|
||||||
|
size_t operator() (const Symbol& s) const {
|
||||||
|
return std::hash<unsigned>() (s);
|
||||||
|
}};
|
||||||
|
|
||||||
|
template <> struct hash<LogVar> {
|
||||||
|
size_t operator() (const LogVar& X) const {
|
||||||
|
return std::hash<unsigned>() (X);
|
||||||
|
}};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef vector<Symbol> Symbols;
|
||||||
|
typedef vector<Symbol> Tuple;
|
||||||
|
typedef vector<Tuple> Tuples;
|
||||||
|
typedef vector<LogVar> LogVars;
|
||||||
|
typedef TinySet<Symbol> SymbolSet;
|
||||||
|
typedef TinySet<LogVar> LogVarSet;
|
||||||
|
typedef TinySet<Tuple> TupleSet;
|
||||||
|
|
||||||
|
|
||||||
|
ostream& operator<< (ostream &os, const Tuple& t);
|
||||||
|
|
||||||
|
|
||||||
|
namespace LiftedUtils {
|
||||||
|
Symbol getSymbol (const string&);
|
||||||
|
void printSymbolDictionary (void);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class Ground
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Ground (Symbol f) : functor_(f) { }
|
||||||
|
Ground (Symbol f, const Symbols& args) : functor_(f), args_(args) { }
|
||||||
|
|
||||||
|
Symbol functor (void) const { return functor_; }
|
||||||
|
Symbols args (void) const { return args_; }
|
||||||
|
unsigned arity (void) const { return args_.size(); }
|
||||||
|
bool isAtom (void) const { return args_.size() == 0; }
|
||||||
|
friend ostream& operator<< (ostream &os, const Ground& gr);
|
||||||
|
private:
|
||||||
|
Symbol functor_;
|
||||||
|
Symbols args_;
|
||||||
|
};
|
||||||
|
typedef vector<Ground> Grounds;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class ConstraintTree;
|
||||||
|
class ObservedFormula
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ObservedFormula (Symbol f, unsigned a, unsigned ev)
|
||||||
|
: functor_(f), arity_(a), evidence_(ev), constr_(0) { }
|
||||||
|
|
||||||
|
ObservedFormula (Symbol f, unsigned ev, const Tuple& tuple)
|
||||||
|
: functor_(f), arity_(tuple.size()), evidence_(ev), constr_(0)
|
||||||
|
{
|
||||||
|
addTuple (tuple);
|
||||||
|
}
|
||||||
|
|
||||||
|
Symbol functor (void) const { return functor_; }
|
||||||
|
unsigned arity (void) const { return arity_; }
|
||||||
|
unsigned evidence (void) const { return evidence_; }
|
||||||
|
ConstraintTree* constr (void) const { return constr_; }
|
||||||
|
bool isAtom (void) const { return arity_ == 0; }
|
||||||
|
|
||||||
|
void addTuple (const Tuple& t);
|
||||||
|
friend ostream& operator<< (ostream &os, const ObservedFormula opv);
|
||||||
|
private:
|
||||||
|
Symbol functor_;
|
||||||
|
unsigned arity_;
|
||||||
|
unsigned evidence_;
|
||||||
|
ConstraintTree* constr_;
|
||||||
|
};
|
||||||
|
typedef vector<ObservedFormula*> ObservedFormulas;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class Substitution
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void add (LogVar X_old, LogVar X_new)
|
||||||
|
{
|
||||||
|
subs_.insert (make_pair (X_old, X_new));
|
||||||
|
}
|
||||||
|
void rename (LogVar X_old, LogVar X_new)
|
||||||
|
{
|
||||||
|
assert (subs_.find (X_old) != subs_.end());
|
||||||
|
subs_.find (X_old)->second = X_new;
|
||||||
|
}
|
||||||
|
LogVar newNameFor (LogVar X) const
|
||||||
|
{
|
||||||
|
assert (subs_.find (X) != subs_.end());
|
||||||
|
return subs_.find (X)->second;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
unordered_map<LogVar, LogVar> subs_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // HORUS_LIFTEDUTILS_H
|
||||||
|
|
@ -23,10 +23,10 @@ CC=@CC@
|
|||||||
CXX=@CXX@
|
CXX=@CXX@
|
||||||
|
|
||||||
# normal
|
# 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
|
# 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 = \
|
HEADERS = \
|
||||||
$(srcdir)/GraphicalModel.h \
|
$(srcdir)/GraphicalModel.h \
|
||||||
$(srcdir)/VarNode.h \
|
|
||||||
$(srcdir)/Distribution.h \
|
|
||||||
$(srcdir)/BayesNet.h \
|
$(srcdir)/BayesNet.h \
|
||||||
$(srcdir)/BayesNode.h \
|
$(srcdir)/BayesNode.h \
|
||||||
$(srcdir)/ElimGraph.h \
|
$(srcdir)/ElimGraph.h \
|
||||||
$(srcdir)/CFactorGraph.h \
|
|
||||||
$(srcdir)/CptEntry.h \
|
|
||||||
$(srcdir)/FactorGraph.h \
|
$(srcdir)/FactorGraph.h \
|
||||||
$(srcdir)/Factor.h \
|
$(srcdir)/Factor.h \
|
||||||
|
$(srcdir)/CFactorGraph.h \
|
||||||
|
$(srcdir)/ConstraintTree.h \
|
||||||
$(srcdir)/Solver.h \
|
$(srcdir)/Solver.h \
|
||||||
$(srcdir)/VarElimSolver.h \
|
$(srcdir)/VarElimSolver.h \
|
||||||
$(srcdir)/BnBpSolver.h \
|
$(srcdir)/BnBpSolver.h \
|
||||||
$(srcdir)/FgBpSolver.h \
|
$(srcdir)/FgBpSolver.h \
|
||||||
$(srcdir)/CbpSolver.h \
|
$(srcdir)/CbpSolver.h \
|
||||||
$(srcdir)/Shared.h \
|
$(srcdir)/FoveSolver.h \
|
||||||
$(srcdir)/StatesIndexer.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
|
$(srcdir)/xmlParser/xmlParser.h
|
||||||
|
|
||||||
CPP_SOURCES = \
|
CPP_SOURCES = \
|
||||||
$(srcdir)/BayesNet.cpp \
|
$(srcdir)/BayesNet.cpp \
|
||||||
$(srcdir)/BayesNode.cpp \
|
$(srcdir)/BayesNode.cpp \
|
||||||
@ -71,12 +79,19 @@ CPP_SOURCES = \
|
|||||||
$(srcdir)/FactorGraph.cpp \
|
$(srcdir)/FactorGraph.cpp \
|
||||||
$(srcdir)/Factor.cpp \
|
$(srcdir)/Factor.cpp \
|
||||||
$(srcdir)/CFactorGraph.cpp \
|
$(srcdir)/CFactorGraph.cpp \
|
||||||
|
$(srcdir)/ConstraintTree.cpp \
|
||||||
$(srcdir)/VarNode.cpp \
|
$(srcdir)/VarNode.cpp \
|
||||||
$(srcdir)/Solver.cpp \
|
$(srcdir)/Solver.cpp \
|
||||||
$(srcdir)/VarElimSolver.cpp \
|
$(srcdir)/VarElimSolver.cpp \
|
||||||
$(srcdir)/BnBpSolver.cpp \
|
$(srcdir)/BnBpSolver.cpp \
|
||||||
$(srcdir)/FgBpSolver.cpp \
|
$(srcdir)/FgBpSolver.cpp \
|
||||||
$(srcdir)/CbpSolver.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)/Util.cpp \
|
||||||
$(srcdir)/HorusYap.cpp \
|
$(srcdir)/HorusYap.cpp \
|
||||||
$(srcdir)/HorusCli.cpp \
|
$(srcdir)/HorusCli.cpp \
|
||||||
@ -89,12 +104,19 @@ OBJS = \
|
|||||||
FactorGraph.o \
|
FactorGraph.o \
|
||||||
Factor.o \
|
Factor.o \
|
||||||
CFactorGraph.o \
|
CFactorGraph.o \
|
||||||
|
ConstraintTree.o \
|
||||||
VarNode.o \
|
VarNode.o \
|
||||||
Solver.o \
|
Solver.o \
|
||||||
VarElimSolver.o \
|
VarElimSolver.o \
|
||||||
BnBpSolver.o \
|
BnBpSolver.o \
|
||||||
FgBpSolver.o \
|
FgBpSolver.o \
|
||||||
CbpSolver.o \
|
CbpSolver.o \
|
||||||
|
FoveSolver.o \
|
||||||
|
Parfactor.o \
|
||||||
|
ProbFormula.o \
|
||||||
|
Histogram.o \
|
||||||
|
ParfactorList.o \
|
||||||
|
LiftedUtils.o \
|
||||||
Util.o \
|
Util.o \
|
||||||
HorusYap.o
|
HorusYap.o
|
||||||
|
|
||||||
@ -105,12 +127,19 @@ HCLI_OBJS = \
|
|||||||
FactorGraph.o \
|
FactorGraph.o \
|
||||||
Factor.o \
|
Factor.o \
|
||||||
CFactorGraph.o \
|
CFactorGraph.o \
|
||||||
|
ConstraintTree.o \
|
||||||
VarNode.o \
|
VarNode.o \
|
||||||
Solver.o \
|
Solver.o \
|
||||||
VarElimSolver.o \
|
VarElimSolver.o \
|
||||||
BnBpSolver.o \
|
BnBpSolver.o \
|
||||||
FgBpSolver.o \
|
FgBpSolver.o \
|
||||||
CbpSolver.o \
|
CbpSolver.o \
|
||||||
|
FoveSolver.o \
|
||||||
|
Parfactor.o \
|
||||||
|
ProbFormula.o \
|
||||||
|
Histogram.o \
|
||||||
|
ParfactorList.o \
|
||||||
|
LiftedUtils.o \
|
||||||
Util.o \
|
Util.o \
|
||||||
xmlParser/xmlParser.o \
|
xmlParser/xmlParser.o \
|
||||||
HorusCli.o
|
HorusCli.o
|
||||||
@ -145,6 +174,10 @@ clean:
|
|||||||
rm -f *.o *~ $(OBJS) $(SOBJS) *.BAK hcli xmlParser/*.o
|
rm -f *.o *~ $(OBJS) $(SOBJS) *.BAK hcli xmlParser/*.o
|
||||||
|
|
||||||
|
|
||||||
|
erase_dots:
|
||||||
|
rm -f *.dot *.png
|
||||||
|
|
||||||
|
|
||||||
depend: $(HEADERS) $(CPP_SOURCES)
|
depend: $(HEADERS) $(CPP_SOURCES)
|
||||||
-@if test "$(GCC)" = yes; then\
|
-@if test "$(GCC)" = yes; then\
|
||||||
$(CC) -std=c++0x -MM -MG $(CFLAGS) -I$(srcdir) -I$(srcdir)/../../../../include -I$(srcdir)/../../../../H $(CPP_SOURCES) >> Makefile;\
|
$(CC) -std=c++0x -MM -MG $(CFLAGS) -I$(srcdir) -I$(srcdir)/../../../../include -I$(srcdir)/../../../../H $(CPP_SOURCES) >> Makefile;\
|
||||||
|
861
packages/CLPBN/clpbn/bp/Parfactor.cpp
Normal file
861
packages/CLPBN/clpbn/bp/Parfactor.cpp
Normal file
@ -0,0 +1,861 @@
|
|||||||
|
|
||||||
|
#include "Parfactor.h"
|
||||||
|
#include "Histogram.h"
|
||||||
|
#include "Indexer.h"
|
||||||
|
#include "Horus.h"
|
||||||
|
|
||||||
|
|
||||||
|
Parfactor::Parfactor (
|
||||||
|
const ProbFormulas& formulas,
|
||||||
|
const Params& params,
|
||||||
|
const Tuples& tuples,
|
||||||
|
unsigned distId)
|
||||||
|
{
|
||||||
|
formulas_ = formulas;
|
||||||
|
params_ = params;
|
||||||
|
distId_ = distId;
|
||||||
|
|
||||||
|
LogVars logVars;
|
||||||
|
for (unsigned i = 0; i < formulas_.size(); i++) {
|
||||||
|
ranges_.push_back (formulas_[i].range());
|
||||||
|
const LogVars& lvs = formulas_[i].logVars();
|
||||||
|
for (unsigned j = 0; j < lvs.size(); j++) {
|
||||||
|
if (std::find (logVars.begin(), logVars.end(), lvs[j]) ==
|
||||||
|
logVars.end()) {
|
||||||
|
logVars.push_back (lvs[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
constr_ = new ConstraintTree (logVars, tuples);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Parfactor::Parfactor (const Parfactor* g, const Tuple& tuple)
|
||||||
|
{
|
||||||
|
formulas_ = g->formulas();
|
||||||
|
params_ = g->params();
|
||||||
|
ranges_ = g->ranges();
|
||||||
|
distId_ = g->distId();
|
||||||
|
constr_ = new ConstraintTree (g->logVars(), {tuple});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Parfactor::Parfactor (const Parfactor* g, ConstraintTree* constr)
|
||||||
|
{
|
||||||
|
formulas_ = g->formulas();
|
||||||
|
params_ = g->params();
|
||||||
|
ranges_ = g->ranges();
|
||||||
|
distId_ = g->distId();
|
||||||
|
constr_ = constr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Parfactor::Parfactor (const Parfactor& g)
|
||||||
|
{
|
||||||
|
formulas_ = g.formulas();
|
||||||
|
params_ = g.params();
|
||||||
|
ranges_ = g.ranges();
|
||||||
|
distId_ = g.distId();
|
||||||
|
constr_ = new ConstraintTree (*g.constr());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Parfactor::~Parfactor (void)
|
||||||
|
{
|
||||||
|
delete constr_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
LogVarSet
|
||||||
|
Parfactor::countedLogVars (void) const
|
||||||
|
{
|
||||||
|
LogVarSet set;
|
||||||
|
for (unsigned i = 0; i < formulas_.size(); i++) {
|
||||||
|
if (formulas_[i].isCounting()) {
|
||||||
|
set.insert (formulas_[i].countedLogVar());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return set;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
LogVarSet
|
||||||
|
Parfactor::uncountedLogVars (void) const
|
||||||
|
{
|
||||||
|
return constr_->logVarSet() - countedLogVars();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
LogVarSet
|
||||||
|
Parfactor::elimLogVars (void) const
|
||||||
|
{
|
||||||
|
LogVarSet requiredToElim = constr_->logVarSet();
|
||||||
|
requiredToElim -= constr_->singletons();
|
||||||
|
requiredToElim -= countedLogVars();
|
||||||
|
return requiredToElim;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
LogVarSet
|
||||||
|
Parfactor::exclusiveLogVars (unsigned fIdx) const
|
||||||
|
{
|
||||||
|
assert (fIdx < formulas_.size());
|
||||||
|
LogVarSet remaining;
|
||||||
|
for (unsigned i = 0; i < formulas_.size(); i++) {
|
||||||
|
if (i != fIdx) {
|
||||||
|
remaining |= formulas_[i].logVarSet();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return formulas_[fIdx].logVarSet() - remaining;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Parfactor::setConstraintTree (ConstraintTree* newTree)
|
||||||
|
{
|
||||||
|
delete constr_;
|
||||||
|
constr_ = newTree;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Parfactor::sumOut (unsigned fIdx)
|
||||||
|
{
|
||||||
|
assert (fIdx < formulas_.size());
|
||||||
|
assert (formulas_[fIdx].contains (elimLogVars()));
|
||||||
|
|
||||||
|
LogVarSet excl = exclusiveLogVars (fIdx);
|
||||||
|
unsigned condCount = constr_->getConditionalCount (excl);
|
||||||
|
Util::pow (params_, condCount);
|
||||||
|
|
||||||
|
vector<unsigned> numAssigns (ranges_[fIdx], 1);
|
||||||
|
if (formulas_[fIdx].isCounting()) {
|
||||||
|
unsigned N = constr_->getConditionalCount (
|
||||||
|
formulas_[fIdx].countedLogVar());
|
||||||
|
unsigned R = formulas_[fIdx].range();
|
||||||
|
unsigned H = ranges_[fIdx];
|
||||||
|
HistogramSet hs (N, R);
|
||||||
|
unsigned N_factorial = Util::factorial (N);
|
||||||
|
for (unsigned h = 0; h < H; h++) {
|
||||||
|
unsigned prod = 1;
|
||||||
|
for (unsigned r = 0; r < R; r++) {
|
||||||
|
prod *= Util::factorial (hs[r]);
|
||||||
|
}
|
||||||
|
numAssigns[h] = N_factorial / prod;
|
||||||
|
hs.nextHistogram();
|
||||||
|
}
|
||||||
|
cout << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
Params copy = params_;
|
||||||
|
params_.clear();
|
||||||
|
params_.resize (copy.size() / ranges_[fIdx], 0.0);
|
||||||
|
|
||||||
|
MapIndexer indexer (ranges_, fIdx);
|
||||||
|
for (unsigned i = 0; i < copy.size(); i++) {
|
||||||
|
unsigned h = indexer[fIdx];
|
||||||
|
// TODO NOT LOG DOMAIN AWARE :(
|
||||||
|
params_[indexer] += numAssigns[h] * copy[i];
|
||||||
|
++ indexer;
|
||||||
|
}
|
||||||
|
formulas_.erase (formulas_.begin() + fIdx);
|
||||||
|
ranges_.erase (ranges_.begin() + fIdx);
|
||||||
|
constr_->remove (excl);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Parfactor::multiply (Parfactor& g)
|
||||||
|
{
|
||||||
|
alignAndExponentiate (this, &g);
|
||||||
|
bool sharedVars = false;
|
||||||
|
vector<unsigned> g_varpos;
|
||||||
|
const ProbFormulas& g_formulas = g.formulas();
|
||||||
|
const Params& g_params = g.params();
|
||||||
|
const Ranges& g_ranges = g.ranges();
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < g_formulas.size(); i++) {
|
||||||
|
int group = g_formulas[i].group();
|
||||||
|
if (indexOfFormulaWithGroup (group) == -1) {
|
||||||
|
insertDimension (g.ranges()[i]);
|
||||||
|
formulas_.push_back (g_formulas[i]);
|
||||||
|
g_varpos.push_back (formulas_.size() - 1);
|
||||||
|
} else {
|
||||||
|
sharedVars = true;
|
||||||
|
g_varpos.push_back (indexOfFormulaWithGroup (group));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sharedVars == false) {
|
||||||
|
unsigned count = 0;
|
||||||
|
for (unsigned i = 0; i < params_.size(); i++) {
|
||||||
|
if (Globals::logDomain) {
|
||||||
|
params_[i] += g_params[count];
|
||||||
|
} else {
|
||||||
|
params_[i] *= g_params[count];
|
||||||
|
}
|
||||||
|
count ++;
|
||||||
|
if (count >= g_params.size()) {
|
||||||
|
count = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
StatesIndexer indexer (ranges_, false);
|
||||||
|
while (indexer.valid()) {
|
||||||
|
unsigned g_li = 0;
|
||||||
|
unsigned prod = 1;
|
||||||
|
for (int j = g_varpos.size() - 1; j >= 0; j--) {
|
||||||
|
g_li += indexer[g_varpos[j]] * prod;
|
||||||
|
prod *= g_ranges[j];
|
||||||
|
}
|
||||||
|
if (Globals::logDomain) {
|
||||||
|
params_[indexer] += g_params[g_li];
|
||||||
|
} else {
|
||||||
|
params_[indexer] *= g_params[g_li];
|
||||||
|
}
|
||||||
|
++ indexer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constr_->join (g.constr(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Parfactor::countConvert (LogVar X)
|
||||||
|
{
|
||||||
|
int fIdx = indexOfFormulaWithLogVar (X);
|
||||||
|
assert (fIdx != -1);
|
||||||
|
assert (constr_->isCountNormalized (X));
|
||||||
|
assert (constr_->getConditionalCount (X) > 1);
|
||||||
|
assert (constr_->isCarteesianProduct (countedLogVars() | X));
|
||||||
|
|
||||||
|
unsigned N = constr_->getConditionalCount (X);
|
||||||
|
unsigned R = ranges_[fIdx];
|
||||||
|
unsigned H = HistogramSet::nrHistograms (N, R);
|
||||||
|
vector<Histogram> histograms = HistogramSet::getHistograms (N, R);
|
||||||
|
|
||||||
|
StatesIndexer indexer (ranges_);
|
||||||
|
vector<Params> summout (params_.size() / R);
|
||||||
|
unsigned count = 0;
|
||||||
|
while (indexer.valid()) {
|
||||||
|
summout[count].reserve (R);
|
||||||
|
for (unsigned r = 0; r < R; r++) {
|
||||||
|
summout[count].push_back (params_[indexer]);
|
||||||
|
indexer.increment (fIdx);
|
||||||
|
}
|
||||||
|
count ++;
|
||||||
|
indexer.reset (fIdx);
|
||||||
|
indexer.incrementExcluding (fIdx);
|
||||||
|
}
|
||||||
|
|
||||||
|
params_.clear();
|
||||||
|
params_.reserve (summout.size() * H);
|
||||||
|
|
||||||
|
vector<bool> mapDims (ranges_.size(), true);
|
||||||
|
ranges_[fIdx] = H;
|
||||||
|
mapDims[fIdx] = false;
|
||||||
|
MapIndexer mapIndexer (ranges_, mapDims);
|
||||||
|
while (mapIndexer.valid()) {
|
||||||
|
double prod = 1.0;
|
||||||
|
unsigned i = mapIndexer.mappedIndex();
|
||||||
|
unsigned h = mapIndexer[fIdx];
|
||||||
|
for (unsigned r = 0; r < R; r++) {
|
||||||
|
// TODO not log domain aware
|
||||||
|
prod *= Util::pow (summout[i][r], histograms[h][r]);
|
||||||
|
}
|
||||||
|
params_.push_back (prod);
|
||||||
|
++ mapIndexer;
|
||||||
|
}
|
||||||
|
formulas_[fIdx].setCountedLogVar (X);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Parfactor::expandPotential (
|
||||||
|
LogVar X,
|
||||||
|
LogVar X_new1,
|
||||||
|
LogVar X_new2)
|
||||||
|
{
|
||||||
|
int fIdx = indexOfFormulaWithLogVar (X);
|
||||||
|
assert (fIdx != -1);
|
||||||
|
assert (formulas_[fIdx].isCounting());
|
||||||
|
|
||||||
|
unsigned N1 = constr_->getConditionalCount (X_new1);
|
||||||
|
unsigned N2 = constr_->getConditionalCount (X_new2);
|
||||||
|
unsigned N = N1 + N2;
|
||||||
|
unsigned R = formulas_[fIdx].range();
|
||||||
|
unsigned H1 = HistogramSet::nrHistograms (N1, R);
|
||||||
|
unsigned H2 = HistogramSet::nrHistograms (N2, R);
|
||||||
|
unsigned H = ranges_[fIdx];
|
||||||
|
|
||||||
|
vector<Histogram> histograms = HistogramSet::getHistograms (N, R);
|
||||||
|
vector<Histogram> histograms1 = HistogramSet::getHistograms (N1, R);
|
||||||
|
vector<Histogram> histograms2 = HistogramSet::getHistograms (N2, R);
|
||||||
|
|
||||||
|
vector<unsigned> sumIndexes;
|
||||||
|
sumIndexes.reserve (H1 * H2);
|
||||||
|
for (unsigned i = 0; i < H1; i++) {
|
||||||
|
for (unsigned j = 0; j < H2; j++) {
|
||||||
|
Histogram hist = histograms1[i];
|
||||||
|
std::transform (
|
||||||
|
hist.begin(), hist.end(),
|
||||||
|
histograms2[j].begin(),
|
||||||
|
hist.begin(),
|
||||||
|
plus<int>());
|
||||||
|
sumIndexes.push_back (HistogramSet::findIndex (hist, histograms));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned size = (params_.size() / H) * H1 * H2;
|
||||||
|
Params copy = params_;
|
||||||
|
params_.clear();
|
||||||
|
params_.reserve (size);
|
||||||
|
|
||||||
|
unsigned prod = 1;
|
||||||
|
vector<unsigned> offsets_ (ranges_.size());
|
||||||
|
for (int i = ranges_.size() - 1; i >= 0; i--) {
|
||||||
|
offsets_[i] = prod;
|
||||||
|
prod *= ranges_[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned index = 0;
|
||||||
|
ranges_[fIdx] = H1 * H2;
|
||||||
|
vector<unsigned> indices (ranges_.size(), 0);
|
||||||
|
for (unsigned k = 0; k < size; k++) {
|
||||||
|
params_.push_back (copy[index]);
|
||||||
|
for (int i = ranges_.size() - 1; i >= 0; i--) {
|
||||||
|
indices[i] ++;
|
||||||
|
if (i == fIdx) {
|
||||||
|
int diff = sumIndexes[indices[i]] - sumIndexes[indices[i] - 1];
|
||||||
|
index += diff * offsets_[i];
|
||||||
|
} else {
|
||||||
|
index += offsets_[i];
|
||||||
|
}
|
||||||
|
if (indices[i] != ranges_[i]) {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
if (i == fIdx) {
|
||||||
|
int diff = sumIndexes[0] - sumIndexes[indices[i]];
|
||||||
|
index += diff * offsets_[i];
|
||||||
|
} else {
|
||||||
|
index -= offsets_[i] * ranges_[i];
|
||||||
|
}
|
||||||
|
indices[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
formulas_.insert (formulas_.begin() + fIdx + 1, formulas_[fIdx]);
|
||||||
|
formulas_[fIdx].rename (X, X_new1);
|
||||||
|
formulas_[fIdx + 1].rename (X, X_new2);
|
||||||
|
ranges_.insert (ranges_.begin() + fIdx + 1, H2);
|
||||||
|
ranges_[fIdx] = H1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Parfactor::fullExpand (LogVar X)
|
||||||
|
{
|
||||||
|
int fIdx = indexOfFormulaWithLogVar (X);
|
||||||
|
assert (fIdx != -1);
|
||||||
|
assert (formulas_[fIdx].isCounting());
|
||||||
|
|
||||||
|
unsigned N = constr_->getConditionalCount (X);
|
||||||
|
unsigned R = formulas_[fIdx].range();
|
||||||
|
unsigned H = ranges_[fIdx];
|
||||||
|
|
||||||
|
vector<Histogram> originHists = HistogramSet::getHistograms (N, R);
|
||||||
|
vector<Histogram> expandHists = HistogramSet::getHistograms (1, R);
|
||||||
|
|
||||||
|
vector<unsigned> sumIndexes;
|
||||||
|
sumIndexes.reserve (N * R);
|
||||||
|
|
||||||
|
Ranges expandRanges (N, R);
|
||||||
|
StatesIndexer indexer (expandRanges);
|
||||||
|
while (indexer.valid()) {
|
||||||
|
vector<unsigned> hist (R, 0);
|
||||||
|
for (unsigned n = 0; n < N; n++) {
|
||||||
|
std::transform (
|
||||||
|
hist.begin(), hist.end(),
|
||||||
|
expandHists[indexer[n]].begin(),
|
||||||
|
hist.begin(),
|
||||||
|
plus<int>());
|
||||||
|
}
|
||||||
|
sumIndexes.push_back (HistogramSet::findIndex (hist, originHists));
|
||||||
|
++ indexer;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned size = (params_.size() / H) * std::pow (R, N);
|
||||||
|
Params copy = params_;
|
||||||
|
params_.clear();
|
||||||
|
params_.reserve (size);
|
||||||
|
|
||||||
|
unsigned prod = 1;
|
||||||
|
vector<unsigned> offsets_ (ranges_.size());
|
||||||
|
for (int i = ranges_.size() - 1; i >= 0; i--) {
|
||||||
|
offsets_[i] = prod;
|
||||||
|
prod *= ranges_[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned index = 0;
|
||||||
|
ranges_[fIdx] = std::pow (R, N);
|
||||||
|
vector<unsigned> indices (ranges_.size(), 0);
|
||||||
|
for (unsigned k = 0; k < size; k++) {
|
||||||
|
params_.push_back (copy[index]);
|
||||||
|
for (int i = ranges_.size() - 1; i >= 0; i--) {
|
||||||
|
indices[i] ++;
|
||||||
|
if (i == fIdx) {
|
||||||
|
int diff = sumIndexes[indices[i]] - sumIndexes[indices[i] - 1];
|
||||||
|
index += diff * offsets_[i];
|
||||||
|
} else {
|
||||||
|
index += offsets_[i];
|
||||||
|
}
|
||||||
|
if (indices[i] != ranges_[i]) {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
if (i == fIdx) {
|
||||||
|
int diff = sumIndexes[0] - sumIndexes[indices[i]];
|
||||||
|
index += diff * offsets_[i];
|
||||||
|
} else {
|
||||||
|
index -= offsets_[i] * ranges_[i];
|
||||||
|
}
|
||||||
|
indices[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ProbFormula f = formulas_[fIdx];
|
||||||
|
formulas_.erase (formulas_.begin() + fIdx);
|
||||||
|
ranges_.erase (ranges_.begin() + fIdx);
|
||||||
|
LogVars newLvs = constr_->expand (X);
|
||||||
|
assert (newLvs.size() == N);
|
||||||
|
for (unsigned i = 0 ; i < N; i++) {
|
||||||
|
ProbFormula newFormula (f.functor(), f.logVars(), f.range());
|
||||||
|
newFormula.rename (X, newLvs[i]);
|
||||||
|
formulas_.insert (formulas_.begin() + fIdx + i, newFormula);
|
||||||
|
ranges_.insert (ranges_.begin() + fIdx + i, R);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Parfactor::reorderAccordingGrounds (const Grounds& grounds)
|
||||||
|
{
|
||||||
|
ProbFormulas newFormulas;
|
||||||
|
for (unsigned i = 0; i < grounds.size(); i++) {
|
||||||
|
for (unsigned j = 0; j < formulas_.size(); j++) {
|
||||||
|
if (grounds[i].functor() == formulas_[j].functor() &&
|
||||||
|
grounds[i].arity() == formulas_[j].arity()) {
|
||||||
|
constr_->moveToTop (formulas_[j].logVars());
|
||||||
|
if (constr_->containsTuple (grounds[i].args())) {
|
||||||
|
newFormulas.push_back (formulas_[j]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert (newFormulas.size() == i + 1);
|
||||||
|
}
|
||||||
|
reorderFormulas (newFormulas);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Parfactor::reorderFormulas (const ProbFormulas& newFormulas)
|
||||||
|
{
|
||||||
|
assert (newFormulas.size() == formulas_.size());
|
||||||
|
if (newFormulas == formulas_) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ranges newRanges;
|
||||||
|
vector<unsigned> positions;
|
||||||
|
for (unsigned i = 0; i < newFormulas.size(); i++) {
|
||||||
|
unsigned idx = indexOf (newFormulas[i]);
|
||||||
|
newRanges.push_back (ranges_[idx]);
|
||||||
|
positions.push_back (idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned N = ranges_.size();
|
||||||
|
Params newParams (params_.size());
|
||||||
|
for (unsigned i = 0; i < params_.size(); i++) {
|
||||||
|
unsigned li = i;
|
||||||
|
// calculate vector index corresponding to linear index
|
||||||
|
vector<unsigned> vi (N);
|
||||||
|
for (int k = N-1; k >= 0; k--) {
|
||||||
|
vi[k] = li % ranges_[k];
|
||||||
|
li /= ranges_[k];
|
||||||
|
}
|
||||||
|
// convert permuted vector index to corresponding linear index
|
||||||
|
unsigned prod = 1;
|
||||||
|
unsigned new_li = 0;
|
||||||
|
for (int k = N - 1; k >= 0; k--) {
|
||||||
|
new_li += vi[positions[k]] * prod;
|
||||||
|
prod *= ranges_[positions[k]];
|
||||||
|
}
|
||||||
|
newParams[new_li] = params_[i];
|
||||||
|
}
|
||||||
|
formulas_ = newFormulas;
|
||||||
|
ranges_ = newRanges;
|
||||||
|
params_ = newParams;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Parfactor::absorveEvidence (unsigned fIdx, unsigned evidence)
|
||||||
|
{
|
||||||
|
LogVarSet excl = exclusiveLogVars (fIdx);
|
||||||
|
assert (fIdx < formulas_.size());
|
||||||
|
assert (evidence < formulas_[fIdx].range());
|
||||||
|
assert (formulas_[fIdx].isCounting() == false);
|
||||||
|
assert (constr_->isCountNormalized (excl));
|
||||||
|
|
||||||
|
Util::pow (params_, constr_->getConditionalCount (excl));
|
||||||
|
|
||||||
|
Params copy = params_;
|
||||||
|
params_.clear();
|
||||||
|
params_.reserve (copy.size() / formulas_[fIdx].range());
|
||||||
|
|
||||||
|
StatesIndexer indexer (ranges_);
|
||||||
|
for (unsigned i = 0; i < evidence; i++) {
|
||||||
|
indexer.increment (fIdx);
|
||||||
|
}
|
||||||
|
while (indexer.valid()) {
|
||||||
|
params_.push_back (copy[indexer]);
|
||||||
|
indexer.incrementExcluding (fIdx);
|
||||||
|
}
|
||||||
|
formulas_.erase (formulas_.begin() + fIdx);
|
||||||
|
ranges_.erase (ranges_.begin() + fIdx);
|
||||||
|
constr_->remove (excl);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Parfactor::normalize (void)
|
||||||
|
{
|
||||||
|
Util::normalize (params_);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Parfactor::setFormulaGroup (const ProbFormula& f, int group)
|
||||||
|
{
|
||||||
|
assert (indexOf (f) != -1);
|
||||||
|
formulas_[indexOf (f)].setGroup (group);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Parfactor::setNewGroups (void)
|
||||||
|
{
|
||||||
|
for (unsigned i = 0; i < formulas_.size(); i++) {
|
||||||
|
formulas_[i].setGroup (ProbFormula::getNewGroup());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Parfactor::applySubstitution (const Substitution& theta)
|
||||||
|
{
|
||||||
|
for (unsigned i = 0; i < formulas_.size(); i++) {
|
||||||
|
LogVars& lvs = formulas_[i].logVars();
|
||||||
|
for (unsigned j = 0; j < lvs.size(); j++) {
|
||||||
|
lvs[j] = theta.newNameFor (lvs[j]);
|
||||||
|
}
|
||||||
|
if (formulas_[i].isCounting()) {
|
||||||
|
LogVar clv = formulas_[i].countedLogVar();
|
||||||
|
formulas_[i].setCountedLogVar (theta.newNameFor (clv));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
constr_->applySubstitution (theta);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
Parfactor::containsGround (const Ground& ground) const
|
||||||
|
{
|
||||||
|
for (unsigned i = 0; i < formulas_.size(); i++) {
|
||||||
|
if (formulas_[i].functor() == ground.functor() &&
|
||||||
|
formulas_[i].arity() == ground.arity()) {
|
||||||
|
constr_->moveToTop (formulas_[i].logVars());
|
||||||
|
if (constr_->containsTuple (ground.args())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
Parfactor::containsGroup (unsigned group) const
|
||||||
|
{
|
||||||
|
for (unsigned i = 0; i < formulas_.size(); i++) {
|
||||||
|
if (formulas_[i].group() == group) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const ProbFormula&
|
||||||
|
Parfactor::formula (unsigned fIdx) const
|
||||||
|
{
|
||||||
|
assert (fIdx < formulas_.size());
|
||||||
|
return formulas_[fIdx];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
unsigned
|
||||||
|
Parfactor::range (unsigned fIdx) const
|
||||||
|
{
|
||||||
|
assert (fIdx < ranges_.size());
|
||||||
|
return ranges_[fIdx];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
unsigned
|
||||||
|
Parfactor::nrFormulas (LogVar X) const
|
||||||
|
{
|
||||||
|
unsigned count = 0;
|
||||||
|
for (unsigned i = 0; i < formulas_.size(); i++) {
|
||||||
|
if (formulas_[i].contains (X)) {
|
||||||
|
count ++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
Parfactor::indexOf (const ProbFormula& f) const
|
||||||
|
{
|
||||||
|
int idx = -1;
|
||||||
|
for (unsigned i = 0; i < formulas_.size(); i++) {
|
||||||
|
if (f == formulas_[i]) {
|
||||||
|
idx = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
Parfactor::indexOfFormulaWithLogVar (LogVar X) const
|
||||||
|
{
|
||||||
|
int idx = -1;
|
||||||
|
assert (nrFormulas (X) == 1);
|
||||||
|
for (unsigned i = 0; i < formulas_.size(); i++) {
|
||||||
|
if (formulas_[i].contains (X)) {
|
||||||
|
idx = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
Parfactor::indexOfFormulaWithGroup (unsigned group) const
|
||||||
|
{
|
||||||
|
int pos = -1;
|
||||||
|
for (unsigned i = 0; i < formulas_.size(); i++) {
|
||||||
|
if (formulas_[i].group() == group) {
|
||||||
|
pos = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
vector<unsigned>
|
||||||
|
Parfactor::getAllGroups (void) const
|
||||||
|
{
|
||||||
|
vector<unsigned> groups (formulas_.size());
|
||||||
|
for (unsigned i = 0; i < formulas_.size(); i++) {
|
||||||
|
groups[i] = formulas_[i].group();
|
||||||
|
}
|
||||||
|
return groups;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
string
|
||||||
|
Parfactor::getHeaderString (void) const
|
||||||
|
{
|
||||||
|
stringstream ss;
|
||||||
|
ss << "phi(" ;
|
||||||
|
for (unsigned i = 0; i < formulas_.size(); i++) {
|
||||||
|
if (i != 0) ss << "," ;
|
||||||
|
ss << formulas_[i];
|
||||||
|
}
|
||||||
|
ss << ")" ;
|
||||||
|
ConstraintTree copy (*constr_);
|
||||||
|
copy.moveToTop (copy.logVarSet().elements());
|
||||||
|
ss << "|" << copy.tupleSet();
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Parfactor::print (bool printParams) const
|
||||||
|
{
|
||||||
|
cout << "Formulas: " ;
|
||||||
|
for (unsigned i = 0; i < formulas_.size(); i++) {
|
||||||
|
if (i != 0) cout << ", " ;
|
||||||
|
cout << formulas_[i];
|
||||||
|
}
|
||||||
|
cout << endl;
|
||||||
|
vector<string> groups;
|
||||||
|
for (unsigned i = 0; i < formulas_.size(); i++) {
|
||||||
|
groups.push_back (string ("g") + Util::toString (formulas_[i].group()));
|
||||||
|
}
|
||||||
|
cout << "Groups: " << groups << endl;
|
||||||
|
cout << "LogVars: " << constr_->logVars() << endl;
|
||||||
|
cout << "Ranges: " << ranges_ << endl;
|
||||||
|
if (printParams == false) {
|
||||||
|
cout << "Params: " << params_ << endl;
|
||||||
|
}
|
||||||
|
cout << "Tuples: " << constr_->tupleSet() << endl;
|
||||||
|
if (printParams) {
|
||||||
|
vector<string> jointStrings;
|
||||||
|
StatesIndexer indexer (ranges_);
|
||||||
|
while (indexer.valid()) {
|
||||||
|
stringstream ss;
|
||||||
|
for (unsigned i = 0; i < formulas_.size(); i++) {
|
||||||
|
if (i != 0) ss << ", " ;
|
||||||
|
if (formulas_[i].isCounting()) {
|
||||||
|
unsigned N = constr_->getConditionalCount (formulas_[i].countedLogVar());
|
||||||
|
HistogramSet hs (N, formulas_[i].range());
|
||||||
|
unsigned c = 0;
|
||||||
|
while (c < indexer[i]) {
|
||||||
|
hs.nextHistogram();
|
||||||
|
c ++;
|
||||||
|
}
|
||||||
|
ss << hs;
|
||||||
|
} else {
|
||||||
|
ss << indexer[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
jointStrings.push_back (ss.str());
|
||||||
|
++ indexer;
|
||||||
|
}
|
||||||
|
for (unsigned i = 0; i < params_.size(); i++) {
|
||||||
|
cout << "f(" << jointStrings[i] << ")" ;
|
||||||
|
cout << " = " << params_[i] << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Parfactor::insertDimension (unsigned range)
|
||||||
|
{
|
||||||
|
Params copy = params_;
|
||||||
|
params_.clear();
|
||||||
|
params_.reserve (copy.size() * range);
|
||||||
|
for (unsigned i = 0; i < copy.size(); i++) {
|
||||||
|
for (unsigned reps = 0; reps < range; reps++) {
|
||||||
|
params_.push_back (copy[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ranges_.push_back (range);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Parfactor::alignAndExponentiate (Parfactor* g1, Parfactor* g2)
|
||||||
|
{
|
||||||
|
LogVars X_1, X_2;
|
||||||
|
const ProbFormulas& formulas1 = g1->formulas();
|
||||||
|
const ProbFormulas& formulas2 = g2->formulas();
|
||||||
|
for (unsigned i = 0; i < formulas1.size(); i++) {
|
||||||
|
for (unsigned j = 0; j < formulas2.size(); j++) {
|
||||||
|
if (formulas1[i].group() == formulas2[j].group()) {
|
||||||
|
X_1.insert (X_1.end(),
|
||||||
|
formulas1[i].logVars().begin(),
|
||||||
|
formulas1[i].logVars().end());
|
||||||
|
X_2.insert (X_2.end(),
|
||||||
|
formulas2[j].logVars().begin(),
|
||||||
|
formulas2[j].logVars().end());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
align (g1, X_1, g2, X_2);
|
||||||
|
LogVarSet Y_1 = g1->logVarSet() - LogVarSet (X_1);
|
||||||
|
LogVarSet Y_2 = g2->logVarSet() - LogVarSet (X_2);
|
||||||
|
assert (g1->constr()->isCountNormalized (Y_1));
|
||||||
|
assert (g2->constr()->isCountNormalized (Y_2));
|
||||||
|
unsigned condCount1 = g1->constr()->getConditionalCount (Y_1);
|
||||||
|
unsigned condCount2 = g2->constr()->getConditionalCount (Y_2);
|
||||||
|
Util::pow (g1->params(), 1.0 / condCount2);
|
||||||
|
Util::pow (g2->params(), 1.0 / condCount1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Parfactor::align (
|
||||||
|
Parfactor* g1, const LogVars& alignLvs1,
|
||||||
|
Parfactor* g2, const LogVars& alignLvs2)
|
||||||
|
{
|
||||||
|
LogVar freeLogVar = 0;
|
||||||
|
Substitution theta1;
|
||||||
|
Substitution theta2;
|
||||||
|
|
||||||
|
const LogVarSet& allLvs1 = g1->logVarSet();
|
||||||
|
for (unsigned i = 0; i < allLvs1.size(); i++) {
|
||||||
|
theta1.add (allLvs1[i], freeLogVar);
|
||||||
|
++ freeLogVar;
|
||||||
|
}
|
||||||
|
|
||||||
|
const LogVarSet& allLvs2 = g2->logVarSet();
|
||||||
|
for (unsigned i = 0; i < allLvs2.size(); i++) {
|
||||||
|
theta2.add (allLvs2[i], freeLogVar);
|
||||||
|
++ freeLogVar;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert (alignLvs1.size() == alignLvs2.size());
|
||||||
|
for (unsigned i = 0; i < alignLvs1.size(); i++) {
|
||||||
|
theta1.rename (alignLvs1[i], theta2.newNameFor (alignLvs2[i]));
|
||||||
|
}
|
||||||
|
g1->applySubstitution (theta1);
|
||||||
|
g2->applySubstitution (theta2);
|
||||||
|
}
|
||||||
|
|
124
packages/CLPBN/clpbn/bp/Parfactor.h
Normal file
124
packages/CLPBN/clpbn/bp/Parfactor.h
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
#ifndef HORUS_PARFACTOR_H
|
||||||
|
#define HORUS_PARFACTOR_H
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
#include "ProbFormula.h"
|
||||||
|
#include "ConstraintTree.h"
|
||||||
|
#include "LiftedUtils.h"
|
||||||
|
#include "Horus.h"
|
||||||
|
|
||||||
|
|
||||||
|
class Parfactor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Parfactor (
|
||||||
|
const ProbFormulas&,
|
||||||
|
const Params&,
|
||||||
|
const Tuples&,
|
||||||
|
unsigned);
|
||||||
|
Parfactor (const Parfactor*, const Tuple&);
|
||||||
|
Parfactor (const Parfactor*, ConstraintTree*);
|
||||||
|
Parfactor (const Parfactor&);
|
||||||
|
~Parfactor (void);
|
||||||
|
|
||||||
|
ProbFormulas& formulas (void) { return formulas_; }
|
||||||
|
|
||||||
|
const ProbFormulas& formulas (void) const { return formulas_; }
|
||||||
|
|
||||||
|
unsigned nrFormulas (void) const { return formulas_.size(); }
|
||||||
|
|
||||||
|
Params& params (void) { return params_; }
|
||||||
|
|
||||||
|
const Params& params (void) const { return params_; }
|
||||||
|
|
||||||
|
unsigned size (void) const { return params_.size(); }
|
||||||
|
|
||||||
|
const Ranges& ranges (void) const { return ranges_; }
|
||||||
|
|
||||||
|
unsigned distId (void) const { return distId_; }
|
||||||
|
|
||||||
|
ConstraintTree* constr (void) { return constr_; }
|
||||||
|
|
||||||
|
const ConstraintTree* constr (void) const { return constr_; }
|
||||||
|
|
||||||
|
const LogVars& logVars (void) const { return constr_->logVars(); }
|
||||||
|
|
||||||
|
const LogVarSet& logVarSet (void) const { return constr_->logVarSet(); }
|
||||||
|
|
||||||
|
LogVarSet countedLogVars (void) const;
|
||||||
|
|
||||||
|
LogVarSet uncountedLogVars (void) const;
|
||||||
|
|
||||||
|
LogVarSet elimLogVars (void) const;
|
||||||
|
|
||||||
|
LogVarSet exclusiveLogVars (unsigned) const;
|
||||||
|
|
||||||
|
void setConstraintTree (ConstraintTree*);
|
||||||
|
|
||||||
|
void sumOut (unsigned);
|
||||||
|
|
||||||
|
void multiply (Parfactor&);
|
||||||
|
|
||||||
|
void countConvert (LogVar);
|
||||||
|
|
||||||
|
void expandPotential (LogVar, LogVar, LogVar);
|
||||||
|
|
||||||
|
void fullExpand (LogVar);
|
||||||
|
|
||||||
|
void reorderAccordingGrounds (const Grounds&);
|
||||||
|
|
||||||
|
void reorderFormulas (const ProbFormulas&);
|
||||||
|
|
||||||
|
void absorveEvidence (unsigned, unsigned);
|
||||||
|
|
||||||
|
void normalize (void);
|
||||||
|
|
||||||
|
void setFormulaGroup (const ProbFormula&, int);
|
||||||
|
|
||||||
|
void setNewGroups (void);
|
||||||
|
|
||||||
|
void applySubstitution (const Substitution&);
|
||||||
|
|
||||||
|
bool containsGround (const Ground&) const;
|
||||||
|
|
||||||
|
bool containsGroup (unsigned) const;
|
||||||
|
|
||||||
|
const ProbFormula& formula (unsigned) const;
|
||||||
|
|
||||||
|
unsigned range (unsigned) const;
|
||||||
|
|
||||||
|
unsigned nrFormulas (LogVar) const;
|
||||||
|
|
||||||
|
int indexOf (const ProbFormula&) const;
|
||||||
|
|
||||||
|
int indexOfFormulaWithLogVar (LogVar) const;
|
||||||
|
|
||||||
|
int indexOfFormulaWithGroup (unsigned) const;
|
||||||
|
|
||||||
|
vector<unsigned> getAllGroups (void) const;
|
||||||
|
|
||||||
|
void print (bool = false) const;
|
||||||
|
|
||||||
|
string getHeaderString (void) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static void alignAndExponentiate (Parfactor*, Parfactor*);
|
||||||
|
static void align (
|
||||||
|
Parfactor*, const LogVars&, Parfactor*, const LogVars&);
|
||||||
|
|
||||||
|
void insertDimension (unsigned);
|
||||||
|
|
||||||
|
ProbFormulas formulas_;
|
||||||
|
Ranges ranges_;
|
||||||
|
Params params_;
|
||||||
|
unsigned distId_;
|
||||||
|
ConstraintTree* constr_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef vector<Parfactor*> Parfactors;
|
||||||
|
|
||||||
|
#endif // HORUS_PARFACTOR_H
|
||||||
|
|
308
packages/CLPBN/clpbn/bp/ParfactorList.cpp
Normal file
308
packages/CLPBN/clpbn/bp/ParfactorList.cpp
Normal file
@ -0,0 +1,308 @@
|
|||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
#include "ParfactorList.h"
|
||||||
|
|
||||||
|
|
||||||
|
ParfactorList::ParfactorList (Parfactors& pfs)
|
||||||
|
{
|
||||||
|
pfList_.insert (pfList_.end(), pfs.begin(), pfs.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ParfactorList::add (Parfactor* pf)
|
||||||
|
{
|
||||||
|
pf->setNewGroups();
|
||||||
|
pfList_.push_back (pf);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ParfactorList::add (Parfactors& pfs)
|
||||||
|
{
|
||||||
|
for (unsigned i = 0; i < pfs.size(); i++) {
|
||||||
|
pfs[i]->setNewGroups();
|
||||||
|
pfList_.push_back (pfs[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ParfactorList::addShattered (Parfactor* pf)
|
||||||
|
{
|
||||||
|
pfList_.push_back (pf);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
list<Parfactor*>::iterator
|
||||||
|
ParfactorList::remove (list<Parfactor*>::iterator it)
|
||||||
|
{
|
||||||
|
return pfList_.erase (it);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
list<Parfactor*>::iterator
|
||||||
|
ParfactorList::deleteAndRemove (list<Parfactor*>::iterator it)
|
||||||
|
{
|
||||||
|
delete *it;
|
||||||
|
return pfList_.erase (it);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ParfactorList::shatter (void)
|
||||||
|
{
|
||||||
|
list<Parfactor*> tempList;
|
||||||
|
Parfactors newPfs;
|
||||||
|
newPfs.insert (newPfs.end(), pfList_.begin(), pfList_.end());
|
||||||
|
while (newPfs.empty() == false) {
|
||||||
|
tempList.insert (tempList.end(), newPfs.begin(), newPfs.end());
|
||||||
|
newPfs.clear();
|
||||||
|
list<Parfactor*>::iterator iter1 = tempList.begin();
|
||||||
|
while (tempList.size() > 1 && iter1 != -- tempList.end()) {
|
||||||
|
list<Parfactor*>::iterator iter2 = iter1;
|
||||||
|
++ iter2;
|
||||||
|
bool incIter1 = true;
|
||||||
|
while (iter2 != tempList.end()) {
|
||||||
|
assert (iter1 != iter2);
|
||||||
|
std::pair<Parfactors, Parfactors> res = shatter (
|
||||||
|
(*iter1)->formulas(), *iter1, (*iter2)->formulas(), *iter2);
|
||||||
|
bool incIter2 = true;
|
||||||
|
if (res.second.empty() == false) {
|
||||||
|
// cout << "second unshattered" << endl;
|
||||||
|
delete *iter2;
|
||||||
|
iter2 = tempList.erase (iter2);
|
||||||
|
incIter2 = false;
|
||||||
|
newPfs.insert (
|
||||||
|
newPfs.begin(), res.second.begin(), res.second.end());
|
||||||
|
}
|
||||||
|
if (res.first.empty() == false) {
|
||||||
|
// cout << "first unshattered" << endl;
|
||||||
|
delete *iter1;
|
||||||
|
iter1 = tempList.erase (iter1);
|
||||||
|
newPfs.insert (
|
||||||
|
newPfs.begin(), res.first.begin(), res.first.end());
|
||||||
|
incIter1 = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (incIter2) {
|
||||||
|
++ iter2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (incIter1) {
|
||||||
|
++ iter1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// cout << "|||||||||||||||||||||||||||||||||||||||||||||||||" << endl;
|
||||||
|
// cout << "||||||||||||| SHATTERING ITERATION ||||||||||||||" << endl;
|
||||||
|
// cout << "|||||||||||||||||||||||||||||||||||||||||||||||||" << endl;
|
||||||
|
// printParfactors (newPfs);
|
||||||
|
// cout << "|||||||||||||||||||||||||||||||||||||||||||||||||" << endl;
|
||||||
|
}
|
||||||
|
pfList_.clear();
|
||||||
|
pfList_.insert (pfList_.end(), tempList.begin(), tempList.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ParfactorList::print (void) const
|
||||||
|
{
|
||||||
|
list<Parfactor*>::const_iterator it;
|
||||||
|
for (it = pfList_.begin(); it != pfList_.end(); ++it) {
|
||||||
|
(*it)->print();
|
||||||
|
cout << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
std::pair<Parfactors, Parfactors>
|
||||||
|
ParfactorList::shatter (
|
||||||
|
ProbFormulas& formulas1,
|
||||||
|
Parfactor* g1,
|
||||||
|
ProbFormulas& formulas2,
|
||||||
|
Parfactor* g2)
|
||||||
|
{
|
||||||
|
assert (g1 != 0 && g2 != 0 && g1 != g2);
|
||||||
|
for (unsigned i = 0; i < formulas1.size(); i++) {
|
||||||
|
for (unsigned j = 0; j < formulas2.size(); j++) {
|
||||||
|
if (formulas1[i].sameSkeletonAs (formulas2[j])) {
|
||||||
|
std::pair<Parfactors, Parfactors> res
|
||||||
|
= shatter (formulas1[i], g1, formulas2[j], g2);
|
||||||
|
if (res.first.empty() == false ||
|
||||||
|
res.second.empty() == false) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return make_pair (Parfactors(), Parfactors());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
std::pair<Parfactors, Parfactors>
|
||||||
|
ParfactorList::shatter (
|
||||||
|
ProbFormula& f1,
|
||||||
|
Parfactor* g1,
|
||||||
|
ProbFormula& f2,
|
||||||
|
Parfactor* g2)
|
||||||
|
{
|
||||||
|
// cout << endl;
|
||||||
|
// cout << "-------------------------------------------------" << endl;
|
||||||
|
// cout << "-> SHATTERING (#" << g1 << ", #" << g2 << ")" << endl;
|
||||||
|
// g1->print();
|
||||||
|
// cout << "-> WITH" << endl;
|
||||||
|
// g2->print();
|
||||||
|
// cout << "-> ON: " << f1.toString (g1->constr()) << endl;
|
||||||
|
// cout << "-> ON: " << f2.toString (g2->constr()) << endl;
|
||||||
|
// cout << "-------------------------------------------------" << endl;
|
||||||
|
|
||||||
|
if (f1.isAtom()) {
|
||||||
|
unsigned group = (f1.group() < f2.group()) ? f1.group() : f2.group();
|
||||||
|
f1.setGroup (group);
|
||||||
|
f2.setGroup (group);
|
||||||
|
return { };
|
||||||
|
}
|
||||||
|
assert (g1->constr()->empty() == false);
|
||||||
|
assert (g2->constr()->empty() == false);
|
||||||
|
if (f1.group() == f2.group()) {
|
||||||
|
// assert (identical (f1, g1->constr(), f2, g2->constr()));
|
||||||
|
return { };
|
||||||
|
}
|
||||||
|
|
||||||
|
g1->constr()->moveToTop (f1.logVars());
|
||||||
|
g2->constr()->moveToTop (f2.logVars());
|
||||||
|
|
||||||
|
std::pair<ConstraintTree*,ConstraintTree*> split1 =
|
||||||
|
g1->constr()->split (g2->constr(), f1.arity());
|
||||||
|
ConstraintTree* commCt1 = split1.first;
|
||||||
|
ConstraintTree* exclCt1 = split1.second;
|
||||||
|
|
||||||
|
if (commCt1->empty()) {
|
||||||
|
// disjoint
|
||||||
|
delete commCt1;
|
||||||
|
delete exclCt1;
|
||||||
|
return { };
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<ConstraintTree*,ConstraintTree*> split2 =
|
||||||
|
g2->constr()->split (g1->constr(), f2.arity());
|
||||||
|
ConstraintTree* commCt2 = split2.first;
|
||||||
|
ConstraintTree* exclCt2 = split2.second;
|
||||||
|
|
||||||
|
assert (commCt1->tupleSet (f1.arity()) ==
|
||||||
|
commCt2->tupleSet (f2.arity()));
|
||||||
|
|
||||||
|
// stringstream ss1; ss1 << "" << count << "_A.dot" ;
|
||||||
|
// stringstream ss2; ss2 << "" << count << "_B.dot" ;
|
||||||
|
// stringstream ss3; ss3 << "" << count << "_A_comm.dot" ;
|
||||||
|
// stringstream ss4; ss4 << "" << count << "_A_excl.dot" ;
|
||||||
|
// stringstream ss5; ss5 << "" << count << "_B_comm.dot" ;
|
||||||
|
// stringstream ss6; ss6 << "" << count << "_B_excl.dot" ;
|
||||||
|
// ct1->exportToGraphViz (ss1.str().c_str(), true);
|
||||||
|
// ct2->exportToGraphViz (ss2.str().c_str(), true);
|
||||||
|
// commCt1->exportToGraphViz (ss3.str().c_str(), true);
|
||||||
|
// exclCt1->exportToGraphViz (ss4.str().c_str(), true);
|
||||||
|
// commCt2->exportToGraphViz (ss5.str().c_str(), true);
|
||||||
|
// exclCt2->exportToGraphViz (ss6.str().c_str(), true);
|
||||||
|
|
||||||
|
if (exclCt1->empty() && exclCt2->empty()) {
|
||||||
|
unsigned group = (f1.group() < f2.group()) ? f1.group() : f2.group();
|
||||||
|
// identical
|
||||||
|
f1.setGroup (group);
|
||||||
|
f2.setGroup (group);
|
||||||
|
// unifyGroups
|
||||||
|
delete commCt1;
|
||||||
|
delete exclCt1;
|
||||||
|
delete commCt2;
|
||||||
|
delete exclCt2;
|
||||||
|
return { };
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned group;
|
||||||
|
if (exclCt1->empty()) {
|
||||||
|
group = f1.group();
|
||||||
|
} else if (exclCt2->empty()) {
|
||||||
|
group = f2.group();
|
||||||
|
} else {
|
||||||
|
group = ProbFormula::getNewGroup();
|
||||||
|
}
|
||||||
|
Parfactors res1 = shatter (g1, f1, commCt1, exclCt1, group);
|
||||||
|
Parfactors res2 = shatter (g2, f2, commCt2, exclCt2, group);
|
||||||
|
return make_pair (res1, res2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Parfactors
|
||||||
|
ParfactorList::shatter (
|
||||||
|
Parfactor* g,
|
||||||
|
const ProbFormula& f,
|
||||||
|
ConstraintTree* commCt,
|
||||||
|
ConstraintTree* exclCt,
|
||||||
|
unsigned commGroup)
|
||||||
|
{
|
||||||
|
Parfactors result;
|
||||||
|
if (f.isCounting()) {
|
||||||
|
LogVar X_new1 = g->constr()->logVarSet().back() + 1;
|
||||||
|
LogVar X_new2 = g->constr()->logVarSet().back() + 2;
|
||||||
|
ConstraintTrees cts = g->constr()->jointCountNormalize (
|
||||||
|
commCt, exclCt, f.countedLogVar(), X_new1, X_new2);
|
||||||
|
for (unsigned i = 0; i < cts.size(); i++) {
|
||||||
|
Parfactor* newPf = new Parfactor (g, cts[i]);
|
||||||
|
if (cts[i]->nrLogVars() == g->constr()->nrLogVars() + 1) {
|
||||||
|
newPf->expandPotential (f.countedLogVar(), X_new1, X_new2);
|
||||||
|
assert (g->constr()->getConditionalCount (f.countedLogVar()) ==
|
||||||
|
cts[i]->getConditionalCount (X_new1) +
|
||||||
|
cts[i]->getConditionalCount (X_new2));
|
||||||
|
} else {
|
||||||
|
assert (g->constr()->getConditionalCount (f.countedLogVar()) ==
|
||||||
|
cts[i]->getConditionalCount (f.countedLogVar()));
|
||||||
|
}
|
||||||
|
newPf->setNewGroups();
|
||||||
|
result.push_back (newPf);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (exclCt->empty()) {
|
||||||
|
delete commCt;
|
||||||
|
delete exclCt;
|
||||||
|
g->setFormulaGroup (f, commGroup);
|
||||||
|
} else {
|
||||||
|
Parfactor* newPf = new Parfactor (g, commCt);
|
||||||
|
newPf->setNewGroups();
|
||||||
|
newPf->setFormulaGroup (f, commGroup);
|
||||||
|
result.push_back (newPf);
|
||||||
|
newPf = new Parfactor (g, exclCt);
|
||||||
|
newPf->setNewGroups();
|
||||||
|
result.push_back (newPf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ParfactorList::unifyGroups (unsigned group1, unsigned group2)
|
||||||
|
{
|
||||||
|
unsigned newGroup = ProbFormula::getNewGroup();
|
||||||
|
for (ParfactorList::iterator it = pfList_.begin();
|
||||||
|
it != pfList_.end(); it++) {
|
||||||
|
ProbFormulas& formulas = (*it)->formulas();
|
||||||
|
for (unsigned i = 0; i < formulas.size(); i++) {
|
||||||
|
if (formulas[i].group() == group1 ||
|
||||||
|
formulas[i].group() == group2) {
|
||||||
|
formulas[i].setGroup (newGroup);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
70
packages/CLPBN/clpbn/bp/ParfactorList.h
Normal file
70
packages/CLPBN/clpbn/bp/ParfactorList.h
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
#ifndef HORUS_PARFACTORLIST_H
|
||||||
|
#define HORUS_PARFACTORLIST_H
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
|
||||||
|
#include "Parfactor.h"
|
||||||
|
#include "ProbFormula.h"
|
||||||
|
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
|
||||||
|
class ParfactorList
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ParfactorList (void) { }
|
||||||
|
ParfactorList (Parfactors&);
|
||||||
|
list<Parfactor*>& getParfactors (void) { return pfList_; }
|
||||||
|
const list<Parfactor*>& getParfactors (void) const { return pfList_; }
|
||||||
|
|
||||||
|
void add (Parfactor* pf);
|
||||||
|
void add (Parfactors& pfs);
|
||||||
|
void addShattered (Parfactor* pf);
|
||||||
|
list<Parfactor*>::iterator remove (list<Parfactor*>::iterator);
|
||||||
|
list<Parfactor*>::iterator deleteAndRemove (list<Parfactor*>::iterator);
|
||||||
|
|
||||||
|
void clear (void) { pfList_.clear(); }
|
||||||
|
unsigned size (void) const { return pfList_.size(); }
|
||||||
|
|
||||||
|
|
||||||
|
void shatter (void);
|
||||||
|
|
||||||
|
typedef std::list<Parfactor*>::iterator iterator;
|
||||||
|
iterator begin (void) { return pfList_.begin(); }
|
||||||
|
iterator end (void) { return pfList_.end(); }
|
||||||
|
|
||||||
|
typedef std::list<Parfactor*>::const_iterator const_iterator;
|
||||||
|
const_iterator begin (void) const { return pfList_.begin(); }
|
||||||
|
const_iterator end (void) const { return pfList_.end(); }
|
||||||
|
|
||||||
|
void print (void) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
static std::pair<Parfactors, Parfactors> shatter (
|
||||||
|
ProbFormulas&,
|
||||||
|
Parfactor*,
|
||||||
|
ProbFormulas&,
|
||||||
|
Parfactor*);
|
||||||
|
|
||||||
|
static std::pair<Parfactors, Parfactors> shatter (
|
||||||
|
ProbFormula&,
|
||||||
|
Parfactor*,
|
||||||
|
ProbFormula&,
|
||||||
|
Parfactor*);
|
||||||
|
|
||||||
|
static Parfactors shatter (
|
||||||
|
Parfactor*,
|
||||||
|
const ProbFormula&,
|
||||||
|
ConstraintTree*,
|
||||||
|
ConstraintTree*,
|
||||||
|
unsigned);
|
||||||
|
|
||||||
|
void unifyGroups (unsigned group1, unsigned group2);
|
||||||
|
|
||||||
|
list<Parfactor*> pfList_;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // HORUS_PARFACTORLIST_H
|
||||||
|
|
115
packages/CLPBN/clpbn/bp/ProbFormula.cpp
Normal file
115
packages/CLPBN/clpbn/bp/ProbFormula.cpp
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
#include "ProbFormula.h"
|
||||||
|
|
||||||
|
|
||||||
|
int ProbFormula::freeGroup_ = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
ProbFormula::sameSkeletonAs (const ProbFormula& f) const
|
||||||
|
{
|
||||||
|
return functor_ == f.functor() && logVars_.size() == f.arity();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
ProbFormula::contains (LogVar lv) const
|
||||||
|
{
|
||||||
|
return std::find (logVars_.begin(), logVars_.end(), lv) !=
|
||||||
|
logVars_.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
ProbFormula::contains (LogVarSet s) const
|
||||||
|
{
|
||||||
|
return LogVarSet (logVars_).contains (s);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
ProbFormula::isAtom (void) const
|
||||||
|
{
|
||||||
|
return logVars_.size() == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
ProbFormula::isCounting (void) const
|
||||||
|
{
|
||||||
|
return countedLogVar_.valid();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
LogVar
|
||||||
|
ProbFormula::countedLogVar (void) const
|
||||||
|
{
|
||||||
|
assert (isCounting());
|
||||||
|
return countedLogVar_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ProbFormula::setCountedLogVar (LogVar lv)
|
||||||
|
{
|
||||||
|
countedLogVar_ = lv;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ProbFormula::rename (LogVar oldName, LogVar newName)
|
||||||
|
{
|
||||||
|
for (unsigned i = 0; i < logVars_.size(); i++) {
|
||||||
|
if (logVars_[i] == oldName) {
|
||||||
|
logVars_[i] = newName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isCounting() && countedLogVar_ == oldName) {
|
||||||
|
countedLogVar_ = newName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
ProbFormula::operator== (const ProbFormula& f) const
|
||||||
|
{
|
||||||
|
return functor_ == f.functor_ && logVars_ == f.logVars_ ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ostream& operator<< (ostream &os, const ProbFormula& f)
|
||||||
|
{
|
||||||
|
os << f.functor_;
|
||||||
|
if (f.isAtom() == false) {
|
||||||
|
os << "(" ;
|
||||||
|
for (unsigned i = 0; i < f.logVars_.size(); i++) {
|
||||||
|
if (i != 0) os << ",";
|
||||||
|
if (f.isCounting() && f.logVars_[i] == f.countedLogVar_) {
|
||||||
|
os << "#" ;
|
||||||
|
}
|
||||||
|
os << f.logVars_[i];
|
||||||
|
}
|
||||||
|
os << ")" ;
|
||||||
|
}
|
||||||
|
os << "::" << f.range_;
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
unsigned
|
||||||
|
ProbFormula::getNewGroup (void)
|
||||||
|
{
|
||||||
|
freeGroup_ ++;
|
||||||
|
return freeGroup_;
|
||||||
|
}
|
||||||
|
|
71
packages/CLPBN/clpbn/bp/ProbFormula.h
Normal file
71
packages/CLPBN/clpbn/bp/ProbFormula.h
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
#ifndef HORUS_PROBFORMULA_H
|
||||||
|
#define HORUS_PROBFORMULA_H
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
#include "ConstraintTree.h"
|
||||||
|
#include "LiftedUtils.h"
|
||||||
|
#include "Horus.h"
|
||||||
|
|
||||||
|
|
||||||
|
class ProbFormula
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ProbFormula (Symbol f, const LogVars& lvs, unsigned range)
|
||||||
|
: functor_(f), logVars_(lvs), range_(range),
|
||||||
|
countedLogVar_() { }
|
||||||
|
|
||||||
|
ProbFormula (Symbol f, unsigned r) : functor_(f), range_(r) { }
|
||||||
|
|
||||||
|
Symbol functor (void) const { return functor_; }
|
||||||
|
|
||||||
|
unsigned arity (void) const { return logVars_.size(); }
|
||||||
|
|
||||||
|
unsigned range (void) const { return range_; }
|
||||||
|
|
||||||
|
LogVars& logVars (void) { return logVars_; }
|
||||||
|
|
||||||
|
const LogVars& logVars (void) const { return logVars_; }
|
||||||
|
|
||||||
|
LogVarSet logVarSet (void) const { return LogVarSet (logVars_); }
|
||||||
|
|
||||||
|
unsigned group (void) const { return groupId_; }
|
||||||
|
|
||||||
|
void setGroup (unsigned g) { groupId_ = g; }
|
||||||
|
|
||||||
|
bool sameSkeletonAs (const ProbFormula&) const;
|
||||||
|
|
||||||
|
bool contains (LogVar) const;
|
||||||
|
|
||||||
|
bool contains (LogVarSet) const;
|
||||||
|
|
||||||
|
bool isAtom (void) const;
|
||||||
|
|
||||||
|
bool isCounting (void) const;
|
||||||
|
|
||||||
|
LogVar countedLogVar (void) const;
|
||||||
|
|
||||||
|
void setCountedLogVar (LogVar);
|
||||||
|
|
||||||
|
void rename (LogVar, LogVar);
|
||||||
|
|
||||||
|
bool operator== (const ProbFormula& f) const;
|
||||||
|
|
||||||
|
friend ostream& operator<< (ostream &out, const ProbFormula& f);
|
||||||
|
|
||||||
|
static unsigned getNewGroup (void);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Symbol functor_;
|
||||||
|
LogVars logVars_;
|
||||||
|
unsigned range_;
|
||||||
|
LogVar countedLogVar_;
|
||||||
|
unsigned groupId_;
|
||||||
|
static int freeGroup_;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef vector<ProbFormula> ProbFormulas;
|
||||||
|
|
||||||
|
|
||||||
|
#endif // HORUS_PROBFORMULA_H
|
||||||
|
|
@ -1,308 +0,0 @@
|
|||||||
#ifndef HORUS_SHARED_H
|
|
||||||
#define HORUS_SHARED_H
|
|
||||||
|
|
||||||
#include <cmath>
|
|
||||||
#include <cassert>
|
|
||||||
#include <limits>
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <unordered_map>
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <fstream>
|
|
||||||
|
|
||||||
#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
|
|
||||||
TypeName(const TypeName&); \
|
|
||||||
void operator=(const TypeName&)
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
class VarNode;
|
|
||||||
class BayesNet;
|
|
||||||
class BayesNode;
|
|
||||||
class Factor;
|
|
||||||
class FgVarNode;
|
|
||||||
class FgFacNode;
|
|
||||||
class SpLink;
|
|
||||||
class BpLink;
|
|
||||||
|
|
||||||
typedef double Param;
|
|
||||||
typedef vector<Param> ParamSet;
|
|
||||||
typedef unsigned VarId;
|
|
||||||
typedef vector<VarId> VarIdSet;
|
|
||||||
typedef vector<VarNode*> VarNodes;
|
|
||||||
typedef vector<BayesNode*> BnNodeSet;
|
|
||||||
typedef vector<FgVarNode*> FgVarSet;
|
|
||||||
typedef vector<FgFacNode*> FgFacSet;
|
|
||||||
typedef vector<Factor*> FactorSet;
|
|
||||||
typedef vector<string> States;
|
|
||||||
typedef vector<unsigned> Ranges;
|
|
||||||
typedef vector<unsigned> DConf;
|
|
||||||
typedef pair<unsigned, unsigned> DConstraint;
|
|
||||||
|
|
||||||
|
|
||||||
// level of debug information
|
|
||||||
static const unsigned DL = 0;
|
|
||||||
|
|
||||||
static const int NO_EVIDENCE = -1;
|
|
||||||
|
|
||||||
// number of digits to show when printing a parameter
|
|
||||||
static const unsigned PRECISION = 5;
|
|
||||||
|
|
||||||
static const bool COLLECT_STATISTICS = false;
|
|
||||||
|
|
||||||
static const bool EXPORT_TO_GRAPHVIZ = false;
|
|
||||||
static const unsigned EXPORT_MINIMAL_SIZE = 100;
|
|
||||||
|
|
||||||
static const double INF = -numeric_limits<Param>::infinity();
|
|
||||||
|
|
||||||
|
|
||||||
namespace NumberSpace {
|
|
||||||
enum ns {
|
|
||||||
NORMAL,
|
|
||||||
LOGARITHM
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
extern NumberSpace::ns NSPACE;
|
|
||||||
|
|
||||||
|
|
||||||
namespace InfAlgorithms {
|
|
||||||
enum InfAlgs
|
|
||||||
{
|
|
||||||
VE, // variable elimination
|
|
||||||
BN_BP, // bayesian network belief propagation
|
|
||||||
FG_BP, // factor graph belief propagation
|
|
||||||
CBP // counting bp solver
|
|
||||||
};
|
|
||||||
extern InfAlgs infAlgorithm;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
namespace BpOptions
|
|
||||||
{
|
|
||||||
enum Schedule {
|
|
||||||
SEQ_FIXED,
|
|
||||||
SEQ_RANDOM,
|
|
||||||
PARALLEL,
|
|
||||||
MAX_RESIDUAL
|
|
||||||
};
|
|
||||||
extern Schedule schedule;
|
|
||||||
extern double accuracy;
|
|
||||||
extern unsigned maxIter;
|
|
||||||
extern bool useAlwaysLoopySolver;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
namespace Util
|
|
||||||
{
|
|
||||||
void toLog (ParamSet&);
|
|
||||||
void fromLog (ParamSet&);
|
|
||||||
void normalize (ParamSet&);
|
|
||||||
void logSum (Param&, Param);
|
|
||||||
void multiply (ParamSet&, const ParamSet&);
|
|
||||||
void multiply (ParamSet&, const ParamSet&, unsigned);
|
|
||||||
void add (ParamSet&, const ParamSet&);
|
|
||||||
void add (ParamSet&, const ParamSet&, unsigned);
|
|
||||||
void pow (ParamSet&, unsigned);
|
|
||||||
Param pow (Param, unsigned);
|
|
||||||
double getL1Distance (const ParamSet&, const ParamSet&);
|
|
||||||
double getMaxNorm (const ParamSet&, const ParamSet&);
|
|
||||||
unsigned getNumberOfDigits (int);
|
|
||||||
bool isInteger (const string&);
|
|
||||||
string parametersToString (const ParamSet&, unsigned = PRECISION);
|
|
||||||
BayesNet* generateBayesianNetworkTreeWithLevel (unsigned);
|
|
||||||
vector<DConf> getDomainConfigurations (const VarNodes&);
|
|
||||||
vector<string> getJointStateStrings (const VarNodes&);
|
|
||||||
double tl (Param v);
|
|
||||||
double fl (Param v);
|
|
||||||
double multIdenty();
|
|
||||||
double addIdenty();
|
|
||||||
double withEvidence();
|
|
||||||
double noEvidence();
|
|
||||||
double one();
|
|
||||||
double zero();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
inline void
|
|
||||||
Util::logSum (Param& x, Param y)
|
|
||||||
{
|
|
||||||
// x = log (exp (x) + exp (y)); return;
|
|
||||||
assert (isfinite (x) && finite (y));
|
|
||||||
// If one value is much smaller than the other, keep the larger value.
|
|
||||||
if (x < (y - log (1e200))) {
|
|
||||||
x = y;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (y < (x - log (1e200))) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
double diff = x - y;
|
|
||||||
assert (isfinite (diff) && finite (x) && finite (y));
|
|
||||||
if (!isfinite (exp (diff))) { // difference is too large
|
|
||||||
x = x > y ? x : y;
|
|
||||||
} else { // otherwise return the sum.
|
|
||||||
x = y + log (static_cast<double>(1.0) + exp (diff));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
inline void
|
|
||||||
Util::multiply (ParamSet& v1, const ParamSet& v2)
|
|
||||||
{
|
|
||||||
assert (v1.size() == v2.size());
|
|
||||||
for (unsigned i = 0; i < v1.size(); i++) {
|
|
||||||
v1[i] *= v2[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
inline void
|
|
||||||
Util::multiply (ParamSet& v1, const ParamSet& v2, unsigned repetitions)
|
|
||||||
{
|
|
||||||
for (unsigned count = 0; count < v1.size(); ) {
|
|
||||||
for (unsigned i = 0; i < v2.size(); i++) {
|
|
||||||
for (unsigned r = 0; r < repetitions; r++) {
|
|
||||||
v1[count] *= v2[i];
|
|
||||||
count ++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
inline void
|
|
||||||
Util::add (ParamSet& v1, const ParamSet& v2)
|
|
||||||
{
|
|
||||||
assert (v1.size() == v2.size());
|
|
||||||
for (unsigned i = 0; i < v1.size(); i++) {
|
|
||||||
v1[i] += v2[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
inline void
|
|
||||||
Util::add (ParamSet& v1, const ParamSet& v2, unsigned repetitions)
|
|
||||||
{
|
|
||||||
for (unsigned count = 0; count < v1.size(); ) {
|
|
||||||
for (unsigned i = 0; i < v2.size(); i++) {
|
|
||||||
for (unsigned r = 0; r < repetitions; r++) {
|
|
||||||
v1[count] += v2[i];
|
|
||||||
count ++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
inline double
|
|
||||||
Util::tl (Param v)
|
|
||||||
{
|
|
||||||
return NSPACE == NumberSpace::NORMAL ? v : log(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline double
|
|
||||||
Util::fl (Param v)
|
|
||||||
{
|
|
||||||
return NSPACE == NumberSpace::NORMAL ? v : exp(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline double
|
|
||||||
Util::multIdenty() {
|
|
||||||
return NSPACE == NumberSpace::NORMAL ? 1.0 : 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline double
|
|
||||||
Util::addIdenty()
|
|
||||||
{
|
|
||||||
return NSPACE == NumberSpace::NORMAL ? 0.0 : INF;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline double
|
|
||||||
Util::withEvidence()
|
|
||||||
{
|
|
||||||
return NSPACE == NumberSpace::NORMAL ? 1.0 : 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline double
|
|
||||||
Util::noEvidence() {
|
|
||||||
return NSPACE == NumberSpace::NORMAL ? 0.0 : INF;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline double
|
|
||||||
Util::one()
|
|
||||||
{
|
|
||||||
return NSPACE == NumberSpace::NORMAL ? 1.0 : 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline double
|
|
||||||
Util::zero() {
|
|
||||||
return NSPACE == NumberSpace::NORMAL ? 0.0 : INF;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
struct NetInfo
|
|
||||||
{
|
|
||||||
NetInfo (unsigned size, bool loopy, unsigned nIters, double time)
|
|
||||||
{
|
|
||||||
this->size = size;
|
|
||||||
this->loopy = loopy;
|
|
||||||
this->nIters = nIters;
|
|
||||||
this->time = time;
|
|
||||||
}
|
|
||||||
unsigned size;
|
|
||||||
bool loopy;
|
|
||||||
unsigned nIters;
|
|
||||||
double time;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct CompressInfo
|
|
||||||
{
|
|
||||||
CompressInfo (unsigned a, unsigned b, unsigned c, unsigned d, unsigned e)
|
|
||||||
{
|
|
||||||
nGroundVars = a;
|
|
||||||
nGroundFactors = b;
|
|
||||||
nClusterVars = c;
|
|
||||||
nClusterFactors = d;
|
|
||||||
nWithoutNeighs = e;
|
|
||||||
}
|
|
||||||
unsigned nGroundVars;
|
|
||||||
unsigned nGroundFactors;
|
|
||||||
unsigned nClusterVars;
|
|
||||||
unsigned nClusterFactors;
|
|
||||||
unsigned nWithoutNeighs;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class Statistics
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
static unsigned getSolvedNetworksCounting (void);
|
|
||||||
static void incrementPrimaryNetworksCounting (void);
|
|
||||||
static unsigned getPrimaryNetworksCounting (void);
|
|
||||||
static void updateStatistics (unsigned, bool, unsigned, double);
|
|
||||||
static void printStatistics (void);
|
|
||||||
static void writeStatisticsToFile (const char*);
|
|
||||||
static void updateCompressingStatistics (
|
|
||||||
unsigned, unsigned, unsigned, unsigned, unsigned);
|
|
||||||
|
|
||||||
private:
|
|
||||||
static string getStatisticString (void);
|
|
||||||
|
|
||||||
static vector<NetInfo> netInfo_;
|
|
||||||
static vector<CompressInfo> compressInfo_;
|
|
||||||
static unsigned primaryNetCount_;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // HORUS_SHARED_H
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
|||||||
#include "Solver.h"
|
#include "Solver.h"
|
||||||
|
#include "Util.h"
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -7,7 +8,6 @@ Solver::printAllPosterioris (void)
|
|||||||
const VarNodes& vars = gm_->getVariableNodes();
|
const VarNodes& vars = gm_->getVariableNodes();
|
||||||
for (unsigned i = 0; i < vars.size(); i++) {
|
for (unsigned i = 0; i < vars.size(); i++) {
|
||||||
printPosterioriOf (vars[i]->varId());
|
printPosterioriOf (vars[i]->varId());
|
||||||
cout << endl;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -17,7 +17,7 @@ void
|
|||||||
Solver::printPosterioriOf (VarId vid)
|
Solver::printPosterioriOf (VarId vid)
|
||||||
{
|
{
|
||||||
VarNode* var = gm_->getVariableNode (vid);
|
VarNode* var = gm_->getVariableNode (vid);
|
||||||
const ParamSet& posterioriDist = getPosterioriOf (vid);
|
const Params& posterioriDist = getPosterioriOf (vid);
|
||||||
const States& states = var->states();
|
const States& states = var->states();
|
||||||
for (unsigned i = 0; i < states.size(); i++) {
|
for (unsigned i = 0; i < states.size(); i++) {
|
||||||
cout << "P(" << var->label() << "=" << states[i] << ") = " ;
|
cout << "P(" << var->label() << "=" << states[i] << ") = " ;
|
||||||
@ -30,10 +30,10 @@ Solver::printPosterioriOf (VarId vid)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Solver::printJointDistributionOf (const VarIdSet& vids)
|
Solver::printJointDistributionOf (const VarIds& vids)
|
||||||
{
|
{
|
||||||
VarNodes vars;
|
VarNodes vars;
|
||||||
VarIdSet vidsWithoutEvidence;
|
VarIds vidsWithoutEvidence;
|
||||||
for (unsigned i = 0; i < vids.size(); i++) {
|
for (unsigned i = 0; i < vids.size(); i++) {
|
||||||
VarNode* var = gm_->getVariableNode (vids[i]);
|
VarNode* var = gm_->getVariableNode (vids[i]);
|
||||||
if (var->hasEvidence() == false) {
|
if (var->hasEvidence() == false) {
|
||||||
@ -41,7 +41,7 @@ Solver::printJointDistributionOf (const VarIdSet& vids)
|
|||||||
vidsWithoutEvidence.push_back (vids[i]);
|
vidsWithoutEvidence.push_back (vids[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const ParamSet& jointDist = getJointDistributionOf (vidsWithoutEvidence);
|
const Params& jointDist = getJointDistributionOf (vidsWithoutEvidence);
|
||||||
vector<string> jointStrings = Util::getJointStateStrings (vars);
|
vector<string> jointStrings = Util::getJointStateStrings (vars);
|
||||||
for (unsigned i = 0; i < jointDist.size(); i++) {
|
for (unsigned i = 0; i < jointDist.size(); i++) {
|
||||||
cout << "P(" << jointStrings[i] << ") = " ;
|
cout << "P(" << jointStrings[i] << ") = " ;
|
||||||
|
@ -17,12 +17,12 @@ class Solver
|
|||||||
}
|
}
|
||||||
virtual ~Solver() {} // to ensure that subclass destructor is called
|
virtual ~Solver() {} // to ensure that subclass destructor is called
|
||||||
virtual void runSolver (void) = 0;
|
virtual void runSolver (void) = 0;
|
||||||
virtual ParamSet getPosterioriOf (VarId) = 0;
|
virtual Params getPosterioriOf (VarId) = 0;
|
||||||
virtual ParamSet getJointDistributionOf (const VarIdSet&) = 0;
|
virtual Params getJointDistributionOf (const VarIds&) = 0;
|
||||||
|
|
||||||
void printAllPosterioris (void);
|
void printAllPosterioris (void);
|
||||||
void printPosterioriOf (VarId vid);
|
void printPosterioriOf (VarId vid);
|
||||||
void printJointDistributionOf (const VarIdSet& vids);
|
void printJointDistributionOf (const VarIds& vids);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const GraphicalModel* gm_;
|
const GraphicalModel* gm_;
|
||||||
|
@ -1,246 +0,0 @@
|
|||||||
#ifndef HORUS_STATESINDEXER_H
|
|
||||||
#define HORUS_STATESINDEXER_H
|
|
||||||
|
|
||||||
#include <iomanip>
|
|
||||||
|
|
||||||
class StatesIndexer {
|
|
||||||
public:
|
|
||||||
|
|
||||||
StatesIndexer (const Ranges& ranges)
|
|
||||||
{
|
|
||||||
maxIndex_ = 1;
|
|
||||||
states_.resize (ranges.size(), 0);
|
|
||||||
ranges_ = ranges;
|
|
||||||
for (unsigned i = 0; i < ranges.size(); i++) {
|
|
||||||
maxIndex_ *= ranges[i];
|
|
||||||
}
|
|
||||||
linearIndex_ = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
StatesIndexer (const VarNodes& vars)
|
|
||||||
{
|
|
||||||
maxIndex_ = 1;
|
|
||||||
states_.resize (vars.size(), 0);
|
|
||||||
ranges_.reserve (vars.size());
|
|
||||||
for (unsigned i = 0; i < vars.size(); i++) {
|
|
||||||
ranges_.push_back (vars[i]->nrStates());
|
|
||||||
maxIndex_ *= vars[i]->nrStates();
|
|
||||||
}
|
|
||||||
linearIndex_ = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
StatesIndexer& operator++ (void) {
|
|
||||||
for (int i = ranges_.size() - 1; i >= 0; i--) {
|
|
||||||
states_[i] ++;
|
|
||||||
if (states_[i] == (int)ranges_[i]) {
|
|
||||||
states_[i] = 0;
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
linearIndex_ ++;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
StatesIndexer& operator-- (void) {
|
|
||||||
for (int i = ranges_.size() - 1; i >= 0; i--) {
|
|
||||||
states_[i] --;
|
|
||||||
if (states_[i] == -1) {
|
|
||||||
states_[i] = ranges_[i] - 1;
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
linearIndex_ --;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
void incrementState (unsigned whichVar)
|
|
||||||
{
|
|
||||||
for (int i = whichVar; i >= 0; i--) {
|
|
||||||
states_[i] ++;
|
|
||||||
if (states_[i] == (int)ranges_[i] && i != 0) {
|
|
||||||
if (i == 0) {
|
|
||||||
linearIndex_ = maxIndex_;
|
|
||||||
} else {
|
|
||||||
states_[i] = 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
linearIndex_ = getLinearIndexFromStates();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void decrementState (unsigned whichVar)
|
|
||||||
{
|
|
||||||
for (int i = whichVar; i >= 0; i--) {
|
|
||||||
states_[i] --;
|
|
||||||
if (states_[i] == -1) {
|
|
||||||
if (i == 0) {
|
|
||||||
linearIndex_ = -1;
|
|
||||||
} else {
|
|
||||||
states_[i] = ranges_[i] - 1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
linearIndex_ = getLinearIndexFromStates();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void nextSameState (unsigned whichVar)
|
|
||||||
{
|
|
||||||
for (int i = ranges_.size() - 1; i >= 0; i--) {
|
|
||||||
if (i != (int)whichVar) {
|
|
||||||
states_[i] ++;
|
|
||||||
if (states_[i] == (int)ranges_[i]) {
|
|
||||||
if (i == 0 || (i-1 == (int)whichVar && whichVar == 0)) {
|
|
||||||
linearIndex_ = maxIndex_;
|
|
||||||
} else {
|
|
||||||
states_[i] = 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
linearIndex_ = getLinearIndexFromStates();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void previousSameState (unsigned whichVar)
|
|
||||||
{
|
|
||||||
for (int i = ranges_.size() - 1; i >= 0; i--) {
|
|
||||||
if (i != (int)whichVar) {
|
|
||||||
states_[i] --;
|
|
||||||
if (states_[i] == - 1) {
|
|
||||||
if (i == 0 || (i-1 == (int)whichVar && whichVar == 0)) {
|
|
||||||
linearIndex_ = -1;
|
|
||||||
} else {
|
|
||||||
states_[i] = ranges_[i] - 1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
linearIndex_ = getLinearIndexFromStates();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void moveToBegin (void)
|
|
||||||
{
|
|
||||||
std::fill (states_.begin(), states_.end(), 0);
|
|
||||||
linearIndex_ = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void moveToEnd (void)
|
|
||||||
{
|
|
||||||
for (unsigned i = 0; i < states_.size(); i++) {
|
|
||||||
states_[i] = ranges_[i] - 1;
|
|
||||||
}
|
|
||||||
linearIndex_ = maxIndex_ - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool valid (void) const
|
|
||||||
{
|
|
||||||
return linearIndex_ >= 0 && linearIndex_ < (int)maxIndex_;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned getLinearIndex (void) const
|
|
||||||
{
|
|
||||||
return linearIndex_;
|
|
||||||
}
|
|
||||||
|
|
||||||
const vector<int>& getStates (void) const
|
|
||||||
{
|
|
||||||
return states_;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned operator[] (unsigned whichVar) const
|
|
||||||
{
|
|
||||||
assert (valid());
|
|
||||||
assert (whichVar < states_.size());
|
|
||||||
return states_[whichVar];
|
|
||||||
}
|
|
||||||
|
|
||||||
string toString (void) const
|
|
||||||
{
|
|
||||||
stringstream ss;
|
|
||||||
ss << "linear index=" << setw (3) << linearIndex_ << " " ;
|
|
||||||
ss << "states= [" << states_[0] ;
|
|
||||||
for (unsigned i = 1; i < states_.size(); i++) {
|
|
||||||
ss << ", " << states_[i];
|
|
||||||
}
|
|
||||||
ss << "]" ;
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
unsigned getLinearIndexFromStates (void)
|
|
||||||
{
|
|
||||||
unsigned prod = 1;
|
|
||||||
unsigned linearIndex = 0;
|
|
||||||
for (int i = states_.size() - 1; i >= 0; i--) {
|
|
||||||
linearIndex += states_[i] * prod;
|
|
||||||
prod *= ranges_[i];
|
|
||||||
}
|
|
||||||
return linearIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
int linearIndex_;
|
|
||||||
int maxIndex_;
|
|
||||||
vector<int> states_;
|
|
||||||
vector<unsigned> ranges_;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
FgVarNode* v1 = new FgVarNode (0, 4);
|
|
||||||
FgVarNode* v2 = new FgVarNode (1, 3);
|
|
||||||
FgVarNode* v3 = new FgVarNode (2, 2);
|
|
||||||
FgVarSet vars = {v1,v2,v3};
|
|
||||||
ParamSet params = {
|
|
||||||
0.2, 0.44, 0.1, 0.88, 0.22,0.62,0.32, 0.42, 0.11, 0.88, 0.8,0.5,
|
|
||||||
0.22, 0.4, 0.11, 0.8, 0.224,0.6,0.21, 0.44, 0.14, 0.68, 0.41,0.6
|
|
||||||
};
|
|
||||||
Factor f (vars,params);
|
|
||||||
StatesIndexer idx (vars);
|
|
||||||
while (idx.valid())
|
|
||||||
{
|
|
||||||
cout << idx.toString() << " p=" << params[idx.getLinearIndex()] << endl;
|
|
||||||
idx.incrementVariableState (0);
|
|
||||||
idx.nextSameState (1);
|
|
||||||
++idx;
|
|
||||||
}
|
|
||||||
cout << endl;
|
|
||||||
idx.moveToEnd();
|
|
||||||
while (idx.valid())
|
|
||||||
{
|
|
||||||
cout << idx.toString() << " p=" << params[idx.getLinearIndex()] << endl;
|
|
||||||
idx.decrementVariableState (0);
|
|
||||||
idx.previousSameState (1);
|
|
||||||
--idx;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
FgVarNode* x0 = new FgVarNode (0, 2);
|
|
||||||
FgVarNode* x1 = new FgVarNode (1, 2);
|
|
||||||
FgVarNode* x2 = new FgVarNode (2, 2);
|
|
||||||
FgVarNode* x3 = new FgVarNode (2, 2);
|
|
||||||
FgVarNode* x4 = new FgVarNode (2, 2);
|
|
||||||
FgVarSet vars_ = {x0,x1,x2,x3,x4};
|
|
||||||
ParamSet params_ = {
|
|
||||||
0.2, 0.44, 0.1, 0.88, 0.11, 0.88, 0.8, 0.5,
|
|
||||||
0.2, 0.44, 0.1, 0.88, 0.11, 0.88, 0.8, 0.5,
|
|
||||||
0.2, 0.44, 0.1, 0.88, 0.11, 0.88, 0.8, 0.5,
|
|
||||||
0.2, 0.44, 0.1, 0.88, 0.11, 0.88, 0.8, 0.5
|
|
||||||
};
|
|
||||||
Factor ff (vars_,params_);
|
|
||||||
ff.printFactor();
|
|
||||||
*/
|
|
||||||
|
|
||||||
#endif // HORUS_STATESINDEXER_H
|
|
||||||
|
|
200
packages/CLPBN/clpbn/bp/TinySet.h
Normal file
200
packages/CLPBN/clpbn/bp/TinySet.h
Normal file
@ -0,0 +1,200 @@
|
|||||||
|
#ifndef HORUS_TINYSET_H
|
||||||
|
#define HORUS_TINYSET_H
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class TinySet
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TinySet (void) {}
|
||||||
|
|
||||||
|
TinySet (const T& t)
|
||||||
|
{
|
||||||
|
elements_.push_back (t);
|
||||||
|
}
|
||||||
|
|
||||||
|
TinySet (const vector<T>& elements)
|
||||||
|
{
|
||||||
|
elements_.reserve (elements.size());
|
||||||
|
for (unsigned i = 0; i < elements.size(); i++) {
|
||||||
|
insert (elements[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TinySet (const TinySet<T>& s) : elements_(s.elements_) { }
|
||||||
|
|
||||||
|
void insert (const T& t)
|
||||||
|
{
|
||||||
|
typename vector<T>::iterator it =
|
||||||
|
std::lower_bound (elements_.begin(), elements_.end(), t);
|
||||||
|
if (it == elements_.end() || *it != t) {
|
||||||
|
elements_.insert (it, t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void remove (const T& t)
|
||||||
|
{
|
||||||
|
typename vector<T>::iterator it =
|
||||||
|
std::lower_bound (elements_.begin(), elements_.end(), t);
|
||||||
|
if (it != elements_.end()) {
|
||||||
|
elements_.erase (it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set union */
|
||||||
|
TinySet operator| (const TinySet& s) const
|
||||||
|
{
|
||||||
|
TinySet res;
|
||||||
|
std::set_union (
|
||||||
|
elements_.begin(),
|
||||||
|
elements_.end(),
|
||||||
|
s.elements_.begin(),
|
||||||
|
s.elements_.end(),
|
||||||
|
std::back_inserter (res.elements_));
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set intersection */
|
||||||
|
TinySet operator& (const TinySet& s) const
|
||||||
|
{
|
||||||
|
TinySet res;
|
||||||
|
std::set_intersection (
|
||||||
|
elements_.begin(),
|
||||||
|
elements_.end(),
|
||||||
|
s.elements_.begin(),
|
||||||
|
s.elements_.end(),
|
||||||
|
std::back_inserter (res.elements_));
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set difference */
|
||||||
|
TinySet operator- (const TinySet& s) const
|
||||||
|
{
|
||||||
|
TinySet res;
|
||||||
|
std::set_difference (
|
||||||
|
elements_.begin(),
|
||||||
|
elements_.end(),
|
||||||
|
s.elements_.begin(),
|
||||||
|
s.elements_.end(),
|
||||||
|
std::back_inserter (res.elements_));
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
TinySet& operator|= (const TinySet& s)
|
||||||
|
{
|
||||||
|
return *this = (*this | s);
|
||||||
|
}
|
||||||
|
|
||||||
|
TinySet& operator&= (const TinySet& s)
|
||||||
|
{
|
||||||
|
return *this = (*this & s);
|
||||||
|
}
|
||||||
|
|
||||||
|
TinySet& operator-= (const TinySet& s)
|
||||||
|
{
|
||||||
|
return *this = (*this - s);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool contains (const T& t) const
|
||||||
|
{
|
||||||
|
return std::binary_search (
|
||||||
|
elements_.begin(), elements_.end(), t);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool contains (const TinySet& s) const
|
||||||
|
{
|
||||||
|
return std::includes (
|
||||||
|
elements_.begin(),
|
||||||
|
elements_.end(),
|
||||||
|
s.elements_.begin(),
|
||||||
|
s.elements_.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool in (const TinySet& s) const
|
||||||
|
{
|
||||||
|
return std::includes (
|
||||||
|
s.elements_.begin(),
|
||||||
|
s.elements_.end(),
|
||||||
|
elements_.begin(),
|
||||||
|
elements_.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool intersects (const TinySet& s) const
|
||||||
|
{
|
||||||
|
return (*this & s).size() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
T operator[] (unsigned i) const
|
||||||
|
{
|
||||||
|
return elements_[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
const vector<T>& elements (void) const
|
||||||
|
{
|
||||||
|
return elements_;
|
||||||
|
}
|
||||||
|
|
||||||
|
T front (void) const
|
||||||
|
{
|
||||||
|
return elements_.front();
|
||||||
|
}
|
||||||
|
|
||||||
|
T back (void) const
|
||||||
|
{
|
||||||
|
return elements_.back();
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned size (void) const
|
||||||
|
{
|
||||||
|
return elements_.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool empty (void) const
|
||||||
|
{
|
||||||
|
return elements_.size() == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef typename std::vector<T>::const_iterator const_iterator;
|
||||||
|
|
||||||
|
const_iterator begin (void) const
|
||||||
|
{
|
||||||
|
return elements_.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
const_iterator end (void) const
|
||||||
|
{
|
||||||
|
return elements_.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator== (const TinySet& s1, const TinySet& s2)
|
||||||
|
{
|
||||||
|
return s1.elements_ == s2.elements_;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator!= (const TinySet& s1, const TinySet& s2)
|
||||||
|
{
|
||||||
|
return s1.elements_ != s2.elements_;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend std::ostream& operator << (std::ostream& out, const TinySet<T>& s)
|
||||||
|
{
|
||||||
|
out << "{" ;
|
||||||
|
for (unsigned i = 0; i < s.size(); i++) {
|
||||||
|
out << ((i != 0) ? "," : "") << s.elements()[i];
|
||||||
|
}
|
||||||
|
out << "}" ;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
vector<T> elements_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // HORUS_TINYSET_H
|
||||||
|
|
@ -1,14 +1,19 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
#include "BayesNet.h"
|
#include "Util.h"
|
||||||
#include "VarNode.h"
|
#include "Indexer.h"
|
||||||
#include "Shared.h"
|
#include "GraphicalModel.h"
|
||||||
#include "StatesIndexer.h"
|
|
||||||
|
|
||||||
|
namespace Globals {
|
||||||
|
bool logDomain = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
namespace InfAlgorithms {
|
namespace InfAlgorithms {
|
||||||
InfAlgs infAlgorithm = InfAlgorithms::VE;
|
//InfAlgs infAlgorithm = InfAlgorithms::VE;
|
||||||
//InfAlgs infAlgorithm = InfAlgorithms::BN_BP;
|
//InfAlgs infAlgorithm = InfAlgorithms::BN_BP;
|
||||||
//InfAlgs infAlgorithm = InfAlgorithms::FG_BP;
|
InfAlgs infAlgorithm = InfAlgorithms::FG_BP;
|
||||||
//InfAlgs infAlgorithm = InfAlgorithms::CBP;
|
//InfAlgs infAlgorithm = InfAlgorithms::CBP;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -20,12 +25,11 @@ Schedule schedule = BpOptions::Schedule::SEQ_FIXED;
|
|||||||
//Schedule schedule = BpOptions::Schedule::MAX_RESIDUAL;
|
//Schedule schedule = BpOptions::Schedule::MAX_RESIDUAL;
|
||||||
double accuracy = 0.0001;
|
double accuracy = 0.0001;
|
||||||
unsigned maxIter = 1000;
|
unsigned maxIter = 1000;
|
||||||
bool useAlwaysLoopySolver = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NumberSpace::ns NSPACE = NumberSpace::NORMAL;
|
|
||||||
|
|
||||||
unordered_map<VarId,VariableInfo> GraphicalModel::varsInfo_;
|
unordered_map<VarId,VariableInfo> GraphicalModel::varsInfo_;
|
||||||
|
unordered_map<unsigned,Distribution*> GraphicalModel::distsInfo_;
|
||||||
|
|
||||||
vector<NetInfo> Statistics::netInfo_;
|
vector<NetInfo> Statistics::netInfo_;
|
||||||
vector<CompressInfo> Statistics::compressInfo_;
|
vector<CompressInfo> Statistics::compressInfo_;
|
||||||
@ -35,7 +39,7 @@ unsigned Statistics::primaryNetCount_;
|
|||||||
namespace Util {
|
namespace Util {
|
||||||
|
|
||||||
void
|
void
|
||||||
toLog (ParamSet& v)
|
toLog (Params& v)
|
||||||
{
|
{
|
||||||
for (unsigned i = 0; i < v.size(); i++) {
|
for (unsigned i = 0; i < v.size(); i++) {
|
||||||
v[i] = log (v[i]);
|
v[i] = log (v[i]);
|
||||||
@ -45,7 +49,7 @@ toLog (ParamSet& v)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
fromLog (ParamSet& v)
|
fromLog (Params& v)
|
||||||
{
|
{
|
||||||
for (unsigned i = 0; i < v.size(); i++) {
|
for (unsigned i = 0; i < v.size(); i++) {
|
||||||
v[i] = exp (v[i]);
|
v[i] = exp (v[i]);
|
||||||
@ -55,92 +59,113 @@ fromLog (ParamSet& v)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
normalize (ParamSet& v)
|
normalize (Params& v)
|
||||||
{
|
{
|
||||||
double sum;
|
double sum;
|
||||||
switch (NSPACE) {
|
if (Globals::logDomain) {
|
||||||
case NumberSpace::NORMAL:
|
sum = addIdenty();
|
||||||
sum = 0.0;
|
for (unsigned i = 0; i < v.size(); i++) {
|
||||||
for (unsigned i = 0; i < v.size(); i++) {
|
logSum (sum, v[i]);
|
||||||
sum += v[i];
|
}
|
||||||
}
|
assert (sum != -numeric_limits<double>::infinity());
|
||||||
assert (sum != 0.0);
|
for (unsigned i = 0; i < v.size(); i++) {
|
||||||
for (unsigned i = 0; i < v.size(); i++) {
|
v[i] -= sum;
|
||||||
v[i] /= sum;
|
}
|
||||||
}
|
} else {
|
||||||
break;
|
sum = 0.0;
|
||||||
case NumberSpace::LOGARITHM:
|
for (unsigned i = 0; i < v.size(); i++) {
|
||||||
sum = addIdenty();
|
sum += v[i];
|
||||||
for (unsigned i = 0; i < v.size(); i++) {
|
}
|
||||||
logSum (sum, v[i]);
|
assert (sum != 0.0);
|
||||||
}
|
for (unsigned i = 0; i < v.size(); i++) {
|
||||||
assert (sum != -numeric_limits<Param>::infinity());
|
v[i] /= sum;
|
||||||
for (unsigned i = 0; i < v.size(); i++) {
|
}
|
||||||
v[i] -= sum;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
pow (ParamSet& v, unsigned expoent)
|
pow (Params& v, double expoent)
|
||||||
{
|
{
|
||||||
if (expoent == 1) {
|
if (Globals::logDomain) {
|
||||||
return; // optimization
|
for (unsigned i = 0; i < v.size(); i++) {
|
||||||
}
|
v[i] *= expoent;
|
||||||
switch (NSPACE) {
|
}
|
||||||
case NumberSpace::NORMAL:
|
} else {
|
||||||
for (unsigned i = 0; i < v.size(); i++) {
|
for (unsigned i = 0; i < v.size(); i++) {
|
||||||
double value = 1.0;
|
v[i] = std::pow (v[i], expoent);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Param
|
void
|
||||||
pow (Param p, unsigned expoent)
|
pow (Params& v, unsigned expoent)
|
||||||
{
|
{
|
||||||
double value = 1.0;
|
if (expoent == 1) {
|
||||||
switch (NSPACE) {
|
return;
|
||||||
case NumberSpace::NORMAL:
|
}
|
||||||
for (unsigned i = 0; i < expoent; i++) {
|
if (Globals::logDomain) {
|
||||||
value *= p;
|
for (unsigned i = 0; i < v.size(); i++) {
|
||||||
}
|
v[i] *= expoent;
|
||||||
break;
|
}
|
||||||
case NumberSpace::LOGARITHM:
|
} else {
|
||||||
value = p * expoent;
|
for (unsigned i = 0; i < v.size(); i++) {
|
||||||
|
v[i] = std::pow (v[i], expoent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
double
|
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());
|
assert (v1.size() == v2.size());
|
||||||
double dist = 0.0;
|
double dist = 0.0;
|
||||||
switch (NSPACE) {
|
if (Globals::logDomain) {
|
||||||
case NumberSpace::NORMAL:
|
for (unsigned i = 0; i < v1.size(); i++) {
|
||||||
for (unsigned i = 0; i < v1.size(); i++) {
|
dist += abs (exp(v1[i]) - exp(v2[i]));
|
||||||
dist += abs (v1[i] - v2[i]);
|
}
|
||||||
}
|
} else {
|
||||||
break;
|
for (unsigned i = 0; i < v1.size(); i++) {
|
||||||
case NumberSpace::LOGARITHM:
|
dist += abs (v1[i] - v2[i]);
|
||||||
for (unsigned i = 0; i < v1.size(); i++) {
|
}
|
||||||
dist += abs (exp(v1[i]) - exp(v2[i]));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return dist;
|
return dist;
|
||||||
}
|
}
|
||||||
@ -148,26 +173,24 @@ getL1Distance (const ParamSet& v1, const ParamSet& v2)
|
|||||||
|
|
||||||
|
|
||||||
double
|
double
|
||||||
getMaxNorm (const ParamSet& v1, const ParamSet& v2)
|
getMaxNorm (const Params& v1, const Params& v2)
|
||||||
{
|
{
|
||||||
assert (v1.size() == v2.size());
|
assert (v1.size() == v2.size());
|
||||||
double max = 0.0;
|
double max = 0.0;
|
||||||
switch (NSPACE) {
|
if (Globals::logDomain) {
|
||||||
case NumberSpace::NORMAL:
|
for (unsigned i = 0; i < v1.size(); i++) {
|
||||||
for (unsigned i = 0; i < v1.size(); i++) {
|
double diff = abs (exp(v1[i]) - exp(v2[i]));
|
||||||
double diff = abs (v1[i] - v2[i]);
|
if (diff > max) {
|
||||||
if (diff > max) {
|
max = diff;
|
||||||
max = diff;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
case NumberSpace::LOGARITHM:
|
} else {
|
||||||
for (unsigned i = 0; i < v1.size(); i++) {
|
for (unsigned i = 0; i < v1.size(); i++) {
|
||||||
double diff = abs (exp(v1[i]) - exp(v2[i]));
|
double diff = abs (v1[i] - v2[i]);
|
||||||
if (diff > max) {
|
if (diff > max) {
|
||||||
max = diff;
|
max = diff;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return max;
|
return max;
|
||||||
}
|
}
|
||||||
@ -200,16 +223,14 @@ isInteger (const string& s)
|
|||||||
|
|
||||||
|
|
||||||
string
|
string
|
||||||
parametersToString (const ParamSet& v, unsigned precision)
|
parametersToString (const Params& v, unsigned precision)
|
||||||
{
|
{
|
||||||
stringstream ss;
|
stringstream ss;
|
||||||
ss.precision (precision);
|
ss.precision (precision);
|
||||||
ss << "[" ;
|
ss << "[" ;
|
||||||
for (unsigned i = 0; i < v.size() - 1; i++) {
|
for (unsigned i = 0; i < v.size(); i++) {
|
||||||
ss << v[i] << ", " ;
|
if (i != 0) ss << ", " ;
|
||||||
}
|
ss << v[i];
|
||||||
if (v.size() != 0) {
|
|
||||||
ss << v[v.size() - 1];
|
|
||||||
}
|
}
|
||||||
ss << "]" ;
|
ss << "]" ;
|
||||||
return ss.str();
|
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>
|
vector<string>
|
||||||
getJointStateStrings (const VarNodes& vars)
|
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 << "max iterations: " << BpOptions::maxIter << endl;
|
||||||
ss1 << "accuracy " << BpOptions::accuracy << 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;
|
ss1 << endl << endl;
|
||||||
|
|
||||||
ss2 << "---------------------------------------------------" << endl;
|
ss2 << "---------------------------------------------------" << endl;
|
||||||
|
244
packages/CLPBN/clpbn/bp/Util.h
Normal file
244
packages/CLPBN/clpbn/bp/Util.h
Normal file
@ -0,0 +1,244 @@
|
|||||||
|
#ifndef HORUS_UTIL_H
|
||||||
|
#define HORUS_UTIL_H
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "Horus.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
namespace Util {
|
||||||
|
|
||||||
|
void toLog (Params&);
|
||||||
|
void fromLog (Params&);
|
||||||
|
void normalize (Params&);
|
||||||
|
void logSum (double&, double);
|
||||||
|
void multiply (Params&, const Params&);
|
||||||
|
void multiply (Params&, const Params&, unsigned);
|
||||||
|
void add (Params&, const Params&);
|
||||||
|
void add (Params&, const Params&, unsigned);
|
||||||
|
void pow (Params&, double);
|
||||||
|
void pow (Params&, unsigned);
|
||||||
|
double pow (double, unsigned);
|
||||||
|
double factorial (double);
|
||||||
|
unsigned nrCombinations (unsigned, unsigned);
|
||||||
|
double getL1Distance (const Params&, const Params&);
|
||||||
|
double getMaxNorm (const Params&, const Params&);
|
||||||
|
unsigned getNumberOfDigits (int);
|
||||||
|
bool isInteger (const string&);
|
||||||
|
string parametersToString (const Params&, unsigned = PRECISION);
|
||||||
|
vector<string> getJointStateStrings (const VarNodes&);
|
||||||
|
double tl (double);
|
||||||
|
double fl (double);
|
||||||
|
double multIdenty();
|
||||||
|
double addIdenty();
|
||||||
|
double withEvidence();
|
||||||
|
double noEvidence();
|
||||||
|
double one();
|
||||||
|
double zero();
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
std::string toString (const T& t)
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << t;
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
std::ostream& operator << (std::ostream& os, const vector<T>& v)
|
||||||
|
{
|
||||||
|
os << "[" ;
|
||||||
|
for (unsigned i = 0; i < v.size(); i++) {
|
||||||
|
os << ((i != 0) ? ", " : "") << v[i];
|
||||||
|
}
|
||||||
|
os << "]" ;
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline void
|
||||||
|
Util::logSum (double& x, double y)
|
||||||
|
{
|
||||||
|
x = log (exp (x) + exp (y)); return;
|
||||||
|
assert (isfinite (x) && isfinite (y));
|
||||||
|
// If one value is much smaller than the other, keep the larger value.
|
||||||
|
if (x < (y - log (1e200))) {
|
||||||
|
x = y;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (y < (x - log (1e200))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
double diff = x - y;
|
||||||
|
assert (isfinite (diff) && isfinite (x) && isfinite (y));
|
||||||
|
if (!isfinite (exp (diff))) { // difference is too large
|
||||||
|
x = x > y ? x : y;
|
||||||
|
} else { // otherwise return the sum.
|
||||||
|
x = y + log (static_cast<double>(1.0) + exp (diff));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline void
|
||||||
|
Util::multiply (Params& v1, const Params& v2)
|
||||||
|
{
|
||||||
|
assert (v1.size() == v2.size());
|
||||||
|
for (unsigned i = 0; i < v1.size(); i++) {
|
||||||
|
v1[i] *= v2[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline void
|
||||||
|
Util::multiply (Params& v1, const Params& v2, unsigned repetitions)
|
||||||
|
{
|
||||||
|
for (unsigned count = 0; count < v1.size(); ) {
|
||||||
|
for (unsigned i = 0; i < v2.size(); i++) {
|
||||||
|
for (unsigned r = 0; r < repetitions; r++) {
|
||||||
|
v1[count] *= v2[i];
|
||||||
|
count ++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline void
|
||||||
|
Util::add (Params& v1, const Params& v2)
|
||||||
|
{
|
||||||
|
assert (v1.size() == v2.size());
|
||||||
|
for (unsigned i = 0; i < v1.size(); i++) {
|
||||||
|
v1[i] += v2[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline void
|
||||||
|
Util::add (Params& v1, const Params& v2, unsigned repetitions)
|
||||||
|
{
|
||||||
|
for (unsigned count = 0; count < v1.size(); ) {
|
||||||
|
for (unsigned i = 0; i < v2.size(); i++) {
|
||||||
|
for (unsigned r = 0; r < repetitions; r++) {
|
||||||
|
v1[count] += v2[i];
|
||||||
|
count ++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline double
|
||||||
|
Util::tl (double v)
|
||||||
|
{
|
||||||
|
return Globals::logDomain ? log(v) : v;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double
|
||||||
|
Util::fl (double v)
|
||||||
|
{
|
||||||
|
return Globals::logDomain ? exp(v) : v;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double
|
||||||
|
Util::multIdenty() {
|
||||||
|
return Globals::logDomain ? 0.0 : 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double
|
||||||
|
Util::addIdenty()
|
||||||
|
{
|
||||||
|
return Globals::logDomain ? INF : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double
|
||||||
|
Util::withEvidence()
|
||||||
|
{
|
||||||
|
return Globals::logDomain ? 0.0 : 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double
|
||||||
|
Util::noEvidence() {
|
||||||
|
return Globals::logDomain ? INF : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double
|
||||||
|
Util::one()
|
||||||
|
{
|
||||||
|
return Globals::logDomain ? 0.0 : 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double
|
||||||
|
Util::zero() {
|
||||||
|
return Globals::logDomain ? INF : 0.0 ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct NetInfo
|
||||||
|
{
|
||||||
|
NetInfo (unsigned size, bool loopy, unsigned nIters, double time)
|
||||||
|
{
|
||||||
|
this->size = size;
|
||||||
|
this->loopy = loopy;
|
||||||
|
this->nIters = nIters;
|
||||||
|
this->time = time;
|
||||||
|
}
|
||||||
|
unsigned size;
|
||||||
|
bool loopy;
|
||||||
|
unsigned nIters;
|
||||||
|
double time;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct CompressInfo
|
||||||
|
{
|
||||||
|
CompressInfo (unsigned a, unsigned b, unsigned c, unsigned d, unsigned e)
|
||||||
|
{
|
||||||
|
nGroundVars = a;
|
||||||
|
nGroundFactors = b;
|
||||||
|
nClusterVars = c;
|
||||||
|
nClusterFactors = d;
|
||||||
|
nWithoutNeighs = e;
|
||||||
|
}
|
||||||
|
unsigned nGroundVars;
|
||||||
|
unsigned nGroundFactors;
|
||||||
|
unsigned nClusterVars;
|
||||||
|
unsigned nClusterFactors;
|
||||||
|
unsigned nWithoutNeighs;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Statistics
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static unsigned getSolvedNetworksCounting (void);
|
||||||
|
static void incrementPrimaryNetworksCounting (void);
|
||||||
|
static unsigned getPrimaryNetworksCounting (void);
|
||||||
|
static void updateStatistics (unsigned, bool, unsigned, double);
|
||||||
|
static void printStatistics (void);
|
||||||
|
static void writeStatisticsToFile (const char*);
|
||||||
|
static void updateCompressingStatistics (
|
||||||
|
unsigned, unsigned, unsigned, unsigned, unsigned);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static string getStatisticString (void);
|
||||||
|
|
||||||
|
static vector<NetInfo> netInfo_;
|
||||||
|
static vector<CompressInfo> compressInfo_;
|
||||||
|
static unsigned primaryNetCount_;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // HORUS_UTIL_H
|
||||||
|
|
@ -3,6 +3,7 @@
|
|||||||
#include "VarElimSolver.h"
|
#include "VarElimSolver.h"
|
||||||
#include "ElimGraph.h"
|
#include "ElimGraph.h"
|
||||||
#include "Factor.h"
|
#include "Factor.h"
|
||||||
|
#include "Util.h"
|
||||||
|
|
||||||
|
|
||||||
VarElimSolver::VarElimSolver (const BayesNet& bn) : Solver (&bn)
|
VarElimSolver::VarElimSolver (const BayesNet& bn) : Solver (&bn)
|
||||||
@ -30,23 +31,23 @@ VarElimSolver::~VarElimSolver (void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
ParamSet
|
Params
|
||||||
VarElimSolver::getPosterioriOf (VarId vid)
|
VarElimSolver::getPosterioriOf (VarId vid)
|
||||||
{
|
{
|
||||||
|
assert (factorGraph_->getFgVarNode (vid));
|
||||||
FgVarNode* vn = factorGraph_->getFgVarNode (vid);
|
FgVarNode* vn = factorGraph_->getFgVarNode (vid);
|
||||||
assert (vn);
|
|
||||||
if (vn->hasEvidence()) {
|
if (vn->hasEvidence()) {
|
||||||
ParamSet params (vn->nrStates(), 0.0);
|
Params params (vn->nrStates(), 0.0);
|
||||||
params[vn->getEvidence()] = 1.0;
|
params[vn->getEvidence()] = 1.0;
|
||||||
return params;
|
return params;
|
||||||
}
|
}
|
||||||
return getJointDistributionOf (VarIdSet() = {vid});
|
return getJointDistributionOf (VarIds() = {vid});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ParamSet
|
Params
|
||||||
VarElimSolver::getJointDistributionOf (const VarIdSet& vids)
|
VarElimSolver::getJointDistributionOf (const VarIds& vids)
|
||||||
{
|
{
|
||||||
factorList_.clear();
|
factorList_.clear();
|
||||||
varFactors_.clear();
|
varFactors_.clear();
|
||||||
@ -55,10 +56,11 @@ VarElimSolver::getJointDistributionOf (const VarIdSet& vids)
|
|||||||
introduceEvidence();
|
introduceEvidence();
|
||||||
chooseEliminationOrder (vids);
|
chooseEliminationOrder (vids);
|
||||||
processFactorList (vids);
|
processFactorList (vids);
|
||||||
ParamSet params = factorList_.back()->getParameters();
|
Params params = factorList_.back()->getParameters();
|
||||||
factorList_.back()->freeDistribution();
|
if (Globals::logDomain) {
|
||||||
|
Util::fromLog (params);
|
||||||
|
}
|
||||||
delete factorList_.back();
|
delete factorList_.back();
|
||||||
Util::normalize (params);
|
|
||||||
return params;
|
return params;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,7 +101,7 @@ VarElimSolver::introduceEvidence (void)
|
|||||||
if (factor->nrVariables() == 1) {
|
if (factor->nrVariables() == 1) {
|
||||||
factorList_[idxs[j]] = 0;
|
factorList_[idxs[j]] = 0;
|
||||||
} else {
|
} else {
|
||||||
factorList_[idxs[j]]->removeInconsistentEntries (
|
factorList_[idxs[j]]->absorveEvidence (
|
||||||
varNodes[i]->varId(), varNodes[i]->getEvidence());
|
varNodes[i]->varId(), varNodes[i]->getEvidence());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -110,10 +112,10 @@ VarElimSolver::introduceEvidence (void)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
VarElimSolver::chooseEliminationOrder (const VarIdSet& vids)
|
VarElimSolver::chooseEliminationOrder (const VarIds& vids)
|
||||||
{
|
{
|
||||||
if (bayesNet_) {
|
if (bayesNet_) {
|
||||||
ElimGraph graph = ElimGraph (*bayesNet_);
|
ElimGraph graph (*bayesNet_);
|
||||||
elimOrder_ = graph.getEliminatingOrder (vids);
|
elimOrder_ = graph.getEliminatingOrder (vids);
|
||||||
} else {
|
} else {
|
||||||
const FgVarSet& varNodes = factorGraph_->getVarNodes();
|
const FgVarSet& varNodes = factorGraph_->getVarNodes();
|
||||||
@ -130,33 +132,31 @@ VarElimSolver::chooseEliminationOrder (const VarIdSet& vids)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
VarElimSolver::processFactorList (const VarIdSet& vids)
|
VarElimSolver::processFactorList (const VarIds& vids)
|
||||||
{
|
{
|
||||||
for (unsigned i = 0; i < elimOrder_.size(); i++) {
|
for (unsigned i = 0; i < elimOrder_.size(); i++) {
|
||||||
// cout << "-----------------------------------------" << endl;
|
|
||||||
// cout << "Eliminating " << elimOrder_[i];
|
|
||||||
// cout << " in the following factors:" << endl;
|
|
||||||
// printActiveFactors();
|
|
||||||
eliminate (elimOrder_[i]);
|
eliminate (elimOrder_[i]);
|
||||||
}
|
}
|
||||||
Factor* thisIsTheEnd = new Factor();
|
|
||||||
|
|
||||||
|
Factor* finalFactor = new Factor();
|
||||||
for (unsigned i = 0; i < factorList_.size(); i++) {
|
for (unsigned i = 0; i < factorList_.size(); i++) {
|
||||||
if (factorList_[i]) {
|
if (factorList_[i]) {
|
||||||
thisIsTheEnd->multiplyByFactor (*factorList_[i]);
|
finalFactor->multiply (*factorList_[i]);
|
||||||
factorList_[i]->freeDistribution();
|
|
||||||
delete factorList_[i];
|
delete factorList_[i];
|
||||||
factorList_[i] = 0;
|
factorList_[i] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
VarIdSet vidsWithoutEvidence;
|
|
||||||
|
VarIds unobservedVids;
|
||||||
for (unsigned i = 0; i < vids.size(); i++) {
|
for (unsigned i = 0; i < vids.size(); i++) {
|
||||||
if (factorGraph_->getFgVarNode (vids[i])->hasEvidence() == false) {
|
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
|
void
|
||||||
VarElimSolver::eliminate (VarId elimVar)
|
VarElimSolver::eliminate (VarId elimVar)
|
||||||
{
|
{
|
||||||
FgVarNode* vn = factorGraph_->getFgVarNode (elimVar);
|
|
||||||
Factor* result = 0;
|
Factor* result = 0;
|
||||||
|
FgVarNode* vn = factorGraph_->getFgVarNode (elimVar);
|
||||||
vector<unsigned>& idxs = varFactors_.find (elimVar)->second;
|
vector<unsigned>& idxs = varFactors_.find (elimVar)->second;
|
||||||
//cout << "eliminating " << setw (5) << elimVar << ":" ;
|
|
||||||
for (unsigned i = 0; i < idxs.size(); i++) {
|
for (unsigned i = 0; i < idxs.size(); i++) {
|
||||||
unsigned idx = idxs[i];
|
unsigned idx = idxs[i];
|
||||||
if (factorList_[idx]) {
|
if (factorList_[idx]) {
|
||||||
if (result == 0) {
|
if (result == 0) {
|
||||||
result = new Factor(*factorList_[idx]);
|
result = new Factor(*factorList_[idx]);
|
||||||
//cout << " " << factorList_[idx]->label();
|
|
||||||
} else {
|
} else {
|
||||||
result->multiplyByFactor (*factorList_[idx]);
|
result->multiply (*factorList_[idx]);
|
||||||
//cout << " x " << factorList_[idx]->label();
|
|
||||||
}
|
}
|
||||||
factorList_[idx]->freeDistribution();
|
|
||||||
delete factorList_[idx];
|
delete factorList_[idx];
|
||||||
factorList_[idx] = 0;
|
factorList_[idx] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (result != 0 && result->nrVariables() != 1) {
|
if (result != 0 && result->nrVariables() != 1) {
|
||||||
result->removeVariable (vn->varId());
|
result->sumOut (vn->varId());
|
||||||
factorList_.push_back (result);
|
factorList_.push_back (result);
|
||||||
// cout << endl <<" factor size=" << result->size() << endl;
|
const VarIds& resultVarIds = result->getVarIds();
|
||||||
const VarIdSet& resultVarIds = result->getVarIds();
|
|
||||||
for (unsigned i = 0; i < resultVarIds.size(); i++) {
|
for (unsigned i = 0; i < resultVarIds.size(); i++) {
|
||||||
vector<unsigned>& idxs =
|
vector<unsigned>& idxs =
|
||||||
varFactors_.find (resultVarIds[i])->second;
|
varFactors_.find (resultVarIds[i])->second;
|
||||||
@ -203,7 +198,7 @@ VarElimSolver::printActiveFactors (void)
|
|||||||
{
|
{
|
||||||
for (unsigned i = 0; i < factorList_.size(); i++) {
|
for (unsigned i = 0; i < factorList_.size(); i++) {
|
||||||
if (factorList_[i] != 0) {
|
if (factorList_[i] != 0) {
|
||||||
factorList_[i]->printFactor();
|
factorList_[i]->print();
|
||||||
cout << endl;
|
cout << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
#include "Solver.h"
|
#include "Solver.h"
|
||||||
#include "FactorGraph.h"
|
#include "FactorGraph.h"
|
||||||
#include "BayesNet.h"
|
#include "BayesNet.h"
|
||||||
#include "Shared.h"
|
#include "Horus.h"
|
||||||
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
@ -18,22 +18,22 @@ class VarElimSolver : public Solver
|
|||||||
VarElimSolver (const BayesNet&);
|
VarElimSolver (const BayesNet&);
|
||||||
VarElimSolver (const FactorGraph&);
|
VarElimSolver (const FactorGraph&);
|
||||||
~VarElimSolver (void);
|
~VarElimSolver (void);
|
||||||
void runSolver (void) { }
|
void runSolver (void) { }
|
||||||
ParamSet getPosterioriOf (VarId);
|
Params getPosterioriOf (VarId);
|
||||||
ParamSet getJointDistributionOf (const VarIdSet&);
|
Params getJointDistributionOf (const VarIds&);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void createFactorList (void);
|
void createFactorList (void);
|
||||||
void introduceEvidence (void);
|
void introduceEvidence (void);
|
||||||
void chooseEliminationOrder (const VarIdSet&);
|
void chooseEliminationOrder (const VarIds&);
|
||||||
void processFactorList (const VarIdSet&);
|
void processFactorList (const VarIds&);
|
||||||
void eliminate (VarId);
|
void eliminate (VarId);
|
||||||
void printActiveFactors (void);
|
void printActiveFactors (void);
|
||||||
|
|
||||||
const BayesNet* bayesNet_;
|
const BayesNet* bayesNet_;
|
||||||
const FactorGraph* factorGraph_;
|
const FactorGraph* factorGraph_;
|
||||||
vector<Factor*> factorList_;
|
vector<Factor*> factorList_;
|
||||||
VarIdSet elimOrder_;
|
VarIds elimOrder_;
|
||||||
unordered_map<VarId, vector<unsigned>> varFactors_;
|
unordered_map<VarId, vector<unsigned>> varFactors_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#ifndef HORUS_VARNODE_H
|
#ifndef HORUS_VARNODE_H
|
||||||
#define HORUS_VARNODE_H
|
#define HORUS_VARNODE_H
|
||||||
|
|
||||||
#include "Shared.h"
|
#include "Horus.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
@ -30,12 +30,14 @@ class VarNode
|
|||||||
|
|
||||||
bool operator== (const VarNode& var) const
|
bool operator== (const VarNode& var) const
|
||||||
{
|
{
|
||||||
|
cout << "equal operator called" << endl;
|
||||||
assert (!(varId_ == var.varId() && nrStates_ != var.nrStates()));
|
assert (!(varId_ == var.varId() && nrStates_ != var.nrStates()));
|
||||||
return varId_ == var.varId();
|
return varId_ == var.varId();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator!= (const VarNode& var) const
|
bool operator!= (const VarNode& var) const
|
||||||
{
|
{
|
||||||
|
cout << "diff operator called" << endl;
|
||||||
assert (!(varId_ == var.varId() && nrStates_ != var.nrStates()));
|
assert (!(varId_ == var.varId() && nrStates_ != var.nrStates()));
|
||||||
return varId_ != var.varId();
|
return varId_ != var.varId();
|
||||||
}
|
}
|
||||||
|
@ -1,34 +0,0 @@
|
|||||||
|
|
||||||
:- use_module(library(clpbn)).
|
|
||||||
|
|
||||||
:- set_clpbn_flag(solver, bp).
|
|
||||||
|
|
||||||
%
|
|
||||||
% R
|
|
||||||
% / | \
|
|
||||||
% / | \
|
|
||||||
% A B C
|
|
||||||
%
|
|
||||||
|
|
||||||
|
|
||||||
r(R) :-
|
|
||||||
{ R = r with p([t, f], [0.35, 0.65]) }.
|
|
||||||
|
|
||||||
a(A) :-
|
|
||||||
r(R),
|
|
||||||
child_dist(R,Dist),
|
|
||||||
{ A = a with Dist }.
|
|
||||||
|
|
||||||
b(B) :-
|
|
||||||
r(R),
|
|
||||||
child_dist(R,Dist),
|
|
||||||
{ B = b with Dist }.
|
|
||||||
|
|
||||||
c(C) :-
|
|
||||||
r(R),
|
|
||||||
child_dist(R,Dist),
|
|
||||||
{ C = c with Dist }.
|
|
||||||
|
|
||||||
|
|
||||||
child_dist(R, p([t, f], [0.3, 0.4, 0.25, 0.05], [R])).
|
|
||||||
|
|
@ -1,76 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="US-ASCII"?>
|
|
||||||
|
|
||||||
<BIF VERSION="0.3">
|
|
||||||
<NETWORK>
|
|
||||||
<NAME>Bayes-Ball: The Rational Pastime Network, Figure 4, a)</NAME>
|
|
||||||
|
|
||||||
<VARIABLE TYPE="nature">
|
|
||||||
<NAME>1</NAME>
|
|
||||||
<OUTCOME></OUTCOME>
|
|
||||||
</VARIABLE>
|
|
||||||
|
|
||||||
<VARIABLE TYPE="nature">
|
|
||||||
<NAME>2</NAME>
|
|
||||||
<OUTCOME></OUTCOME>
|
|
||||||
</VARIABLE>
|
|
||||||
|
|
||||||
<VARIABLE TYPE="nature">
|
|
||||||
<NAME>3</NAME>
|
|
||||||
<OUTCOME></OUTCOME>
|
|
||||||
</VARIABLE>
|
|
||||||
|
|
||||||
<VARIABLE TYPE="nature">
|
|
||||||
<NAME>4</NAME>
|
|
||||||
<OUTCOME></OUTCOME>
|
|
||||||
</VARIABLE>
|
|
||||||
|
|
||||||
<VARIABLE TYPE="nature">
|
|
||||||
<NAME>5</NAME>
|
|
||||||
<OUTCOME></OUTCOME>
|
|
||||||
</VARIABLE>
|
|
||||||
|
|
||||||
<VARIABLE TYPE="nature">
|
|
||||||
<NAME>6</NAME>
|
|
||||||
<OUTCOME></OUTCOME>
|
|
||||||
</VARIABLE>
|
|
||||||
|
|
||||||
<DEFINITION>
|
|
||||||
<FOR>1</FOR>
|
|
||||||
<TABLE>1</TABLE>
|
|
||||||
</DEFINITION>
|
|
||||||
|
|
||||||
<DEFINITION>
|
|
||||||
<FOR>2</FOR>
|
|
||||||
<GIVEN>1</GIVEN>
|
|
||||||
<GIVEN>3</GIVEN>
|
|
||||||
<TABLE>1</TABLE>
|
|
||||||
</DEFINITION>
|
|
||||||
|
|
||||||
<DEFINITION>
|
|
||||||
<FOR>3</FOR>
|
|
||||||
<TABLE>1</TABLE>
|
|
||||||
</DEFINITION>
|
|
||||||
|
|
||||||
<DEFINITION>
|
|
||||||
<FOR>4</FOR>
|
|
||||||
<GIVEN>1</GIVEN>
|
|
||||||
<GIVEN>5</GIVEN>
|
|
||||||
<TABLE>1</TABLE>
|
|
||||||
</DEFINITION>
|
|
||||||
|
|
||||||
<DEFINITION>
|
|
||||||
<FOR>5</FOR>
|
|
||||||
<GIVEN>2</GIVEN>
|
|
||||||
<GIVEN>6</GIVEN>
|
|
||||||
<TABLE>1</TABLE>
|
|
||||||
</DEFINITION>
|
|
||||||
|
|
||||||
<DEFINITION>
|
|
||||||
<FOR>6</FOR>
|
|
||||||
<GIVEN>3</GIVEN>
|
|
||||||
<TABLE>1</TABLE>
|
|
||||||
</DEFINITION>
|
|
||||||
|
|
||||||
</NETWORK>
|
|
||||||
</BIF>
|
|
||||||
|
|
@ -1,74 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="US-ASCII"?>
|
|
||||||
|
|
||||||
<BIF VERSION="0.3">
|
|
||||||
<NETWORK>
|
|
||||||
<NAME>Bayes-Ball: The Rational Pastime Network, Figure 4, c)</NAME>
|
|
||||||
|
|
||||||
<VARIABLE TYPE="nature">
|
|
||||||
<NAME>1</NAME>
|
|
||||||
<OUTCOME></OUTCOME>
|
|
||||||
</VARIABLE>
|
|
||||||
|
|
||||||
<VARIABLE TYPE="nature">
|
|
||||||
<NAME>2</NAME>
|
|
||||||
<OUTCOME></OUTCOME>
|
|
||||||
</VARIABLE>
|
|
||||||
|
|
||||||
<VARIABLE TYPE="nature">
|
|
||||||
<NAME>3</NAME>
|
|
||||||
<OUTCOME></OUTCOME>
|
|
||||||
</VARIABLE>
|
|
||||||
|
|
||||||
<VARIABLE TYPE="nature">
|
|
||||||
<NAME>4</NAME>
|
|
||||||
<OUTCOME></OUTCOME>
|
|
||||||
</VARIABLE>
|
|
||||||
|
|
||||||
<VARIABLE TYPE="nature">
|
|
||||||
<NAME>5</NAME>
|
|
||||||
<OUTCOME></OUTCOME>
|
|
||||||
</VARIABLE>
|
|
||||||
|
|
||||||
<VARIABLE TYPE="nature">
|
|
||||||
<NAME>6</NAME>
|
|
||||||
<OUTCOME></OUTCOME>
|
|
||||||
</VARIABLE>
|
|
||||||
|
|
||||||
<DEFINITION>
|
|
||||||
<FOR>1</FOR>
|
|
||||||
<TABLE>1</TABLE>
|
|
||||||
</DEFINITION>
|
|
||||||
|
|
||||||
<DEFINITION>
|
|
||||||
<FOR>2</FOR>
|
|
||||||
<GIVEN>1</GIVEN>
|
|
||||||
<GIVEN>3</GIVEN>
|
|
||||||
<TABLE>1</TABLE>
|
|
||||||
</DEFINITION>
|
|
||||||
|
|
||||||
<DEFINITION>
|
|
||||||
<FOR>3</FOR>
|
|
||||||
<TABLE>1</TABLE>
|
|
||||||
</DEFINITION>
|
|
||||||
|
|
||||||
<DEFINITION>
|
|
||||||
<FOR>4</FOR>
|
|
||||||
<GIVEN>5</GIVEN>
|
|
||||||
<TABLE>1</TABLE>
|
|
||||||
</DEFINITION>
|
|
||||||
|
|
||||||
<DEFINITION>
|
|
||||||
<FOR>5</FOR>
|
|
||||||
<GIVEN>2</GIVEN>
|
|
||||||
<GIVEN>6</GIVEN>
|
|
||||||
<TABLE>1</TABLE>
|
|
||||||
</DEFINITION>
|
|
||||||
|
|
||||||
<DEFINITION>
|
|
||||||
<FOR>6</FOR>
|
|
||||||
<TABLE>1</TABLE>
|
|
||||||
</DEFINITION>
|
|
||||||
|
|
||||||
</NETWORK>
|
|
||||||
</BIF>
|
|
||||||
|
|
@ -1,53 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="US-ASCII"?>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
|
|
||||||
A B
|
|
||||||
\ /
|
|
||||||
\ /
|
|
||||||
C
|
|
||||||
|
|
||||||
-->
|
|
||||||
|
|
||||||
<BIF VERSION="0.3">
|
|
||||||
<NETWORK>
|
|
||||||
<NAME>Neapolitan</NAME>
|
|
||||||
|
|
||||||
<VARIABLE TYPE="nature">
|
|
||||||
<NAME>A</NAME>
|
|
||||||
<OUTCOME>a1</OUTCOME>
|
|
||||||
<OUTCOME>a2</OUTCOME>
|
|
||||||
</VARIABLE>
|
|
||||||
|
|
||||||
<VARIABLE TYPE="nature">
|
|
||||||
<NAME>B</NAME>
|
|
||||||
<OUTCOME>b1</OUTCOME>
|
|
||||||
<OUTCOME>b2</OUTCOME>
|
|
||||||
</VARIABLE>
|
|
||||||
|
|
||||||
<VARIABLE TYPE="nature">
|
|
||||||
<NAME>C</NAME>
|
|
||||||
<OUTCOME>c1</OUTCOME>
|
|
||||||
<OUTCOME>c2</OUTCOME>
|
|
||||||
</VARIABLE>
|
|
||||||
|
|
||||||
<DEFINITION>
|
|
||||||
<FOR>A</FOR>
|
|
||||||
<TABLE> .695 .305 </TABLE>
|
|
||||||
</DEFINITION>
|
|
||||||
|
|
||||||
<DEFINITION>
|
|
||||||
<FOR>B</FOR>
|
|
||||||
<TABLE> .25 .75 </TABLE>
|
|
||||||
</DEFINITION>
|
|
||||||
|
|
||||||
<DEFINITION>
|
|
||||||
<FOR>C</FOR>
|
|
||||||
<GIVEN>A</GIVEN>
|
|
||||||
<GIVEN>B</GIVEN>
|
|
||||||
<TABLE> .2 .8 .45 .55 .32 .68 .7 .3 </TABLE>
|
|
||||||
</DEFINITION>
|
|
||||||
|
|
||||||
</NETWORK>
|
|
||||||
</BIF>
|
|
||||||
|
|
47
packages/CLPBN/clpbn/bp/examples/burglary-alarm.fg
Normal file
47
packages/CLPBN/clpbn/bp/examples/burglary-alarm.fg
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
5
|
||||||
|
|
||||||
|
1
|
||||||
|
0
|
||||||
|
2
|
||||||
|
2
|
||||||
|
0 0.001
|
||||||
|
1 0.999
|
||||||
|
|
||||||
|
1
|
||||||
|
1
|
||||||
|
2
|
||||||
|
2
|
||||||
|
0 0.002
|
||||||
|
1 0.998
|
||||||
|
|
||||||
|
3
|
||||||
|
1 0 2
|
||||||
|
2 2 2
|
||||||
|
8
|
||||||
|
0 0.95
|
||||||
|
1 0.94
|
||||||
|
2 0.29
|
||||||
|
3 0.001
|
||||||
|
4 0.05
|
||||||
|
5 0.06
|
||||||
|
6 0.71
|
||||||
|
7 0.999
|
||||||
|
|
||||||
|
2
|
||||||
|
2 3
|
||||||
|
2 2
|
||||||
|
4
|
||||||
|
0 0.9
|
||||||
|
1 0.05
|
||||||
|
2 0.1
|
||||||
|
3 0.95
|
||||||
|
|
||||||
|
2
|
||||||
|
2 4
|
||||||
|
2 2
|
||||||
|
4
|
||||||
|
0 0.7
|
||||||
|
1 0.01
|
||||||
|
2 0.3
|
||||||
|
3 0.99
|
||||||
|
|
@ -1,58 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="US-ASCII"?>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
|
|
||||||
A
|
|
||||||
|
|
|
||||||
|
|
|
||||||
-
|
|
||||||
B
|
|
||||||
|
|
|
||||||
|
|
|
||||||
-
|
|
||||||
C
|
|
||||||
|
|
||||||
-->
|
|
||||||
|
|
||||||
<BIF VERSION="0.3">
|
|
||||||
<NETWORK>
|
|
||||||
<NAME>Simple Chain</NAME>
|
|
||||||
|
|
||||||
<VARIABLE TYPE="nature">
|
|
||||||
<NAME>A</NAME>
|
|
||||||
<OUTCOME>a1</OUTCOME>
|
|
||||||
<OUTCOME>a2</OUTCOME>
|
|
||||||
</VARIABLE>
|
|
||||||
|
|
||||||
<VARIABLE TYPE="nature">
|
|
||||||
<NAME>B</NAME>
|
|
||||||
<OUTCOME>b1</OUTCOME>
|
|
||||||
<OUTCOME>b2</OUTCOME>
|
|
||||||
</VARIABLE>
|
|
||||||
|
|
||||||
<VARIABLE TYPE="nature">
|
|
||||||
<NAME>C</NAME>
|
|
||||||
<OUTCOME>c1</OUTCOME>
|
|
||||||
<OUTCOME>c2</OUTCOME>
|
|
||||||
</VARIABLE>
|
|
||||||
|
|
||||||
<DEFINITION>
|
|
||||||
<FOR>A</FOR>
|
|
||||||
<TABLE>0.3 0.7</TABLE>
|
|
||||||
</DEFINITION>
|
|
||||||
|
|
||||||
<DEFINITION>
|
|
||||||
<FOR>B</FOR>
|
|
||||||
<GIVEN>A</GIVEN>
|
|
||||||
<TABLE>0.4 0.6 0.2 0.8</TABLE>
|
|
||||||
</DEFINITION>
|
|
||||||
|
|
||||||
<DEFINITION>
|
|
||||||
<FOR>C</FOR>
|
|
||||||
<GIVEN>B</GIVEN>
|
|
||||||
<TABLE>0.9 0.1 0.25 0.75</TABLE>
|
|
||||||
</DEFINITION>
|
|
||||||
|
|
||||||
</NETWORK>
|
|
||||||
</BIF>
|
|
||||||
|
|
78022
packages/CLPBN/clpbn/bp/examples/city1000.fg
Normal file
78022
packages/CLPBN/clpbn/bp/examples/city1000.fg
Normal file
File diff suppressed because it is too large
Load Diff
780022
packages/CLPBN/clpbn/bp/examples/city10000.fg
Normal file
780022
packages/CLPBN/clpbn/bp/examples/city10000.fg
Normal file
File diff suppressed because it is too large
Load Diff
390022
packages/CLPBN/clpbn/bp/examples/city5000.fg
Normal file
390022
packages/CLPBN/clpbn/bp/examples/city5000.fg
Normal file
File diff suppressed because it is too large
Load Diff
18
packages/CLPBN/clpbn/bp/examples/competing_workshops.yap
Normal file
18
packages/CLPBN/clpbn/bp/examples/competing_workshops.yap
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
|
||||||
|
:- use_module(library(pfl)).
|
||||||
|
|
||||||
|
%:- set_clpbn_flag(solver,ve).
|
||||||
|
%:- set_clpbn_flag(solver,bp), clpbn_bp:set_horus_flag(inf_alg,ve).
|
||||||
|
:- set_clpbn_flag(solver,fove).
|
||||||
|
|
||||||
|
c(x1,y1).
|
||||||
|
%c(x1,y1).
|
||||||
|
%c(x2,y2).
|
||||||
|
|
||||||
|
bayes hot(Y)::[t,f] ; [0.2, 0.4] ; [c(_,Y)].
|
||||||
|
|
||||||
|
bayes attends(X)::[t,f] , hot(Y) ; [0.1, 0.2, 0.3, 0.4] ; [c(X,Y)].
|
||||||
|
|
||||||
|
bayes series::[t,f] , attends(X) ; [0.5, 0.6, 0.7, 0.8] ; [c(X,_)].
|
||||||
|
|
||||||
|
|
@ -1,54 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="US-ASCII"?>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
|
|
||||||
A B
|
|
||||||
\ /
|
|
||||||
\ /
|
|
||||||
-
|
|
||||||
C
|
|
||||||
|
|
||||||
-->
|
|
||||||
|
|
||||||
<BIF VERSION="0.3">
|
|
||||||
<NETWORK>
|
|
||||||
<NAME>Simple Convergence</NAME>
|
|
||||||
|
|
||||||
<VARIABLE TYPE="nature">
|
|
||||||
<NAME>A</NAME>
|
|
||||||
<OUTCOME>a1</OUTCOME>
|
|
||||||
<OUTCOME>a2</OUTCOME>
|
|
||||||
</VARIABLE>
|
|
||||||
|
|
||||||
<VARIABLE TYPE="nature">
|
|
||||||
<NAME>B</NAME>
|
|
||||||
<OUTCOME>b1</OUTCOME>
|
|
||||||
<OUTCOME>b2</OUTCOME>
|
|
||||||
</VARIABLE>
|
|
||||||
|
|
||||||
<VARIABLE TYPE="nature">
|
|
||||||
<NAME>C</NAME>
|
|
||||||
<OUTCOME>c1</OUTCOME>
|
|
||||||
<OUTCOME>c2</OUTCOME>
|
|
||||||
</VARIABLE>
|
|
||||||
|
|
||||||
<DEFINITION>
|
|
||||||
<FOR>A</FOR>
|
|
||||||
<TABLE>.695 .305</TABLE>
|
|
||||||
</DEFINITION>
|
|
||||||
|
|
||||||
<DEFINITION>
|
|
||||||
<FOR>B</FOR>
|
|
||||||
<TABLE>0.25 0.75</TABLE>
|
|
||||||
</DEFINITION>
|
|
||||||
|
|
||||||
<DEFINITION>
|
|
||||||
<FOR>C</FOR>
|
|
||||||
<GIVEN>A</GIVEN>
|
|
||||||
<GIVEN>B</GIVEN>
|
|
||||||
<TABLE>0.2 0.8 0.45 0.55 0.32 0.68 0.7 0.3</TABLE>
|
|
||||||
</DEFINITION>
|
|
||||||
|
|
||||||
</NETWORK>
|
|
||||||
</BIF>
|
|
||||||
|
|
@ -1,51 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="US-ASCII"?>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
|
|
||||||
A
|
|
||||||
/ \
|
|
||||||
/ \
|
|
||||||
- -
|
|
||||||
B C
|
|
||||||
|
|
||||||
-->
|
|
||||||
|
|
||||||
<BIF VERSION="0.3">
|
|
||||||
<NETWORK>
|
|
||||||
<NAME>Simple Divergence</NAME>
|
|
||||||
|
|
||||||
<VARIABLE TYPE="nature">
|
|
||||||
<NAME>A</NAME>
|
|
||||||
<OUTCOME></OUTCOME>
|
|
||||||
</VARIABLE>
|
|
||||||
|
|
||||||
<VARIABLE TYPE="nature">
|
|
||||||
<NAME>B</NAME>
|
|
||||||
<OUTCOME></OUTCOME>
|
|
||||||
</VARIABLE>
|
|
||||||
|
|
||||||
<VARIABLE TYPE="nature">
|
|
||||||
<NAME>C</NAME>
|
|
||||||
<OUTCOME></OUTCOME>
|
|
||||||
</VARIABLE>
|
|
||||||
|
|
||||||
<DEFINITION>
|
|
||||||
<FOR>A</FOR>
|
|
||||||
<TABLE>1</TABLE>
|
|
||||||
</DEFINITION>
|
|
||||||
|
|
||||||
<DEFINITION>
|
|
||||||
<FOR>B</FOR>
|
|
||||||
<GIVEN>A</GIVEN>
|
|
||||||
<TABLE>1</TABLE>
|
|
||||||
</DEFINITION>
|
|
||||||
|
|
||||||
<DEFINITION>
|
|
||||||
<FOR>C</FOR>
|
|
||||||
<GIVEN>A</GIVEN>
|
|
||||||
<TABLE>1</TABLE>
|
|
||||||
</DEFINITION>
|
|
||||||
|
|
||||||
</NETWORK>
|
|
||||||
</BIF>
|
|
||||||
|
|
50
packages/CLPBN/clpbn/bp/examples/fail1.yap
Normal file
50
packages/CLPBN/clpbn/bp/examples/fail1.yap
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
|
||||||
|
:- use_module(library(pfl)).
|
||||||
|
|
||||||
|
:- set_clpbn_flag(solver,fove).
|
||||||
|
|
||||||
|
|
||||||
|
c(x1,y1,z1).
|
||||||
|
c(x1,y1,z2).
|
||||||
|
c(x1,y1,z3).
|
||||||
|
c(x1,y1,z4).
|
||||||
|
c(x1,y1,z5).
|
||||||
|
c(x1,y1,z6).
|
||||||
|
c(x1,y1,z7).
|
||||||
|
|
||||||
|
c(x1,y2,z1).
|
||||||
|
c(x1,y2,z2).
|
||||||
|
c(x1,y2,z3).
|
||||||
|
c(x1,y2,z4).
|
||||||
|
c(x1,y2,z5).
|
||||||
|
c(x1,y2,z6).
|
||||||
|
c(x1,y2,z7).
|
||||||
|
|
||||||
|
c(x2,y1,z1).
|
||||||
|
c(x2,y1,z2).
|
||||||
|
c(x2,y1,z3).
|
||||||
|
c(x2,y1,z4).
|
||||||
|
c(x2,y1,z5).
|
||||||
|
c(x2,y1,z6).
|
||||||
|
c(x2,y1,z7).
|
||||||
|
|
||||||
|
c(x2,y2,z1).
|
||||||
|
c(x2,y2,z2).
|
||||||
|
c(x2,y2,z3).
|
||||||
|
c(x2,y2,z4).
|
||||||
|
c(x2,y2,z5).
|
||||||
|
c(x2,y2,z6).
|
||||||
|
c(x2,y2,z7).
|
||||||
|
|
||||||
|
|
||||||
|
bayes p(X,Y,Z)::[t,f] , q(Y), s(Z) ; cpt ; [c(X,Y,Z)].
|
||||||
|
|
||||||
|
bayes q(Y)::[t,f] ; [0.50, 0.40] ; [c(_,Y,_)].
|
||||||
|
|
||||||
|
bayes s(Z)::[t,f] ; [0.33, 0.46] ; [c(_,_,Z)].
|
||||||
|
|
||||||
|
cpt([0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8]).
|
||||||
|
|
||||||
|
|
||||||
|
?- p(x1,y1,z1,X), s(z1,t), s(z3,f).
|
||||||
|
|
15
packages/CLPBN/clpbn/bp/examples/fail2.yap
Normal file
15
packages/CLPBN/clpbn/bp/examples/fail2.yap
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
|
||||||
|
:- use_module(library(pfl)).
|
||||||
|
|
||||||
|
:- set_clpbn_flag(solver,fove).
|
||||||
|
|
||||||
|
|
||||||
|
t(ann).
|
||||||
|
t(dave).
|
||||||
|
|
||||||
|
bayes p(X)::[t,f] ; [0.1, 0.3] ; [t(X)].
|
||||||
|
|
||||||
|
|
||||||
|
?- p(ann,X), p(ann,f).
|
||||||
|
|
||||||
|
|
18
packages/CLPBN/clpbn/bp/examples/fail3.yap
Normal file
18
packages/CLPBN/clpbn/bp/examples/fail3.yap
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
|
||||||
|
:- use_module(library(pfl)).
|
||||||
|
|
||||||
|
:- set_clpbn_flag(solver,fove).
|
||||||
|
|
||||||
|
|
||||||
|
t(ann).
|
||||||
|
t(dave).
|
||||||
|
|
||||||
|
bayes p(X)::[t,f] ; [0.1, 0.3] ; [t(X)].
|
||||||
|
|
||||||
|
|
||||||
|
p(ann,t).
|
||||||
|
|
||||||
|
|
||||||
|
?- p(dave,X).
|
||||||
|
|
||||||
|
|
@ -1,106 +0,0 @@
|
|||||||
<?XML VERSION="1.0"?>
|
|
||||||
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Bayesian network in BIF (BayesNet Interchange Format)
|
|
||||||
Produced by JavaBayes (http://www.cs.cmu.edu/~javabayes/
|
|
||||||
Output created Fri Nov 14 13:14:15 GMT+00:00 1997
|
|
||||||
-->
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- DTD for the BIF format -->
|
|
||||||
<!DOCTYPE BIF [
|
|
||||||
<!ELEMENT PROPERTY (#PCDATA)>
|
|
||||||
<!ELEMENT TYPE (#PCDATA)>
|
|
||||||
<!ELEMENT VALUE (#PCDATA)>
|
|
||||||
<!ELEMENT NAME (#PCDATA)>
|
|
||||||
<!ELEMENT NETWORK
|
|
||||||
( NAME, ( PROPERTY | VARIABLE | PROBABILITY )* )>
|
|
||||||
<!ELEMENT VARIABLE ( NAME, TYPE, ( VALUE | PROPERTY )* ) >
|
|
||||||
<!ELEMENT PROBABILITY
|
|
||||||
( FOR | GIVEN | TABLE | ENTRY | DEFAULT | PROPERTY )* >
|
|
||||||
<!ELEMENT TABLE (#PCDATA)>
|
|
||||||
<!ELEMENT DEFAULT (TABLE)>
|
|
||||||
<!ELEMENT ENTRY ( VALUE* , TABLE )>
|
|
||||||
]>
|
|
||||||
|
|
||||||
|
|
||||||
<BIF>
|
|
||||||
<NETWORK>
|
|
||||||
<NAME>John-Mary-Call</NAME>
|
|
||||||
|
|
||||||
<!-- Variables -->
|
|
||||||
<VARIABLE>
|
|
||||||
<NAME>Burglary</NAME>
|
|
||||||
<TYPE>discrete</TYPE>
|
|
||||||
<VALUE>False</VALUE>
|
|
||||||
<VALUE>True</VALUE>
|
|
||||||
<PROPERTY>position = (145, 114)</PROPERTY>
|
|
||||||
</VARIABLE>
|
|
||||||
|
|
||||||
<VARIABLE>
|
|
||||||
<NAME>Earthquake</NAME>
|
|
||||||
<TYPE>discrete</TYPE>
|
|
||||||
<VALUE>False</VALUE>
|
|
||||||
<VALUE>True</VALUE>
|
|
||||||
<PROPERTY>position = (351, 110)</PROPERTY>
|
|
||||||
</VARIABLE>
|
|
||||||
|
|
||||||
<VARIABLE>
|
|
||||||
<NAME>Alarm</NAME>
|
|
||||||
<TYPE>discrete</TYPE>
|
|
||||||
<VALUE>False</VALUE>
|
|
||||||
<VALUE>True</VALUE>
|
|
||||||
<PROPERTY>position = (253, 224)</PROPERTY>
|
|
||||||
</VARIABLE>
|
|
||||||
|
|
||||||
<VARIABLE>
|
|
||||||
<NAME>JohnCalls</NAME>
|
|
||||||
<TYPE>discrete</TYPE>
|
|
||||||
<VALUE>False</VALUE>
|
|
||||||
<VALUE>True</VALUE>
|
|
||||||
<PROPERTY>position = (156, 343)</PROPERTY>
|
|
||||||
</VARIABLE>
|
|
||||||
|
|
||||||
<VARIABLE>
|
|
||||||
<NAME>MaryCalls</NAME>
|
|
||||||
<TYPE>discrete</TYPE>
|
|
||||||
<VALUE>False</VALUE>
|
|
||||||
<VALUE>True</VALUE>
|
|
||||||
<PROPERTY>position = (344, 341)</PROPERTY>
|
|
||||||
</VARIABLE>
|
|
||||||
|
|
||||||
|
|
||||||
<!-- Probability distributions -->
|
|
||||||
<PROBABILITY>
|
|
||||||
<FOR>Burglary</FOR>
|
|
||||||
<TABLE>0.999 0.0010 </TABLE>
|
|
||||||
</PROBABILITY>
|
|
||||||
|
|
||||||
<PROBABILITY>
|
|
||||||
<FOR>Earthquake</FOR>
|
|
||||||
<TABLE>0.998 0.0020 </TABLE>
|
|
||||||
</PROBABILITY>
|
|
||||||
|
|
||||||
<PROBABILITY>
|
|
||||||
<FOR>Alarm</FOR>
|
|
||||||
<GIVEN>Burglary</GIVEN>
|
|
||||||
<GIVEN>Earthquake</GIVEN>
|
|
||||||
<TABLE>0.999 0.71 0.06 0.05 0.0010 0.29 0.94 0.95 </TABLE>
|
|
||||||
</PROBABILITY>
|
|
||||||
|
|
||||||
<PROBABILITY>
|
|
||||||
<FOR>JohnCalls</FOR>
|
|
||||||
<GIVEN>Alarm</GIVEN>
|
|
||||||
<TABLE>0.95 0.1 0.05 0.9 </TABLE>
|
|
||||||
</PROBABILITY>
|
|
||||||
|
|
||||||
<PROBABILITY>
|
|
||||||
<FOR>MaryCalls</FOR>
|
|
||||||
<GIVEN>Alarm</GIVEN>
|
|
||||||
<TABLE>0.99 0.3 0.01 0.7 </TABLE>
|
|
||||||
</PROBABILITY>
|
|
||||||
|
|
||||||
|
|
||||||
</BIF>
|
|
@ -1,67 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="US-ASCII"?>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
|
|
||||||
P1 P2 P3
|
|
||||||
\ | /
|
|
||||||
\ | /
|
|
||||||
-
|
|
||||||
C
|
|
||||||
|
|
||||||
-->
|
|
||||||
|
|
||||||
<BIF VERSION="0.3">
|
|
||||||
<NETWORK>
|
|
||||||
|
|
||||||
<NAME>Simple Convergence</NAME>
|
|
||||||
<VARIABLE TYPE="nature">
|
|
||||||
<NAME>P1</NAME>
|
|
||||||
<OUTCOME>p1</OUTCOME>
|
|
||||||
<OUTCOME>p2</OUTCOME>
|
|
||||||
</VARIABLE>
|
|
||||||
|
|
||||||
<VARIABLE TYPE="nature">
|
|
||||||
<NAME>P2</NAME>
|
|
||||||
<OUTCOME>p1</OUTCOME>
|
|
||||||
<OUTCOME>p2</OUTCOME>
|
|
||||||
<OUTCOME>p3</OUTCOME>
|
|
||||||
</VARIABLE>
|
|
||||||
|
|
||||||
<VARIABLE TYPE="nature">
|
|
||||||
<NAME>P3</NAME>
|
|
||||||
<OUTCOME>p1</OUTCOME>
|
|
||||||
<OUTCOME>p2</OUTCOME>
|
|
||||||
</VARIABLE>
|
|
||||||
|
|
||||||
<VARIABLE TYPE="nature">
|
|
||||||
<NAME>C</NAME>
|
|
||||||
<OUTCOME>c1</OUTCOME>
|
|
||||||
<OUTCOME>c2</OUTCOME>
|
|
||||||
</VARIABLE>
|
|
||||||
|
|
||||||
<DEFINITION>
|
|
||||||
<FOR>P1</FOR>
|
|
||||||
<TABLE>.695 .305</TABLE>
|
|
||||||
</DEFINITION>
|
|
||||||
|
|
||||||
<DEFINITION>
|
|
||||||
<FOR>P2</FOR>
|
|
||||||
<TABLE>0.2 0.3 0.5</TABLE>
|
|
||||||
</DEFINITION>
|
|
||||||
|
|
||||||
<DEFINITION>
|
|
||||||
<FOR>P3</FOR>
|
|
||||||
<TABLE>0.25 0.75</TABLE>
|
|
||||||
</DEFINITION>
|
|
||||||
|
|
||||||
<DEFINITION>
|
|
||||||
<FOR>C</FOR>
|
|
||||||
<GIVEN>P1</GIVEN>
|
|
||||||
<GIVEN>P2</GIVEN>
|
|
||||||
<GIVEN>P3</GIVEN>
|
|
||||||
<TABLE>0.2 0.8 0.45 0.55 0.32 0.68 0.7 0.3 0.3 0.7 0.55 0.45 0.22 0.78 0.25 0.75 0.11 0.89 0.34 0.66 0.1 0.9 0.6 0.4</TABLE>
|
|
||||||
</DEFINITION>
|
|
||||||
|
|
||||||
</NETWORK>
|
|
||||||
</BIF>
|
|
||||||
|
|
@ -1,81 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="US-ASCII"?>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
|
|
||||||
A E
|
|
||||||
/ \ /
|
|
||||||
/ \ /
|
|
||||||
B C
|
|
||||||
\ /
|
|
||||||
\ /
|
|
||||||
D
|
|
||||||
|
|
||||||
-->
|
|
||||||
|
|
||||||
<BIF VERSION="0.3">
|
|
||||||
<NETWORK>
|
|
||||||
<NAME>Loop</NAME>
|
|
||||||
|
|
||||||
<VARIABLE TYPE="nature">
|
|
||||||
<NAME>A</NAME>
|
|
||||||
<OUTCOME>a1</OUTCOME>
|
|
||||||
<OUTCOME>a2</OUTCOME>
|
|
||||||
</VARIABLE>
|
|
||||||
|
|
||||||
<VARIABLE TYPE="nature">
|
|
||||||
<NAME>B</NAME>
|
|
||||||
<OUTCOME>b1</OUTCOME>
|
|
||||||
<OUTCOME>b2</OUTCOME>
|
|
||||||
</VARIABLE>
|
|
||||||
|
|
||||||
<VARIABLE TYPE="nature">
|
|
||||||
<NAME>C</NAME>
|
|
||||||
<OUTCOME>c1</OUTCOME>
|
|
||||||
<OUTCOME>c2</OUTCOME>
|
|
||||||
</VARIABLE>
|
|
||||||
|
|
||||||
<VARIABLE TYPE="nature">
|
|
||||||
<NAME>D</NAME>
|
|
||||||
<OUTCOME>d1</OUTCOME>
|
|
||||||
<OUTCOME>d2</OUTCOME>
|
|
||||||
</VARIABLE>
|
|
||||||
|
|
||||||
<VARIABLE TYPE="nature">
|
|
||||||
<NAME>E</NAME>
|
|
||||||
<OUTCOME>e1</OUTCOME>
|
|
||||||
<OUTCOME>e2</OUTCOME>
|
|
||||||
</VARIABLE>
|
|
||||||
|
|
||||||
<DEFINITION>
|
|
||||||
<FOR>A</FOR>
|
|
||||||
<TABLE> .01 .09 </TABLE>
|
|
||||||
</DEFINITION>
|
|
||||||
|
|
||||||
<DEFINITION>
|
|
||||||
<FOR>B</FOR>
|
|
||||||
<GIVEN>A</GIVEN>
|
|
||||||
<TABLE> .03 .97 .6 .4 </TABLE>
|
|
||||||
</DEFINITION>
|
|
||||||
|
|
||||||
<DEFINITION>
|
|
||||||
<FOR>C</FOR>
|
|
||||||
<GIVEN>A</GIVEN>
|
|
||||||
<GIVEN>E</GIVEN>
|
|
||||||
<TABLE> .24 .76 .12 .88 .2 .4. 5. .6 </TABLE>
|
|
||||||
</DEFINITION>
|
|
||||||
|
|
||||||
<DEFINITION>
|
|
||||||
<FOR>D</FOR>
|
|
||||||
<GIVEN>B</GIVEN>
|
|
||||||
<GIVEN>C</GIVEN>
|
|
||||||
<TABLE> .2 .8 .7 .3 .45 .55 .22 .78 </TABLE>
|
|
||||||
</DEFINITION>
|
|
||||||
|
|
||||||
<DEFINITION>
|
|
||||||
<FOR>E</FOR>
|
|
||||||
<TABLE> .5 .6</TABLE>
|
|
||||||
</DEFINITION>
|
|
||||||
|
|
||||||
</NETWORK>
|
|
||||||
</BIF>
|
|
||||||
|
|
@ -1,55 +0,0 @@
|
|||||||
|
|
||||||
:- use_module(library(clpbn)).
|
|
||||||
|
|
||||||
:- set_clpbn_flag(solver, bp).
|
|
||||||
|
|
||||||
%
|
|
||||||
% B F
|
|
||||||
% \ /
|
|
||||||
% \ /
|
|
||||||
% A
|
|
||||||
%
|
|
||||||
|
|
||||||
b(B) :-
|
|
||||||
b_table(BDist),
|
|
||||||
{ B = b with p([b1, b2], BDist) }.
|
|
||||||
|
|
||||||
f(F) :-
|
|
||||||
f_table(FDist),
|
|
||||||
{ F = f with p([f1, f2], FDist) }.
|
|
||||||
|
|
||||||
a(A) :-
|
|
||||||
b(B),
|
|
||||||
f(F),
|
|
||||||
a_table(ADist),
|
|
||||||
{ A = a with p([a1, a2], ADist, [B, F]) }.
|
|
||||||
|
|
||||||
d(D) :-
|
|
||||||
a(A),
|
|
||||||
f(F),
|
|
||||||
d_table(DDist),
|
|
||||||
{ D = d with p([d1, d2, d3, d4], DDist, [A, F]) }.
|
|
||||||
|
|
||||||
|
|
||||||
b_table([0.005, 0.995]).
|
|
||||||
|
|
||||||
f_table([0.03, 0.97]).
|
|
||||||
|
|
||||||
a_table([0.992, 0.99, 0.2, 0.003,
|
|
||||||
0.008, 0.01, 0.8, 0.997]).
|
|
||||||
|
|
||||||
d_table([1.0, 0.0, 0.0, 0.0,
|
|
||||||
0.0, 1.0, 0.0, 0.0,
|
|
||||||
0.0, 0.0, 1.0, 0.0,
|
|
||||||
0.0, 0.0, 0.0, 1.0]).
|
|
||||||
|
|
||||||
%d_table([0.997, 0.001, 0.001, 0.001,
|
|
||||||
% 0.001, 0.997, 0.001, 0.001,
|
|
||||||
% 0.001, 0.001, 0.997, 0.001,
|
|
||||||
% 0.001, 0.001, 0.001, 0.997]).
|
|
||||||
|
|
||||||
%d_table([0.15, 0.1, 0.7, 0.5,
|
|
||||||
% 0.25, 0.3, 0.2, 0.25,
|
|
||||||
% 0.3, 0.15, 0.35, 0.2,
|
|
||||||
% 0.3, 0.4, 0.2, 0.1]).
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
|||||||
MARKOV
|
|
||||||
3
|
|
||||||
2 2 2
|
|
||||||
3
|
|
||||||
1 0
|
|
||||||
1 1
|
|
||||||
3 2 0 1
|
|
||||||
|
|
||||||
2
|
|
||||||
0.005 0.995
|
|
||||||
|
|
||||||
2
|
|
||||||
0.03 0.97
|
|
||||||
|
|
||||||
8
|
|
||||||
0.992 0.99 0.2 0.003
|
|
||||||
0.008 0.01 0.8 0.997
|
|
@ -1,53 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="US-ASCII"?>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
|
|
||||||
B F
|
|
||||||
\ /
|
|
||||||
\ /
|
|
||||||
A
|
|
||||||
|
|
||||||
-->
|
|
||||||
|
|
||||||
<BIF VERSION="0.3">
|
|
||||||
<NETWORK>
|
|
||||||
<NAME>Neapolitan</NAME>
|
|
||||||
|
|
||||||
<VARIABLE TYPE="nature">
|
|
||||||
<NAME>B</NAME>
|
|
||||||
<OUTCOME>b1</OUTCOME>
|
|
||||||
<OUTCOME>b2</OUTCOME>
|
|
||||||
</VARIABLE>
|
|
||||||
|
|
||||||
<VARIABLE TYPE="nature">
|
|
||||||
<NAME>F</NAME>
|
|
||||||
<OUTCOME>f1</OUTCOME>
|
|
||||||
<OUTCOME>f2</OUTCOME>
|
|
||||||
</VARIABLE>
|
|
||||||
|
|
||||||
<VARIABLE TYPE="nature">
|
|
||||||
<NAME>A</NAME>
|
|
||||||
<OUTCOME>a1</OUTCOME>
|
|
||||||
<OUTCOME>a2</OUTCOME>
|
|
||||||
</VARIABLE>
|
|
||||||
|
|
||||||
<DEFINITION>
|
|
||||||
<FOR>B</FOR>
|
|
||||||
<TABLE> .005 .995 </TABLE>
|
|
||||||
</DEFINITION>
|
|
||||||
|
|
||||||
<DEFINITION>
|
|
||||||
<FOR>F</FOR>
|
|
||||||
<TABLE> .03 .97 </TABLE>
|
|
||||||
</DEFINITION>
|
|
||||||
|
|
||||||
<DEFINITION>
|
|
||||||
<FOR>A</FOR>
|
|
||||||
<GIVEN>B</GIVEN>
|
|
||||||
<GIVEN>F</GIVEN>
|
|
||||||
<TABLE> .992 .008 .99 .01 .2 .8 .003 .997 </TABLE>
|
|
||||||
</DEFINITION>
|
|
||||||
|
|
||||||
</NETWORK>
|
|
||||||
</BIF>
|
|
||||||
|
|
@ -1,36 +0,0 @@
|
|||||||
|
|
||||||
:- use_module(library(clpbn)).
|
|
||||||
|
|
||||||
:- set_clpbn_flag(solver, bp).
|
|
||||||
%:- set_clpbn_flag(solver, jt).
|
|
||||||
|
|
||||||
%
|
|
||||||
% B F
|
|
||||||
% \ /
|
|
||||||
% \ /
|
|
||||||
% A
|
|
||||||
%
|
|
||||||
|
|
||||||
|
|
||||||
b(B) :-
|
|
||||||
b_table(BDist),
|
|
||||||
{ B = b with p([b1, b2], BDist) }.
|
|
||||||
|
|
||||||
f(F) :-
|
|
||||||
f_table(FDist),
|
|
||||||
{ F = f with p([f1, f2], FDist) }.
|
|
||||||
|
|
||||||
a(A) :-
|
|
||||||
b(B),
|
|
||||||
f(F),
|
|
||||||
a_table(ADist),
|
|
||||||
{ A = a with p([a1, a2], ADist, [B, F]) }.
|
|
||||||
|
|
||||||
|
|
||||||
b_table([0.005, 0.995]).
|
|
||||||
|
|
||||||
f_table([0.03, 0.97]).
|
|
||||||
|
|
||||||
a_table([0.992, 0.99, 0.2, 0.003,
|
|
||||||
0.008, 0.01, 0.8, 0.997]).
|
|
||||||
|
|
@ -1,128 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="US-ASCII"?>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
|
|
||||||
A B C
|
|
||||||
\ | /
|
|
||||||
\ | /
|
|
||||||
D
|
|
||||||
/ | \
|
|
||||||
/ | \
|
|
||||||
E F G
|
|
||||||
|
|
||||||
-->
|
|
||||||
|
|
||||||
<BIF VERSION="0.3">
|
|
||||||
<NETWORK>
|
|
||||||
<NAME>Node with several parents and childs</NAME>
|
|
||||||
|
|
||||||
<VARIABLE TYPE="nature">
|
|
||||||
<NAME>A</NAME>
|
|
||||||
<OUTCOME>a1</OUTCOME>
|
|
||||||
<OUTCOME>a2</OUTCOME>
|
|
||||||
</VARIABLE>
|
|
||||||
|
|
||||||
<VARIABLE TYPE="nature">
|
|
||||||
<NAME>B</NAME>
|
|
||||||
<OUTCOME>b1</OUTCOME>
|
|
||||||
<OUTCOME>b2</OUTCOME>
|
|
||||||
<OUTCOME>b3</OUTCOME>
|
|
||||||
<OUTCOME>b4</OUTCOME>
|
|
||||||
</VARIABLE>
|
|
||||||
|
|
||||||
<VARIABLE TYPE="nature">
|
|
||||||
<NAME>C</NAME>
|
|
||||||
<OUTCOME>c1</OUTCOME>
|
|
||||||
<OUTCOME>c2</OUTCOME>
|
|
||||||
<OUTCOME>c3</OUTCOME>
|
|
||||||
</VARIABLE>
|
|
||||||
|
|
||||||
<VARIABLE TYPE="nature">
|
|
||||||
<NAME>D</NAME>
|
|
||||||
<OUTCOME>d1</OUTCOME>
|
|
||||||
<OUTCOME>d2</OUTCOME>
|
|
||||||
<OUTCOME>d3</OUTCOME>
|
|
||||||
</VARIABLE>
|
|
||||||
|
|
||||||
<VARIABLE TYPE="nature">
|
|
||||||
<NAME>E</NAME>
|
|
||||||
<OUTCOME>e1</OUTCOME>
|
|
||||||
<OUTCOME>e2</OUTCOME>
|
|
||||||
<OUTCOME>e3</OUTCOME>
|
|
||||||
<OUTCOME>e4</OUTCOME>
|
|
||||||
</VARIABLE>
|
|
||||||
|
|
||||||
<VARIABLE TYPE="nature">
|
|
||||||
<NAME>F</NAME>
|
|
||||||
<OUTCOME>f1</OUTCOME>
|
|
||||||
<OUTCOME>f2</OUTCOME>
|
|
||||||
<OUTCOME>f3</OUTCOME>
|
|
||||||
</VARIABLE>
|
|
||||||
|
|
||||||
<VARIABLE TYPE="nature">
|
|
||||||
<NAME>G</NAME>
|
|
||||||
<OUTCOME>g1</OUTCOME>
|
|
||||||
<OUTCOME>g2</OUTCOME>
|
|
||||||
</VARIABLE>
|
|
||||||
|
|
||||||
|
|
||||||
<DEFINITION>
|
|
||||||
<FOR>A</FOR>
|
|
||||||
<TABLE> .1 .2 </TABLE>
|
|
||||||
</DEFINITION>
|
|
||||||
|
|
||||||
<DEFINITION>
|
|
||||||
<FOR>B</FOR>
|
|
||||||
<TABLE> .01 .02 .03 .04 </TABLE>
|
|
||||||
</DEFINITION>
|
|
||||||
|
|
||||||
<DEFINITION>
|
|
||||||
<FOR>C</FOR>
|
|
||||||
<TABLE> .11 .22 .33 </TABLE>
|
|
||||||
</DEFINITION>
|
|
||||||
|
|
||||||
<DEFINITION>
|
|
||||||
<FOR>D</FOR>
|
|
||||||
<GIVEN>A</GIVEN>
|
|
||||||
<GIVEN>B</GIVEN>
|
|
||||||
<GIVEN>C</GIVEN>
|
|
||||||
<TABLE>
|
|
||||||
.522 .008 .99 .01 .2 .8 .003 .457 .423 .007 .92 .04 .5 .232 .033 .227 .112 .048 .91 .21 .24 .18 .005 .227
|
|
||||||
.212 .04 .59 .21 .6 .1 .023 .215 .913 .017 .96 .01 .55 .422 .013 .417 .272 .068 .61 .11 .26 .28 .205 .322
|
|
||||||
.142 .028 .19 .11 .5 .67 .013 .437 .163 .067 .12 .06 .1 .262 .063 .167 .512 .028 .11 .41 .14 .68 .015 .92
|
|
||||||
</TABLE>
|
|
||||||
</DEFINITION>
|
|
||||||
|
|
||||||
<DEFINITION>
|
|
||||||
<FOR>E</FOR>
|
|
||||||
<GIVEN>D</GIVEN>
|
|
||||||
<TABLE>
|
|
||||||
.111 .11 .1
|
|
||||||
.222 .22 .2
|
|
||||||
.333 .33 .3
|
|
||||||
.444 .44 .4
|
|
||||||
</TABLE>
|
|
||||||
</DEFINITION>
|
|
||||||
|
|
||||||
<DEFINITION>
|
|
||||||
<FOR>F</FOR>
|
|
||||||
<GIVEN>D</GIVEN>
|
|
||||||
<TABLE>
|
|
||||||
.112 .111 .110
|
|
||||||
.223 .222 .221
|
|
||||||
.334 .333 .332
|
|
||||||
</TABLE>
|
|
||||||
</DEFINITION>
|
|
||||||
|
|
||||||
<DEFINITION>
|
|
||||||
<FOR>G</FOR>
|
|
||||||
<GIVEN>D</GIVEN>
|
|
||||||
<TABLE>
|
|
||||||
.101 .102 .103
|
|
||||||
.201 .202 .203
|
|
||||||
</TABLE>
|
|
||||||
</DEFINITION>
|
|
||||||
|
|
||||||
</NETWORK>
|
|
||||||
</BIF>
|
|
||||||
|
|
120
packages/CLPBN/clpbn/bp/examples/smokers_2.fg
Normal file
120
packages/CLPBN/clpbn/bp/examples/smokers_2.fg
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
14
|
||||||
|
|
||||||
|
1
|
||||||
|
6
|
||||||
|
2
|
||||||
|
2
|
||||||
|
0 9.974182
|
||||||
|
1 1.000000
|
||||||
|
|
||||||
|
1
|
||||||
|
7
|
||||||
|
2
|
||||||
|
2
|
||||||
|
0 9.974182
|
||||||
|
1 1.000000
|
||||||
|
|
||||||
|
1
|
||||||
|
4
|
||||||
|
2
|
||||||
|
2
|
||||||
|
0 4.055200
|
||||||
|
1 1.000000
|
||||||
|
|
||||||
|
1
|
||||||
|
5
|
||||||
|
2
|
||||||
|
2
|
||||||
|
0 4.055200
|
||||||
|
1 1.000000
|
||||||
|
|
||||||
|
1
|
||||||
|
0
|
||||||
|
2
|
||||||
|
2
|
||||||
|
0 7.389056
|
||||||
|
1 1.000000
|
||||||
|
|
||||||
|
1
|
||||||
|
2
|
||||||
|
2
|
||||||
|
2
|
||||||
|
0 7.389056
|
||||||
|
1 1.000000
|
||||||
|
|
||||||
|
1
|
||||||
|
1
|
||||||
|
2
|
||||||
|
2
|
||||||
|
0 7.389056
|
||||||
|
1 1.000000
|
||||||
|
|
||||||
|
1
|
||||||
|
3
|
||||||
|
2
|
||||||
|
2
|
||||||
|
0 7.389056
|
||||||
|
1 1.000000
|
||||||
|
|
||||||
|
2
|
||||||
|
4 6
|
||||||
|
2 2
|
||||||
|
4
|
||||||
|
0 4.481689
|
||||||
|
1 1.000000
|
||||||
|
2 4.481689
|
||||||
|
3 4.481689
|
||||||
|
|
||||||
|
2
|
||||||
|
5 7
|
||||||
|
2 2
|
||||||
|
4
|
||||||
|
0 4.481689
|
||||||
|
1 1.000000
|
||||||
|
2 4.481689
|
||||||
|
3 4.481689
|
||||||
|
|
||||||
|
2
|
||||||
|
0 4
|
||||||
|
2 2
|
||||||
|
4
|
||||||
|
0 3.004166
|
||||||
|
1 3.004166
|
||||||
|
2 3.004166
|
||||||
|
3 3.004166
|
||||||
|
|
||||||
|
3
|
||||||
|
2 5 4
|
||||||
|
2 2 2
|
||||||
|
8
|
||||||
|
0 3.004166
|
||||||
|
1 3.004166
|
||||||
|
2 3.004166
|
||||||
|
3 1.000000
|
||||||
|
4 3.004166
|
||||||
|
5 1.000000
|
||||||
|
6 3.004166
|
||||||
|
7 3.004166
|
||||||
|
|
||||||
|
3
|
||||||
|
1 4 5
|
||||||
|
2 2 2
|
||||||
|
8
|
||||||
|
0 3.004166
|
||||||
|
1 3.004166
|
||||||
|
2 3.004166
|
||||||
|
3 1.000000
|
||||||
|
4 3.004166
|
||||||
|
5 1.000000
|
||||||
|
6 3.004166
|
||||||
|
7 3.004166
|
||||||
|
|
||||||
|
2
|
||||||
|
3 5
|
||||||
|
2 2
|
||||||
|
4
|
||||||
|
0 3.004166
|
||||||
|
1 3.004166
|
||||||
|
2 3.004166
|
||||||
|
3 3.004166
|
||||||
|
|
239
packages/CLPBN/clpbn/bp/examples/smokers_3.fg
Normal file
239
packages/CLPBN/clpbn/bp/examples/smokers_3.fg
Normal file
@ -0,0 +1,239 @@
|
|||||||
|
27
|
||||||
|
|
||||||
|
1
|
||||||
|
12
|
||||||
|
2
|
||||||
|
2
|
||||||
|
0 9.974182
|
||||||
|
1 1.000000
|
||||||
|
|
||||||
|
1
|
||||||
|
13
|
||||||
|
2
|
||||||
|
2
|
||||||
|
0 9.974182
|
||||||
|
1 1.000000
|
||||||
|
|
||||||
|
1
|
||||||
|
14
|
||||||
|
2
|
||||||
|
2
|
||||||
|
0 9.974182
|
||||||
|
1 1.000000
|
||||||
|
|
||||||
|
1
|
||||||
|
9
|
||||||
|
2
|
||||||
|
2
|
||||||
|
0 4.055200
|
||||||
|
1 1.000000
|
||||||
|
|
||||||
|
1
|
||||||
|
10
|
||||||
|
2
|
||||||
|
2
|
||||||
|
0 4.055200
|
||||||
|
1 1.000000
|
||||||
|
|
||||||
|
1
|
||||||
|
11
|
||||||
|
2
|
||||||
|
2
|
||||||
|
0 4.055200
|
||||||
|
1 1.000000
|
||||||
|
|
||||||
|
1
|
||||||
|
0
|
||||||
|
2
|
||||||
|
2
|
||||||
|
0 7.389056
|
||||||
|
1 1.000000
|
||||||
|
|
||||||
|
1
|
||||||
|
3
|
||||||
|
2
|
||||||
|
2
|
||||||
|
0 7.389056
|
||||||
|
1 1.000000
|
||||||
|
|
||||||
|
1
|
||||||
|
6
|
||||||
|
2
|
||||||
|
2
|
||||||
|
0 7.389056
|
||||||
|
1 1.000000
|
||||||
|
|
||||||
|
1
|
||||||
|
1
|
||||||
|
2
|
||||||
|
2
|
||||||
|
0 7.389056
|
||||||
|
1 1.000000
|
||||||
|
|
||||||
|
1
|
||||||
|
4
|
||||||
|
2
|
||||||
|
2
|
||||||
|
0 7.389056
|
||||||
|
1 1.000000
|
||||||
|
|
||||||
|
1
|
||||||
|
7
|
||||||
|
2
|
||||||
|
2
|
||||||
|
0 7.389056
|
||||||
|
1 1.000000
|
||||||
|
|
||||||
|
1
|
||||||
|
2
|
||||||
|
2
|
||||||
|
2
|
||||||
|
0 7.389056
|
||||||
|
1 1.000000
|
||||||
|
|
||||||
|
1
|
||||||
|
5
|
||||||
|
2
|
||||||
|
2
|
||||||
|
0 7.389056
|
||||||
|
1 1.000000
|
||||||
|
|
||||||
|
1
|
||||||
|
8
|
||||||
|
2
|
||||||
|
2
|
||||||
|
0 7.389056
|
||||||
|
1 1.000000
|
||||||
|
|
||||||
|
2
|
||||||
|
9 12
|
||||||
|
2 2
|
||||||
|
4
|
||||||
|
0 4.481689
|
||||||
|
1 1.000000
|
||||||
|
2 4.481689
|
||||||
|
3 4.481689
|
||||||
|
|
||||||
|
2
|
||||||
|
10 13
|
||||||
|
2 2
|
||||||
|
4
|
||||||
|
0 4.481689
|
||||||
|
1 1.000000
|
||||||
|
2 4.481689
|
||||||
|
3 4.481689
|
||||||
|
|
||||||
|
2
|
||||||
|
11 14
|
||||||
|
2 2
|
||||||
|
4
|
||||||
|
0 4.481689
|
||||||
|
1 1.000000
|
||||||
|
2 4.481689
|
||||||
|
3 4.481689
|
||||||
|
|
||||||
|
2
|
||||||
|
0 9
|
||||||
|
2 2
|
||||||
|
4
|
||||||
|
0 3.004166
|
||||||
|
1 3.004166
|
||||||
|
2 3.004166
|
||||||
|
3 3.004166
|
||||||
|
|
||||||
|
3
|
||||||
|
3 10 9
|
||||||
|
2 2 2
|
||||||
|
8
|
||||||
|
0 3.004166
|
||||||
|
1 3.004166
|
||||||
|
2 3.004166
|
||||||
|
3 1.000000
|
||||||
|
4 3.004166
|
||||||
|
5 1.000000
|
||||||
|
6 3.004166
|
||||||
|
7 3.004166
|
||||||
|
|
||||||
|
3
|
||||||
|
6 11 9
|
||||||
|
2 2 2
|
||||||
|
8
|
||||||
|
0 3.004166
|
||||||
|
1 3.004166
|
||||||
|
2 3.004166
|
||||||
|
3 1.000000
|
||||||
|
4 3.004166
|
||||||
|
5 1.000000
|
||||||
|
6 3.004166
|
||||||
|
7 3.004166
|
||||||
|
|
||||||
|
3
|
||||||
|
1 9 10
|
||||||
|
2 2 2
|
||||||
|
8
|
||||||
|
0 3.004166
|
||||||
|
1 3.004166
|
||||||
|
2 3.004166
|
||||||
|
3 1.000000
|
||||||
|
4 3.004166
|
||||||
|
5 1.000000
|
||||||
|
6 3.004166
|
||||||
|
7 3.004166
|
||||||
|
|
||||||
|
2
|
||||||
|
4 10
|
||||||
|
2 2
|
||||||
|
4
|
||||||
|
0 3.004166
|
||||||
|
1 3.004166
|
||||||
|
2 3.004166
|
||||||
|
3 3.004166
|
||||||
|
|
||||||
|
3
|
||||||
|
7 11 10
|
||||||
|
2 2 2
|
||||||
|
8
|
||||||
|
0 3.004166
|
||||||
|
1 3.004166
|
||||||
|
2 3.004166
|
||||||
|
3 1.000000
|
||||||
|
4 3.004166
|
||||||
|
5 1.000000
|
||||||
|
6 3.004166
|
||||||
|
7 3.004166
|
||||||
|
|
||||||
|
3
|
||||||
|
2 9 11
|
||||||
|
2 2 2
|
||||||
|
8
|
||||||
|
0 3.004166
|
||||||
|
1 3.004166
|
||||||
|
2 3.004166
|
||||||
|
3 1.000000
|
||||||
|
4 3.004166
|
||||||
|
5 1.000000
|
||||||
|
6 3.004166
|
||||||
|
7 3.004166
|
||||||
|
|
||||||
|
3
|
||||||
|
5 10 11
|
||||||
|
2 2 2
|
||||||
|
8
|
||||||
|
0 3.004166
|
||||||
|
1 3.004166
|
||||||
|
2 3.004166
|
||||||
|
3 1.000000
|
||||||
|
4 3.004166
|
||||||
|
5 1.000000
|
||||||
|
6 3.004166
|
||||||
|
7 3.004166
|
||||||
|
|
||||||
|
2
|
||||||
|
8 11
|
||||||
|
2 2
|
||||||
|
4
|
||||||
|
0 3.004166
|
||||||
|
1 3.004166
|
||||||
|
2 3.004166
|
||||||
|
3 3.004166
|
||||||
|
|
398
packages/CLPBN/clpbn/bp/examples/smokers_4.fg
Normal file
398
packages/CLPBN/clpbn/bp/examples/smokers_4.fg
Normal file
@ -0,0 +1,398 @@
|
|||||||
|
44
|
||||||
|
|
||||||
|
1
|
||||||
|
20
|
||||||
|
2
|
||||||
|
2
|
||||||
|
0 9.974182
|
||||||
|
1 1.000000
|
||||||
|
|
||||||
|
1
|
||||||
|
21
|
||||||
|
2
|
||||||
|
2
|
||||||
|
0 9.974182
|
||||||
|
1 1.000000
|
||||||
|
|
||||||
|
1
|
||||||
|
22
|
||||||
|
2
|
||||||
|
2
|
||||||
|
0 9.974182
|
||||||
|
1 1.000000
|
||||||
|
|
||||||
|
1
|
||||||
|
23
|
||||||
|
2
|
||||||
|
2
|
||||||
|
0 9.974182
|
||||||
|
1 1.000000
|
||||||
|
|
||||||
|
1
|
||||||
|
16
|
||||||
|
2
|
||||||
|
2
|
||||||
|
0 4.055200
|
||||||
|
1 1.000000
|
||||||
|
|
||||||
|
1
|
||||||
|
17
|
||||||
|
2
|
||||||
|
2
|
||||||
|
0 4.055200
|
||||||
|
1 1.000000
|
||||||
|
|
||||||
|
1
|
||||||
|
18
|
||||||
|
2
|
||||||
|
2
|
||||||
|
0 4.055200
|
||||||
|
1 1.000000
|
||||||
|
|
||||||
|
1
|
||||||
|
19
|
||||||
|
2
|
||||||
|
2
|
||||||
|
0 4.055200
|
||||||
|
1 1.000000
|
||||||
|
|
||||||
|
1
|
||||||
|
0
|
||||||
|
2
|
||||||
|
2
|
||||||
|
0 7.389056
|
||||||
|
1 1.000000
|
||||||
|
|
||||||
|
1
|
||||||
|
4
|
||||||
|
2
|
||||||
|
2
|
||||||
|
0 7.389056
|
||||||
|
1 1.000000
|
||||||
|
|
||||||
|
1
|
||||||
|
8
|
||||||
|
2
|
||||||
|
2
|
||||||
|
0 7.389056
|
||||||
|
1 1.000000
|
||||||
|
|
||||||
|
1
|
||||||
|
12
|
||||||
|
2
|
||||||
|
2
|
||||||
|
0 7.389056
|
||||||
|
1 1.000000
|
||||||
|
|
||||||
|
1
|
||||||
|
1
|
||||||
|
2
|
||||||
|
2
|
||||||
|
0 7.389056
|
||||||
|
1 1.000000
|
||||||
|
|
||||||
|
1
|
||||||
|
5
|
||||||
|
2
|
||||||
|
2
|
||||||
|
0 7.389056
|
||||||
|
1 1.000000
|
||||||
|
|
||||||
|
1
|
||||||
|
9
|
||||||
|
2
|
||||||
|
2
|
||||||
|
0 7.389056
|
||||||
|
1 1.000000
|
||||||
|
|
||||||
|
1
|
||||||
|
13
|
||||||
|
2
|
||||||
|
2
|
||||||
|
0 7.389056
|
||||||
|
1 1.000000
|
||||||
|
|
||||||
|
1
|
||||||
|
2
|
||||||
|
2
|
||||||
|
2
|
||||||
|
0 7.389056
|
||||||
|
1 1.000000
|
||||||
|
|
||||||
|
1
|
||||||
|
6
|
||||||
|
2
|
||||||
|
2
|
||||||
|
0 7.389056
|
||||||
|
1 1.000000
|
||||||
|
|
||||||
|
1
|
||||||
|
10
|
||||||
|
2
|
||||||
|
2
|
||||||
|
0 7.389056
|
||||||
|
1 1.000000
|
||||||
|
|
||||||
|
1
|
||||||
|
14
|
||||||
|
2
|
||||||
|
2
|
||||||
|
0 7.389056
|
||||||
|
1 1.000000
|
||||||
|
|
||||||
|
1
|
||||||
|
3
|
||||||
|
2
|
||||||
|
2
|
||||||
|
0 7.389056
|
||||||
|
1 1.000000
|
||||||
|
|
||||||
|
1
|
||||||
|
7
|
||||||
|
2
|
||||||
|
2
|
||||||
|
0 7.389056
|
||||||
|
1 1.000000
|
||||||
|
|
||||||
|
1
|
||||||
|
11
|
||||||
|
2
|
||||||
|
2
|
||||||
|
0 7.389056
|
||||||
|
1 1.000000
|
||||||
|
|
||||||
|
1
|
||||||
|
15
|
||||||
|
2
|
||||||
|
2
|
||||||
|
0 7.389056
|
||||||
|
1 1.000000
|
||||||
|
|
||||||
|
2
|
||||||
|
16 20
|
||||||
|
2 2
|
||||||
|
4
|
||||||
|
0 4.481689
|
||||||
|
1 1.000000
|
||||||
|
2 4.481689
|
||||||
|
3 4.481689
|
||||||
|
|
||||||
|
2
|
||||||
|
17 21
|
||||||
|
2 2
|
||||||
|
4
|
||||||
|
0 4.481689
|
||||||
|
1 1.000000
|
||||||
|
2 4.481689
|
||||||
|
3 4.481689
|
||||||
|
|
||||||
|
2
|
||||||
|
18 22
|
||||||
|
2 2
|
||||||
|
4
|
||||||
|
0 4.481689
|
||||||
|
1 1.000000
|
||||||
|
2 4.481689
|
||||||
|
3 4.481689
|
||||||
|
|
||||||
|
2
|
||||||
|
19 23
|
||||||
|
2 2
|
||||||
|
4
|
||||||
|
0 4.481689
|
||||||
|
1 1.000000
|
||||||
|
2 4.481689
|
||||||
|
3 4.481689
|
||||||
|
|
||||||
|
2
|
||||||
|
0 16
|
||||||
|
2 2
|
||||||
|
4
|
||||||
|
0 3.004166
|
||||||
|
1 3.004166
|
||||||
|
2 3.004166
|
||||||
|
3 3.004166
|
||||||
|
|
||||||
|
3
|
||||||
|
4 17 16
|
||||||
|
2 2 2
|
||||||
|
8
|
||||||
|
0 3.004166
|
||||||
|
1 3.004166
|
||||||
|
2 3.004166
|
||||||
|
3 1.000000
|
||||||
|
4 3.004166
|
||||||
|
5 1.000000
|
||||||
|
6 3.004166
|
||||||
|
7 3.004166
|
||||||
|
|
||||||
|
3
|
||||||
|
8 18 16
|
||||||
|
2 2 2
|
||||||
|
8
|
||||||
|
0 3.004166
|
||||||
|
1 3.004166
|
||||||
|
2 3.004166
|
||||||
|
3 1.000000
|
||||||
|
4 3.004166
|
||||||
|
5 1.000000
|
||||||
|
6 3.004166
|
||||||
|
7 3.004166
|
||||||
|
|
||||||
|
3
|
||||||
|
12 19 16
|
||||||
|
2 2 2
|
||||||
|
8
|
||||||
|
0 3.004166
|
||||||
|
1 3.004166
|
||||||
|
2 3.004166
|
||||||
|
3 1.000000
|
||||||
|
4 3.004166
|
||||||
|
5 1.000000
|
||||||
|
6 3.004166
|
||||||
|
7 3.004166
|
||||||
|
|
||||||
|
3
|
||||||
|
1 16 17
|
||||||
|
2 2 2
|
||||||
|
8
|
||||||
|
0 3.004166
|
||||||
|
1 3.004166
|
||||||
|
2 3.004166
|
||||||
|
3 1.000000
|
||||||
|
4 3.004166
|
||||||
|
5 1.000000
|
||||||
|
6 3.004166
|
||||||
|
7 3.004166
|
||||||
|
|
||||||
|
2
|
||||||
|
5 17
|
||||||
|
2 2
|
||||||
|
4
|
||||||
|
0 3.004166
|
||||||
|
1 3.004166
|
||||||
|
2 3.004166
|
||||||
|
3 3.004166
|
||||||
|
|
||||||
|
3
|
||||||
|
9 18 17
|
||||||
|
2 2 2
|
||||||
|
8
|
||||||
|
0 3.004166
|
||||||
|
1 3.004166
|
||||||
|
2 3.004166
|
||||||
|
3 1.000000
|
||||||
|
4 3.004166
|
||||||
|
5 1.000000
|
||||||
|
6 3.004166
|
||||||
|
7 3.004166
|
||||||
|
|
||||||
|
3
|
||||||
|
13 19 17
|
||||||
|
2 2 2
|
||||||
|
8
|
||||||
|
0 3.004166
|
||||||
|
1 3.004166
|
||||||
|
2 3.004166
|
||||||
|
3 1.000000
|
||||||
|
4 3.004166
|
||||||
|
5 1.000000
|
||||||
|
6 3.004166
|
||||||
|
7 3.004166
|
||||||
|
|
||||||
|
3
|
||||||
|
2 16 18
|
||||||
|
2 2 2
|
||||||
|
8
|
||||||
|
0 3.004166
|
||||||
|
1 3.004166
|
||||||
|
2 3.004166
|
||||||
|
3 1.000000
|
||||||
|
4 3.004166
|
||||||
|
5 1.000000
|
||||||
|
6 3.004166
|
||||||
|
7 3.004166
|
||||||
|
|
||||||
|
3
|
||||||
|
6 17 18
|
||||||
|
2 2 2
|
||||||
|
8
|
||||||
|
0 3.004166
|
||||||
|
1 3.004166
|
||||||
|
2 3.004166
|
||||||
|
3 1.000000
|
||||||
|
4 3.004166
|
||||||
|
5 1.000000
|
||||||
|
6 3.004166
|
||||||
|
7 3.004166
|
||||||
|
|
||||||
|
2
|
||||||
|
10 18
|
||||||
|
2 2
|
||||||
|
4
|
||||||
|
0 3.004166
|
||||||
|
1 3.004166
|
||||||
|
2 3.004166
|
||||||
|
3 3.004166
|
||||||
|
|
||||||
|
3
|
||||||
|
14 19 18
|
||||||
|
2 2 2
|
||||||
|
8
|
||||||
|
0 3.004166
|
||||||
|
1 3.004166
|
||||||
|
2 3.004166
|
||||||
|
3 1.000000
|
||||||
|
4 3.004166
|
||||||
|
5 1.000000
|
||||||
|
6 3.004166
|
||||||
|
7 3.004166
|
||||||
|
|
||||||
|
3
|
||||||
|
3 16 19
|
||||||
|
2 2 2
|
||||||
|
8
|
||||||
|
0 3.004166
|
||||||
|
1 3.004166
|
||||||
|
2 3.004166
|
||||||
|
3 1.000000
|
||||||
|
4 3.004166
|
||||||
|
5 1.000000
|
||||||
|
6 3.004166
|
||||||
|
7 3.004166
|
||||||
|
|
||||||
|
3
|
||||||
|
7 17 19
|
||||||
|
2 2 2
|
||||||
|
8
|
||||||
|
0 3.004166
|
||||||
|
1 3.004166
|
||||||
|
2 3.004166
|
||||||
|
3 1.000000
|
||||||
|
4 3.004166
|
||||||
|
5 1.000000
|
||||||
|
6 3.004166
|
||||||
|
7 3.004166
|
||||||
|
|
||||||
|
3
|
||||||
|
11 18 19
|
||||||
|
2 2 2
|
||||||
|
8
|
||||||
|
0 3.004166
|
||||||
|
1 3.004166
|
||||||
|
2 3.004166
|
||||||
|
3 1.000000
|
||||||
|
4 3.004166
|
||||||
|
5 1.000000
|
||||||
|
6 3.004166
|
||||||
|
7 3.004166
|
||||||
|
|
||||||
|
2
|
||||||
|
15 19
|
||||||
|
2 2
|
||||||
|
4
|
||||||
|
0 3.004166
|
||||||
|
1 3.004166
|
||||||
|
2 3.004166
|
||||||
|
3 3.004166
|
||||||
|
|
@ -1,17 +0,0 @@
|
|||||||
MARKOV
|
|
||||||
3
|
|
||||||
2 2 2
|
|
||||||
3
|
|
||||||
1 0
|
|
||||||
1 1
|
|
||||||
3 2 0 1
|
|
||||||
|
|
||||||
2
|
|
||||||
.695 .305
|
|
||||||
|
|
||||||
2
|
|
||||||
.25 .75
|
|
||||||
|
|
||||||
8
|
|
||||||
0.2 0.45 0.32 0.7
|
|
||||||
0.8 0.55 0.68 0.3
|
|
@ -1,36 +0,0 @@
|
|||||||
MARKOV
|
|
||||||
5
|
|
||||||
4 2 3 2 3
|
|
||||||
7
|
|
||||||
1 0
|
|
||||||
1 1
|
|
||||||
1 2
|
|
||||||
1 3
|
|
||||||
1 4
|
|
||||||
2 0 1
|
|
||||||
4 1 2 3 4
|
|
||||||
|
|
||||||
4
|
|
||||||
0.1 0.7 0.43 0.22
|
|
||||||
|
|
||||||
2
|
|
||||||
0.2 0.6
|
|
||||||
|
|
||||||
3
|
|
||||||
0.3 0.5 0.2
|
|
||||||
|
|
||||||
2
|
|
||||||
0.15 0.75
|
|
||||||
|
|
||||||
3
|
|
||||||
0.25 0.45 0.15
|
|
||||||
|
|
||||||
8
|
|
||||||
0.210 0.333 0.457 0.4
|
|
||||||
0.811 0.000 0.189 0.89
|
|
||||||
|
|
||||||
36
|
|
||||||
0.1 0.15 0.2 0.25 0.3 0.45 0.5 0.55 0.65 0.7 0.75 0.9
|
|
||||||
0.11 0.22 0.33 0.44 0.55 0.66 0.77 0.88 0.91 0.93 0.95 0.97
|
|
||||||
0.42 0.22 0.33 0.44 0.15 0.36 0.27 0.28 0.21 0.13 0.25 0.17
|
|
||||||
|
|
@ -1,128 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="US-ASCII"?>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
|
|
||||||
A B C
|
|
||||||
\ | /
|
|
||||||
\ | /
|
|
||||||
D
|
|
||||||
/ | \
|
|
||||||
/ | \
|
|
||||||
E F G
|
|
||||||
|
|
||||||
-->
|
|
||||||
|
|
||||||
<BIF VERSION="0.3">
|
|
||||||
<NETWORK>
|
|
||||||
<NAME>Node with several parents and childs</NAME>
|
|
||||||
|
|
||||||
<VARIABLE TYPE="nature">
|
|
||||||
<NAME>A</NAME>
|
|
||||||
<OUTCOME>a1</OUTCOME>
|
|
||||||
<OUTCOME>a2</OUTCOME>
|
|
||||||
</VARIABLE>
|
|
||||||
|
|
||||||
<VARIABLE TYPE="nature">
|
|
||||||
<NAME>B</NAME>
|
|
||||||
<OUTCOME>b1</OUTCOME>
|
|
||||||
<OUTCOME>b2</OUTCOME>
|
|
||||||
<OUTCOME>b3</OUTCOME>
|
|
||||||
<OUTCOME>b4</OUTCOME>
|
|
||||||
</VARIABLE>
|
|
||||||
|
|
||||||
<VARIABLE TYPE="nature">
|
|
||||||
<NAME>C</NAME>
|
|
||||||
<OUTCOME>c1</OUTCOME>
|
|
||||||
<OUTCOME>c2</OUTCOME>
|
|
||||||
<OUTCOME>c3</OUTCOME>
|
|
||||||
</VARIABLE>
|
|
||||||
|
|
||||||
<VARIABLE TYPE="nature">
|
|
||||||
<NAME>D</NAME>
|
|
||||||
<OUTCOME>d1</OUTCOME>
|
|
||||||
<OUTCOME>d2</OUTCOME>
|
|
||||||
<OUTCOME>d3</OUTCOME>
|
|
||||||
</VARIABLE>
|
|
||||||
|
|
||||||
<VARIABLE TYPE="nature">
|
|
||||||
<NAME>E</NAME>
|
|
||||||
<OUTCOME>e1</OUTCOME>
|
|
||||||
<OUTCOME>e2</OUTCOME>
|
|
||||||
<OUTCOME>e3</OUTCOME>
|
|
||||||
<OUTCOME>e4</OUTCOME>
|
|
||||||
</VARIABLE>
|
|
||||||
|
|
||||||
<VARIABLE TYPE="nature">
|
|
||||||
<NAME>F</NAME>
|
|
||||||
<OUTCOME>f1</OUTCOME>
|
|
||||||
<OUTCOME>f2</OUTCOME>
|
|
||||||
<OUTCOME>f3</OUTCOME>
|
|
||||||
</VARIABLE>
|
|
||||||
|
|
||||||
<VARIABLE TYPE="nature">
|
|
||||||
<NAME>G</NAME>
|
|
||||||
<OUTCOME>g1</OUTCOME>
|
|
||||||
<OUTCOME>g2</OUTCOME>
|
|
||||||
</VARIABLE>
|
|
||||||
|
|
||||||
|
|
||||||
<DEFINITION>
|
|
||||||
<FOR>A</FOR>
|
|
||||||
<TABLE> .1 .2 </TABLE>
|
|
||||||
</DEFINITION>
|
|
||||||
|
|
||||||
<DEFINITION>
|
|
||||||
<FOR>B</FOR>
|
|
||||||
<TABLE> .01 .02 .03 .04 </TABLE>
|
|
||||||
</DEFINITION>
|
|
||||||
|
|
||||||
<DEFINITION>
|
|
||||||
<FOR>C</FOR>
|
|
||||||
<TABLE> .11 .22 .33 </TABLE>
|
|
||||||
</DEFINITION>
|
|
||||||
|
|
||||||
<DEFINITION>
|
|
||||||
<FOR>D</FOR>
|
|
||||||
<GIVEN>A</GIVEN>
|
|
||||||
<GIVEN>B</GIVEN>
|
|
||||||
<GIVEN>C</GIVEN>
|
|
||||||
<TABLE>
|
|
||||||
.522 .008 .99 .01 .2 .8 .003 .457 .423 .007 .92 .04 .5 .232 .033 .227 .112 .048 .91 .21 .24 .18 .005 .227
|
|
||||||
.212 .04 .59 .21 .6 .1 .023 .215 .913 .017 .96 .01 .55 .422 .013 .417 .272 .068 .61 .11 .26 .28 .205 .322
|
|
||||||
.142 .028 .19 .11 .5 .67 .013 .437 .163 .067 .12 .06 .1 .262 .063 .167 .512 .028 .11 .41 .14 .68 .015 .92
|
|
||||||
</TABLE>
|
|
||||||
</DEFINITION>
|
|
||||||
|
|
||||||
<DEFINITION>
|
|
||||||
<FOR>E</FOR>
|
|
||||||
<GIVEN>D</GIVEN>
|
|
||||||
<TABLE>
|
|
||||||
.111 .11 .1
|
|
||||||
.222 .22 .2
|
|
||||||
.333 .33 .3
|
|
||||||
.444 .44 .4
|
|
||||||
</TABLE>
|
|
||||||
</DEFINITION>
|
|
||||||
|
|
||||||
<DEFINITION>
|
|
||||||
<FOR>F</FOR>
|
|
||||||
<GIVEN>D</GIVEN>
|
|
||||||
<TABLE>
|
|
||||||
.112 .111 .110
|
|
||||||
.223 .222 .221
|
|
||||||
.334 .333 .332
|
|
||||||
</TABLE>
|
|
||||||
</DEFINITION>
|
|
||||||
|
|
||||||
<DEFINITION>
|
|
||||||
<FOR>G</FOR>
|
|
||||||
<GIVEN>D</GIVEN>
|
|
||||||
<TABLE>
|
|
||||||
.101 .102 .103
|
|
||||||
.201 .202 .203
|
|
||||||
</TABLE>
|
|
||||||
</DEFINITION>
|
|
||||||
|
|
||||||
</NETWORK>
|
|
||||||
</BIF>
|
|
||||||
|
|
@ -1,36 +0,0 @@
|
|||||||
MARKOV
|
|
||||||
5
|
|
||||||
4 2 3 2 3
|
|
||||||
7
|
|
||||||
1 0
|
|
||||||
1 1
|
|
||||||
1 2
|
|
||||||
1 3
|
|
||||||
1 4
|
|
||||||
2 0 1
|
|
||||||
4 1 2 3 4
|
|
||||||
|
|
||||||
4
|
|
||||||
0.1 0.7 0.43 0.22
|
|
||||||
|
|
||||||
2
|
|
||||||
0.2 0.6
|
|
||||||
|
|
||||||
3
|
|
||||||
0.3 0.5 0.2
|
|
||||||
|
|
||||||
2
|
|
||||||
0.15 0.75
|
|
||||||
|
|
||||||
3
|
|
||||||
0.25 0.45 0.15
|
|
||||||
|
|
||||||
8
|
|
||||||
0.210 0.333 0.457 0.4
|
|
||||||
0.811 0.000 0.189 0.89
|
|
||||||
|
|
||||||
36
|
|
||||||
0.1 0.15 0.2 0.25 0.3 0.45 0.5 0.55 0.65 0.7 0.75 0.9
|
|
||||||
0.11 0.22 0.33 0.44 0.55 0.66 0.77 0.88 0.91 0.93 0.95 0.97
|
|
||||||
0.42 0.22 0.33 0.44 0.15 0.36 0.27 0.28 0.21 0.13 0.25 0.17
|
|
||||||
|
|
@ -1,60 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
cp ~/bin/yap ~/bin/town_comp
|
|
||||||
YAP=~/bin/town_comp
|
|
||||||
|
|
||||||
#OUT_FILE_NAME=results`date "+ %H:%M:%S %d-%m-%Y"`.log
|
|
||||||
OUT_FILE_NAME=bp_compress.log
|
|
||||||
rm -f $OUT_FILE_NAME
|
|
||||||
rm -f ignore.$OUT_FILE_NAME
|
|
||||||
|
|
||||||
|
|
||||||
function run_solver
|
|
||||||
{
|
|
||||||
if [ $2 = bp ]
|
|
||||||
then
|
|
||||||
extra_flag1=clpbn_bp:set_solver_parameter\(run_mode,$4\)
|
|
||||||
extra_flag2=clpbn_bp:set_solver_parameter\(schedule,$5\)
|
|
||||||
extra_flag3=clpbn_bp:set_solver_parameter\(always_loopy_solver,$6\)
|
|
||||||
else
|
|
||||||
extra_flag1=true
|
|
||||||
extra_flag2=true
|
|
||||||
extra_flag3=true
|
|
||||||
fi
|
|
||||||
/usr/bin/time -o $OUT_FILE_NAME -a -f "real:%E\tuser:%U\tsys:%S" $YAP << EOF >> $OUT_FILE_NAME 2>> ignore.$OUT_FILE_NAME
|
|
||||||
[$1].
|
|
||||||
clpbn:set_clpbn_flag(solver,$2),
|
|
||||||
clpbn_bp:use_log_space,
|
|
||||||
$extra_flag1, $extra_flag2, $extra_flag3,
|
|
||||||
run_query(_R),
|
|
||||||
open("$OUT_FILE_NAME", 'append',S),
|
|
||||||
format(S, '$3: ~15+ ',[]),
|
|
||||||
close(S).
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function run_all_graphs
|
|
||||||
{
|
|
||||||
echo "*******************************************************************" >> "$OUT_FILE_NAME"
|
|
||||||
echo "results for solver $2" >> $OUT_FILE_NAME
|
|
||||||
echo "*******************************************************************" >> "$OUT_FILE_NAME"
|
|
||||||
run_solver town_1000 $1 town_1000 $3 $4 $5
|
|
||||||
run_solver town_5000 $1 town_5000 $3 $4 $5
|
|
||||||
run_solver town_10000 $1 town_10000 $3 $4 $5
|
|
||||||
run_solver town_50000 $1 town_50000 $3 $4 $5
|
|
||||||
run_solver town_100000 $1 town_100000 $3 $4 $5
|
|
||||||
run_solver town_500000 $1 town_500000 $3 $4 $5
|
|
||||||
run_solver town_1000000 $1 town_1000000 $3 $4 $5
|
|
||||||
run_solver town_2500000 $1 town_2500000 $3 $4 $5
|
|
||||||
run_solver town_5000000 $1 town_5000000 $3 $4 $5
|
|
||||||
run_solver town_7500000 $1 town_7500000 $3 $4 $5
|
|
||||||
run_solver town_10000000 $1 town_10000000 $3 $4 $5
|
|
||||||
}
|
|
||||||
|
|
||||||
run_solver town_10000 "bp(compress,seq_fixed)" town_10000 compress seq_fixed true
|
|
||||||
exit
|
|
||||||
|
|
||||||
##########
|
|
||||||
run_all_graphs bp "bp(compress,seq_fixed) " compress seq_fixed true
|
|
||||||
|
|
@ -1,51 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
YAP=~/bin/town_conv
|
|
||||||
|
|
||||||
#OUT_FILE_NAME=results`date "+ %H:%M:%S %d-%m-%Y"`.log
|
|
||||||
OUT_FILE_NAME=bp_convert.log
|
|
||||||
rm -f $OUT_FILE_NAME
|
|
||||||
rm -f ignore.$OUT_FILE_NAME
|
|
||||||
|
|
||||||
|
|
||||||
function run_solver
|
|
||||||
{
|
|
||||||
if [ $2 = bp ]
|
|
||||||
then
|
|
||||||
extra_flag1=clpbn_bp:set_solver_parameter\(run_mode,$4\)
|
|
||||||
extra_flag2=clpbn_bp:set_solver_parameter\(schedule,$5\)
|
|
||||||
extra_flag3=clpbn_bp:set_solver_parameter\(always_loopy_solver,$6\)
|
|
||||||
else
|
|
||||||
extra_flag1=true
|
|
||||||
extra_flag2=true
|
|
||||||
extra_flag3=true
|
|
||||||
fi
|
|
||||||
/usr/bin/time -o $OUT_FILE_NAME -a -f "real:%E\tuser:%U\tsys:%S" $YAP << EOF >> $OUT_FILE_NAME 2>> ignore.$OUT_FILE_NAME
|
|
||||||
[$1].
|
|
||||||
clpbn:set_clpbn_flag(solver,$2),
|
|
||||||
clpbn_bp:use_log_space,
|
|
||||||
$extra_flag1, $extra_flag2, $extra_flag3,
|
|
||||||
run_query(_R),
|
|
||||||
open("$OUT_FILE_NAME", 'append',S),
|
|
||||||
format(S, '$3: ~15+ ',[]),
|
|
||||||
close(S).
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function run_all_graphs
|
|
||||||
{
|
|
||||||
echo "*******************************************************************" >> "$OUT_FILE_NAME"
|
|
||||||
echo "results for solver $2" >> $OUT_FILE_NAME
|
|
||||||
echo "*******************************************************************" >> "$OUT_FILE_NAME"
|
|
||||||
run_solver town_1000 $1 town_1000 $3 $4 $5
|
|
||||||
run_solver town_5000 $1 town_5000 $3 $4 $5
|
|
||||||
run_solver town_10000 $1 town_10000 $3 $4 $5
|
|
||||||
run_solver town_50000 $1 town_50000 $3 $4 $5
|
|
||||||
run_solver town_100000 $1 town_100000 $3 $4 $5
|
|
||||||
run_solver town_500000 $1 town_500000 $3 $4 $5
|
|
||||||
run_solver town_1000000 $1 town_1000000 $3 $4 $5
|
|
||||||
}
|
|
||||||
|
|
||||||
run_all_graphs bp "bp(convert,seq_fixed) " convert seq_fixed false
|
|
||||||
|
|
@ -1,50 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
YAP=~/bin/town_norm
|
|
||||||
|
|
||||||
#OUT_FILE_NAME=results`date "+ %H:%M:%S %d-%m-%Y"`.log
|
|
||||||
OUT_FILE_NAME=bp_normal.log
|
|
||||||
rm -f $OUT_FILE_NAME
|
|
||||||
rm -f ignore.$OUT_FILE_NAME
|
|
||||||
|
|
||||||
|
|
||||||
function run_solver
|
|
||||||
{
|
|
||||||
if [ $2 = bp ]
|
|
||||||
then
|
|
||||||
extra_flag1=clpbn_bp:set_solver_parameter\(run_mode,$4\)
|
|
||||||
extra_flag2=clpbn_bp:set_solver_parameter\(schedule,$5\)
|
|
||||||
extra_flag3=clpbn_bp:set_solver_parameter\(always_loopy_solver,$6\)
|
|
||||||
else
|
|
||||||
extra_flag1=true
|
|
||||||
extra_flag2=true
|
|
||||||
extra_flag3=true
|
|
||||||
fi
|
|
||||||
/usr/bin/time -o $OUT_FILE_NAME -a -f "real:%E\tuser:%U\tsys:%S" $YAP << EOF >> $OUT_FILE_NAME 2>> ignore.$OUT_FILE_NAME
|
|
||||||
[$1].
|
|
||||||
clpbn:set_clpbn_flag(solver,$2),
|
|
||||||
clpbn_bp:use_log_space,
|
|
||||||
$extra_flag1, $extra_flag2, $extra_flag3,
|
|
||||||
run_query(_R),
|
|
||||||
open("$OUT_FILE_NAME", 'append',S),
|
|
||||||
format(S, '$3: ~15+ ',[]),
|
|
||||||
close(S).
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function run_all_graphs
|
|
||||||
{
|
|
||||||
echo "*******************************************************************" >> "$OUT_FILE_NAME"
|
|
||||||
echo "results for solver $2" >> $OUT_FILE_NAME
|
|
||||||
echo "*******************************************************************" >> "$OUT_FILE_NAME"
|
|
||||||
run_solver town_1000 $1 town_1000 $3 $4 $5
|
|
||||||
run_solver town_5000 $1 town_5000 $3 $4 $5
|
|
||||||
run_solver town_10000 $1 town_10000 $3 $4 $5
|
|
||||||
run_solver town_50000 $1 town_50000 $3 $4 $5
|
|
||||||
run_solver town_100000 $1 town_100000 $3 $4 $5
|
|
||||||
run_solver town_500000 $1 town_500000 $3 $4 $5
|
|
||||||
run_solver town_1000000 $1 town_1000000 $3 $4 $5
|
|
||||||
}
|
|
||||||
|
|
||||||
run_all_graphs bp "bp(normal,seq_fixed) " normal seq_fixed false
|
|
@ -1,51 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
YAP=~/bin/town_gibbs
|
|
||||||
|
|
||||||
#OUT_FILE_NAME=results`date "+ %H:%M:%S %d-%m-%Y"`.log
|
|
||||||
OUT_FILE_NAME=gibbs.log
|
|
||||||
rm -f $OUT_FILE_NAME
|
|
||||||
rm -f ignore.$OUT_FILE_NAME
|
|
||||||
|
|
||||||
|
|
||||||
function run_solver
|
|
||||||
{
|
|
||||||
if [ $2 = bp ]
|
|
||||||
then
|
|
||||||
extra_flag1=clpbn_bp:set_solver_parameter\(run_mode,$4\)
|
|
||||||
extra_flag2=clpbn_bp:set_solver_parameter\(schedule,$5\)
|
|
||||||
extra_flag3=clpbn_bp:set_solver_parameter\(always_loopy_solver,$6\)
|
|
||||||
else
|
|
||||||
extra_flag1=true
|
|
||||||
extra_flag2=true
|
|
||||||
extra_flag3=true
|
|
||||||
fi
|
|
||||||
/usr/bin/time -o $OUT_FILE_NAME -a -f "real:%E\tuser:%U\tsys:%S" $YAP << EOF >> $OUT_FILE_NAME 2>> ignore.$OUT_FILE_NAME
|
|
||||||
[$1].
|
|
||||||
clpbn:set_clpbn_flag(solver,$2),
|
|
||||||
clpbn_bp:use_log_space,
|
|
||||||
$extra_flag1, $extra_flag2, $extra_flag3,
|
|
||||||
run_query(_R),
|
|
||||||
open("$OUT_FILE_NAME", 'append',S),
|
|
||||||
format(S, '$3: ~15+ ',[]),
|
|
||||||
close(S).
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function run_all_graphs
|
|
||||||
{
|
|
||||||
echo "*******************************************************************" >> "$OUT_FILE_NAME"
|
|
||||||
echo "results for solver $2" >> $OUT_FILE_NAME
|
|
||||||
echo "*******************************************************************" >> "$OUT_FILE_NAME"
|
|
||||||
run_solver town_1000 $1 town_1000 $3 $4 $5
|
|
||||||
run_solver town_5000 $1 town_5000 $3 $4 $5
|
|
||||||
run_solver town_10000 $1 town_10000 $3 $4 $5
|
|
||||||
run_solver town_50000 $1 town_50000 $3 $4 $5
|
|
||||||
run_solver town_100000 $1 town_100000 $3 $4 $5
|
|
||||||
run_solver town_500000 $1 town_500000 $3 $4 $5
|
|
||||||
run_solver town_1000000 $1 town_1000000 $3 $4 $5
|
|
||||||
}
|
|
||||||
|
|
||||||
run_all_graphs gibbs "gibbs "
|
|
||||||
|
|
@ -1,51 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
YAP=~/bin/town_jt
|
|
||||||
|
|
||||||
#OUT_FILE_NAME=results`date "+ %H:%M:%S %d-%m-%Y"`.log
|
|
||||||
OUT_FILE_NAME=jt.log
|
|
||||||
rm -f $OUT_FILE_NAME
|
|
||||||
rm -f ignore.$OUT_FILE_NAME
|
|
||||||
|
|
||||||
|
|
||||||
function run_solver
|
|
||||||
{
|
|
||||||
if [ $2 = bp ]
|
|
||||||
then
|
|
||||||
extra_flag1=clpbn_bp:set_solver_parameter\(run_mode,$4\)
|
|
||||||
extra_flag2=clpbn_bp:set_solver_parameter\(schedule,$5\)
|
|
||||||
extra_flag3=clpbn_bp:set_solver_parameter\(always_loopy_solver,$6\)
|
|
||||||
else
|
|
||||||
extra_flag1=true
|
|
||||||
extra_flag2=true
|
|
||||||
extra_flag3=true
|
|
||||||
fi
|
|
||||||
/usr/bin/time -o $OUT_FILE_NAME -a -f "real:%E\tuser:%U\tsys:%S" $YAP << EOF >> $OUT_FILE_NAME 2>> ignore.$OUT_FILE_NAME
|
|
||||||
[$1].
|
|
||||||
clpbn:set_clpbn_flag(solver,$2),
|
|
||||||
clpbn_bp:use_log_space,
|
|
||||||
$extra_flag1, $extra_flag2, $extra_flag3,
|
|
||||||
run_query(_R),
|
|
||||||
open("$OUT_FILE_NAME", 'append',S),
|
|
||||||
format(S, '$3: ~15+ ',[]),
|
|
||||||
close(S).
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function run_all_graphs
|
|
||||||
{
|
|
||||||
echo "*******************************************************************" >> "$OUT_FILE_NAME"
|
|
||||||
echo "results for solver $2" >> $OUT_FILE_NAME
|
|
||||||
echo "*******************************************************************" >> "$OUT_FILE_NAME"
|
|
||||||
run_solver town_1000 $1 town_1000 $3 $4 $5
|
|
||||||
run_solver town_5000 $1 town_5000 $3 $4 $5
|
|
||||||
run_solver town_10000 $1 town_10000 $3 $4 $5
|
|
||||||
run_solver town_50000 $1 town_50000 $3 $4 $5
|
|
||||||
run_solver town_100000 $1 town_100000 $3 $4 $5
|
|
||||||
run_solver town_500000 $1 town_500000 $3 $4 $5
|
|
||||||
run_solver town_1000000 $1 town_1000000 $3 $4 $5
|
|
||||||
}
|
|
||||||
|
|
||||||
run_all_graphs jt "jt "
|
|
||||||
|
|
@ -1,51 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
YAP=~/bin/town_ve
|
|
||||||
|
|
||||||
#OUT_FILE_NAME=results`date "+ %H:%M:%S %d-%m-%Y"`.log
|
|
||||||
OUT_FILE_NAME=ve.log
|
|
||||||
rm -f $OUT_FILE_NAME
|
|
||||||
rm -f ignore.$OUT_FILE_NAME
|
|
||||||
|
|
||||||
|
|
||||||
function run_solver
|
|
||||||
{
|
|
||||||
if [ $2 = bp ]
|
|
||||||
then
|
|
||||||
extra_flag1=clpbn_bp:set_solver_parameter\(run_mode,$4\)
|
|
||||||
extra_flag2=clpbn_bp:set_solver_parameter\(schedule,$5\)
|
|
||||||
extra_flag3=clpbn_bp:set_solver_parameter\(always_loopy_solver,$6\)
|
|
||||||
else
|
|
||||||
extra_flag1=true
|
|
||||||
extra_flag2=true
|
|
||||||
extra_flag3=true
|
|
||||||
fi
|
|
||||||
/usr/bin/time -o $OUT_FILE_NAME -a -f "real:%E\tuser:%U\tsys:%S" $YAP << EOF >> $OUT_FILE_NAME 2>> ignore.$OUT_FILE_NAME
|
|
||||||
[$1].
|
|
||||||
clpbn:set_clpbn_flag(solver,$2),
|
|
||||||
clpbn_bp:use_log_space,
|
|
||||||
$extra_flag1, $extra_flag2, $extra_flag3,
|
|
||||||
run_query(_R),
|
|
||||||
open("$OUT_FILE_NAME", 'append',S),
|
|
||||||
format(S, '$3: ~15+ ',[]),
|
|
||||||
close(S).
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function run_all_graphs
|
|
||||||
{
|
|
||||||
echo "*******************************************************************" >> "$OUT_FILE_NAME"
|
|
||||||
echo "results for solver $2" >> $OUT_FILE_NAME
|
|
||||||
echo "*******************************************************************" >> "$OUT_FILE_NAME"
|
|
||||||
run_solver town_1000 $1 town_1000 $3 $4 $5
|
|
||||||
run_solver town_5000 $1 town_5000 $3 $4 $5
|
|
||||||
run_solver town_10000 $1 town_10000 $3 $4 $5
|
|
||||||
run_solver town_50000 $1 town_50000 $3 $4 $5
|
|
||||||
run_solver town_100000 $1 town_100000 $3 $4 $5
|
|
||||||
run_solver town_500000 $1 town_500000 $3 $4 $5
|
|
||||||
run_solver town_1000000 $1 town_1000000 $3 $4 $5
|
|
||||||
}
|
|
||||||
|
|
||||||
run_all_graphs ve "ve "
|
|
||||||
|
|
@ -1,65 +0,0 @@
|
|||||||
|
|
||||||
conservative_city(City, Cons) :-
|
|
||||||
cons_table(City, ConsDist),
|
|
||||||
{ Cons = conservative_city(City) with p([y,n], ConsDist) }.
|
|
||||||
|
|
||||||
|
|
||||||
gender(X, Gender) :-
|
|
||||||
gender_table(X, GenderDist),
|
|
||||||
{ Gender = gender(X) with p([m,f], GenderDist) }.
|
|
||||||
|
|
||||||
|
|
||||||
hair_color(X, Color) :-
|
|
||||||
lives(X, City),
|
|
||||||
conservative_city(City, Cons),
|
|
||||||
hair_color_table(X,ColorTable),
|
|
||||||
{ Color = hair_color(X) with
|
|
||||||
p([t,f], ColorTable,[Cons]) }.
|
|
||||||
|
|
||||||
|
|
||||||
car_color(X, Color) :-
|
|
||||||
hair_color(X, HColor),
|
|
||||||
car_color_table(X,CColorTable),
|
|
||||||
{ Color = car_color(X) with
|
|
||||||
p([t,f], CColorTable,[HColor]) }.
|
|
||||||
|
|
||||||
|
|
||||||
height(X, Height) :-
|
|
||||||
gender(X, Gender),
|
|
||||||
height_table(X,HeightTable),
|
|
||||||
{ Height = height(X) with
|
|
||||||
p([t,f], HeightTable,[Gender]) }.
|
|
||||||
|
|
||||||
|
|
||||||
shoe_size(X, Shoesize) :-
|
|
||||||
height(X, Height),
|
|
||||||
shoe_size_table(X,ShoesizeTable),
|
|
||||||
{ Shoesize = shoe_size(X) with
|
|
||||||
p([t,f], ShoesizeTable,[Height]) }.
|
|
||||||
|
|
||||||
|
|
||||||
guilty(X, Guilt) :-
|
|
||||||
guilty_table(X, GuiltDist),
|
|
||||||
{ Guilt = guilty(X) with p([y,n], GuiltDist) }.
|
|
||||||
|
|
||||||
|
|
||||||
descn(X, Descn) :-
|
|
||||||
car_color(X, Car),
|
|
||||||
hair_color(X, Hair),
|
|
||||||
height(X, Height),
|
|
||||||
guilty(X, Guilt),
|
|
||||||
descn_table(X, DescTable),
|
|
||||||
{ Descn = descn(X) with
|
|
||||||
p([t,f], DescTable,[Car,Hair,Height,Guilt]) }.
|
|
||||||
|
|
||||||
|
|
||||||
witness(City, Witness) :-
|
|
||||||
descn(joe, DescnJ),
|
|
||||||
descn(p2, Descn2),
|
|
||||||
wit_table(WitTable),
|
|
||||||
{ Witness = witness(City) with
|
|
||||||
p([t,f], WitTable,[DescnJ, Descn2]) }.
|
|
||||||
|
|
||||||
|
|
||||||
:- ensure_loaded(tables).
|
|
||||||
|
|
@ -1,46 +0,0 @@
|
|||||||
|
|
||||||
cons_table(amsterdam, [0.2, 0.8]) :- !.
|
|
||||||
cons_table(_, [0.8, 0.2]).
|
|
||||||
|
|
||||||
|
|
||||||
gender_table(_, [0.55, 0.44]).
|
|
||||||
|
|
||||||
|
|
||||||
hair_color_table(_,
|
|
||||||
/* conservative_city */
|
|
||||||
/* y n */
|
|
||||||
[ 0.05, 0.1,
|
|
||||||
0.95, 0.9 ]).
|
|
||||||
|
|
||||||
|
|
||||||
car_color_table(_,
|
|
||||||
/* t f */
|
|
||||||
[ 0.9, 0.2,
|
|
||||||
0.1, 0.8 ]).
|
|
||||||
|
|
||||||
|
|
||||||
height_table(_,
|
|
||||||
/* m f */
|
|
||||||
[ 0.6, 0.4,
|
|
||||||
0.4, 0.6 ]).
|
|
||||||
|
|
||||||
|
|
||||||
shoe_size_table(_,
|
|
||||||
/* t f */
|
|
||||||
[ 0.9, 0.1,
|
|
||||||
0.1, 0.9 ]).
|
|
||||||
|
|
||||||
|
|
||||||
guilty_table(_, [0.23, 0.77]).
|
|
||||||
|
|
||||||
|
|
||||||
descn_table(_,
|
|
||||||
/* color, hair, height, guilt */
|
|
||||||
/* ttttt tttf ttft ttff tfttt tftf tfft tfff ttttt fttf ftft ftff ffttt fftf ffft ffff */
|
|
||||||
[ 0.99, 0.5, 0.23, 0.88, 0.41, 0.3, 0.76, 0.87, 0.44, 0.43, 0.29, 0.72, 0.33, 0.91, 0.95, 0.92,
|
|
||||||
0.01, 0.5, 0.77, 0.12, 0.59, 0.7, 0.24, 0.13, 0.56, 0.57, 0.61, 0.28, 0.77, 0.09, 0.05, 0.08]).
|
|
||||||
|
|
||||||
|
|
||||||
wit_table([0.2, 0.45, 0.24, 0.34,
|
|
||||||
0.8, 0.55, 0.76, 0.66]).
|
|
||||||
|
|
@ -1,59 +0,0 @@
|
|||||||
#!/home/tgomes/bin/yap -L --
|
|
||||||
|
|
||||||
/*
|
|
||||||
Steps:
|
|
||||||
1. generate N facts lives(I, nyc), 0 <= I < N.
|
|
||||||
2. generate evidence on descn for N people, *** except for 1 ***
|
|
||||||
3. Run query ?- guilty(joe, Guilty), witness(joe, t), descn(2,t), descn(3, f), descn(4, f) ...
|
|
||||||
*/
|
|
||||||
|
|
||||||
:- initialization(main).
|
|
||||||
|
|
||||||
|
|
||||||
main :-
|
|
||||||
unix(argv([H])),
|
|
||||||
generate_town(H).
|
|
||||||
|
|
||||||
|
|
||||||
generate_town(N) :-
|
|
||||||
atomic_concat(['town_', N, '.yap'], FileName),
|
|
||||||
open(FileName, 'write', S),
|
|
||||||
write(S, ':- source.\n'),
|
|
||||||
write(S, ':- style_check(all).\n'),
|
|
||||||
write(S, ':- yap_flag(unknown,error).\n'),
|
|
||||||
write(S, ':- yap_flag(write_strings,on).\n'),
|
|
||||||
write(S, ':- use_module(library(clpbn)).\n'),
|
|
||||||
write(S, ':- set_clpbn_flag(solver, bp).\n'),
|
|
||||||
write(S, ':- [-schema].\n\n'),
|
|
||||||
write(S, 'lives(_joe, nyc).\n'),
|
|
||||||
atom_number(N, N2),
|
|
||||||
generate_people(S, N2, 2),
|
|
||||||
write(S, '\nrun_query(Guilty) :- \n'),
|
|
||||||
write(S, '\tguilty(joe, Guilty),\n'),
|
|
||||||
write(S, '\twitness(nyc, t),\n'),
|
|
||||||
write(S, '\trunall(X, ev(X)).\n\n\n'),
|
|
||||||
write(S, 'runall(G, Wrapper) :-\n'),
|
|
||||||
write(S, '\tfindall(G, Wrapper, L),\n'),
|
|
||||||
write(S, '\texecute_all(L).\n\n\n'),
|
|
||||||
write(S, 'execute_all([]).\n'),
|
|
||||||
write(S, 'execute_all(G.L) :-\n'),
|
|
||||||
write(S, '\tcall(G),\n'),
|
|
||||||
write(S, '\texecute_all(L).\n\n\n'),
|
|
||||||
generate_query(S, N2, 2),
|
|
||||||
close(S).
|
|
||||||
|
|
||||||
|
|
||||||
generate_people(_, N, Counting1) :- !.
|
|
||||||
generate_people(S, N, Counting) :-
|
|
||||||
format(S, 'lives(p~w, nyc).~n', [Counting]),
|
|
||||||
Counting1 is Counting + 1,
|
|
||||||
generate_people(S, N, Counting1).
|
|
||||||
|
|
||||||
|
|
||||||
generate_query(S, N, Counting) :-
|
|
||||||
Counting > N, !.
|
|
||||||
generate_query(S, N, Counting) :- !,
|
|
||||||
format(S, 'ev(descn(p~w, t)).~n', [Counting]),
|
|
||||||
Counting1 is Counting + 1,
|
|
||||||
generate_query(S, N, Counting1).
|
|
||||||
|
|
@ -1,69 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="US-ASCII"?>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
|
|
||||||
A B
|
|
||||||
\ /
|
|
||||||
\ /
|
|
||||||
C
|
|
||||||
|
|
|
||||||
|
|
|
||||||
D
|
|
||||||
|
|
||||||
-->
|
|
||||||
|
|
||||||
|
|
||||||
<BIF VERSION="0.3">
|
|
||||||
<NETWORK>
|
|
||||||
<NAME>Simple Loop</NAME>
|
|
||||||
|
|
||||||
<VARIABLE TYPE="nature">
|
|
||||||
<NAME>A</NAME>
|
|
||||||
<OUTCOME>a1</OUTCOME>
|
|
||||||
<OUTCOME>a2</OUTCOME>
|
|
||||||
</VARIABLE>
|
|
||||||
|
|
||||||
<VARIABLE TYPE="nature">
|
|
||||||
<NAME>B</NAME>
|
|
||||||
<OUTCOME>b1</OUTCOME>
|
|
||||||
<OUTCOME>b2</OUTCOME>
|
|
||||||
</VARIABLE>
|
|
||||||
|
|
||||||
<VARIABLE TYPE="nature">
|
|
||||||
<NAME>C</NAME>
|
|
||||||
<OUTCOME>c1</OUTCOME>
|
|
||||||
<OUTCOME>c2</OUTCOME>
|
|
||||||
</VARIABLE>
|
|
||||||
|
|
||||||
<VARIABLE TYPE="nature">
|
|
||||||
<NAME>D</NAME>
|
|
||||||
<OUTCOME>d1</OUTCOME>
|
|
||||||
<OUTCOME>d2</OUTCOME>
|
|
||||||
</VARIABLE>
|
|
||||||
|
|
||||||
<DEFINITION>
|
|
||||||
<FOR>A</FOR>
|
|
||||||
<TABLE> .001 .009 </TABLE>
|
|
||||||
</DEFINITION>
|
|
||||||
|
|
||||||
<DEFINITION>
|
|
||||||
<FOR>B</FOR>
|
|
||||||
<TABLE> .002 .008 </TABLE>
|
|
||||||
</DEFINITION>
|
|
||||||
|
|
||||||
<DEFINITION>
|
|
||||||
<FOR>C</FOR>
|
|
||||||
<GIVEN>A</GIVEN>
|
|
||||||
<GIVEN>B</GIVEN>
|
|
||||||
<TABLE> .95 .05 .94 .06 .29 .71 .001 .999 </TABLE>
|
|
||||||
</DEFINITION>
|
|
||||||
|
|
||||||
<DEFINITION>
|
|
||||||
<FOR>D</FOR>
|
|
||||||
<GIVEN>C</GIVEN>
|
|
||||||
<TABLE> .9 .1 .05 .95 </TABLE>
|
|
||||||
</DEFINITION>
|
|
||||||
|
|
||||||
</NETWORK>
|
|
||||||
</BIF>
|
|
||||||
|
|
Reference in New Issue
Block a user