new version of belief propagation solver.

This commit is contained in:
Vitor Santos Costa
2011-07-22 21:33:30 +01:00
parent a16a7d5b1c
commit 69e5fed10f
41 changed files with 3804 additions and 2238 deletions

View File

@@ -2,14 +2,15 @@
#define BP_SHARED_H
#include <cmath>
#include <iostream>
#include <fstream>
#include <cassert>
#include <vector>
#include <map>
#include <unordered_map>
// Macro to disallow the copy constructor and operator= functions
#include <iostream>
#include <fstream>
#include <iomanip>
#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
TypeName(const TypeName&); \
void operator=(const TypeName&)
@@ -19,61 +20,162 @@ using namespace std;
class Variable;
class BayesNode;
class FgVarNode;
class Factor;
class Link;
class Edge;
typedef double Param;
typedef vector<Param> ParamSet;
typedef vector<Param> Message;
typedef const ParamSet& CParamSet;
typedef unsigned Vid;
typedef vector<Vid> VidSet;
typedef const VidSet& CVidSet;
typedef vector<Variable*> VarSet;
typedef vector<BayesNode*> NodeSet;
typedef vector<BayesNode*> BnNodeSet;
typedef const BnNodeSet& CBnNodeSet;
typedef vector<FgVarNode*> FgVarSet;
typedef const FgVarSet& CFgVarSet;
typedef vector<Factor*> FactorSet;
typedef const FactorSet& CFactorSet;
typedef vector<Link*> LinkSet;
typedef const LinkSet& CLinkSet;
typedef vector<Edge*> EdgeSet;
typedef const EdgeSet& CEdgeSet;
typedef vector<string> Domain;
typedef vector<unsigned> DomainConf;
typedef pair<unsigned, unsigned> DomainConstr;
typedef unordered_map<unsigned, unsigned> IndexMap;
typedef vector<unsigned> DConf;
typedef pair<unsigned, unsigned> DConstraint;
typedef map<unsigned, unsigned> IndexMap;
//extern unsigned DL;
// level of debug information
static const unsigned DL = 0;
// number of digits to show when printing a parameter
static const unsigned PRECISION = 10;
static const int NO_EVIDENCE = -1;
// shared by bp and sp solver
enum Schedule
// number of digits to show when printing a parameter
static const unsigned PRECISION = 5;
static const bool EXPORT_TO_DOT = false;
static const unsigned EXPORT_MIN_SIZE = 30;
namespace SolverOptions
{
S_SEQ_FIXED,
S_SEQ_RANDOM,
S_PARALLEL,
S_MAX_RESIDUAL
enum Schedule
{
S_SEQ_FIXED,
S_SEQ_RANDOM,
S_PARALLEL,
S_MAX_RESIDUAL
};
extern bool runBayesBall;
extern bool convertBn2Fg;
extern bool compressFactorGraph;
extern Schedule schedule;
extern double accuracy;
extern unsigned maxIter;
}
namespace Util
{
void normalize (ParamSet&);
void pow (ParamSet&, unsigned);
double getL1dist (CParamSet, CParamSet);
double getMaxNorm (CParamSet, CParamSet);
bool isInteger (const string&);
string parametersToString (CParamSet);
vector<DConf> getDomainConfigurations (const VarSet&);
vector<string> getInstantiations (const VarSet&);
};
struct NetInfo
{
NetInfo (unsigned c, double t)
NetInfo (void)
{
counting = c;
solvingTime = t;
counting = 0;
nIters = 0;
solvingTime = 0.0;
}
unsigned counting;
double solvingTime;
unsigned nIters;
};
struct CompressInfo
{
CompressInfo (unsigned a, unsigned b, unsigned c,
unsigned d, unsigned e) {
nUncVars = a;
nUncFactors = b;
nCompVars = c;
nCompFactors = d;
nNeighborlessVars = e;
}
unsigned nUncVars;
unsigned nUncFactors;
unsigned nCompVars;
unsigned nCompFactors;
unsigned nNeighborlessVars;
};
typedef map<unsigned, NetInfo> StatisticMap;
class Statistics
{
public:
static void updateStats (unsigned size, double time)
static void updateStats (unsigned size, unsigned nIters, double time)
{
StatisticMap::iterator it = stats_.find(size);
StatisticMap::iterator it = stats_.find (size);
if (it == stats_.end()) {
stats_.insert (make_pair (size, NetInfo (1, 0.0)));
it = (stats_.insert (make_pair (size, NetInfo()))).first;
} else {
it->second.counting ++;
it->second.nIters += nIters;
it->second.solvingTime += time;
totalOfIterations += nIters;
if (nIters > maxIterations) {
maxIterations = nIters;
}
}
}
static void updateCompressingStats (unsigned nUncVars,
unsigned nUncFactors,
unsigned nCompVars,
unsigned nCompFactors,
unsigned nNeighborlessVars) {
compressInfo_.push_back (CompressInfo (
nUncVars, nUncFactors, nCompVars, nCompFactors, nNeighborlessVars));
}
static void printCompressingStats (const char* fileName)
{
ofstream out (fileName);
if (!out.is_open()) {
cerr << "error: cannot open file to write at " ;
cerr << "BayesNet::printCompressingStats()" << endl;
abort();
}
out << "--------------------------------------" ;
out << "--------------------------------------" << endl;
out << " Compression Stats" << endl;
out << "--------------------------------------" ;
out << "--------------------------------------" << endl;
out << left;
out << "Uncompress Compressed Uncompress Compressed Neighborless";
out << endl;
out << "Vars Vars Factors Factors Vars" ;
out << endl;
for (unsigned i = 0; i < compressInfo_.size(); i++) {
out << setw (13) << compressInfo_[i].nUncVars;
out << setw (13) << compressInfo_[i].nCompVars;
out << setw (13) << compressInfo_[i].nUncFactors;
out << setw (13) << compressInfo_[i].nCompFactors;
out << setw (13) << compressInfo_[i].nNeighborlessVars;
out << endl;
}
}
@@ -84,20 +186,12 @@ class Statistics
return it->second.counting;
}
static void updateIterations (unsigned nIters)
{
totalOfIterations += nIters;
if (nIters > maxIterations) {
maxIterations = nIters;
}
}
static void writeStats (void)
{
ofstream out ("../../stats.txt");
if (!out.is_open()) {
cerr << "error: cannot open file to write at " ;
cerr << "Statistics:::updateStats()" << endl;
cerr << "Statistics::updateStats()" << endl;
abort();
}
unsigned avgIterations = 0;
@@ -117,17 +211,24 @@ class Statistics
out << " average iterations: " << avgIterations << endl;
out << "total solving time " << totalSolvingTime << endl;
out << endl;
out << "Network Size\tCounting\tSolving Time\tAverage Time" << endl;
out << left << endl;
out << setw (15) << "Network Size" ;
out << setw (15) << "Counting" ;
out << setw (15) << "Solving Time" ;
out << setw (15) << "Average Time" ;
out << setw (15) << "#Iterations" ;
out << endl;
for (StatisticMap::iterator it = stats_.begin();
it != stats_.end(); it++) {
out << it->first;
out << "\t\t" << it->second.counting;
out << "\t\t" << it->second.solvingTime;
out << setw (15) << it->first;
out << setw (15) << it->second.counting;
out << setw (15) << it->second.solvingTime;
if (it->second.counting > 0) {
out << "\t\t" << it->second.solvingTime / it->second.counting;
out << setw (15) << it->second.solvingTime / it->second.counting;
} else {
out << "\t\t0.0" ;
out << setw (15) << "0.0" ;
}
out << setw (15) << it->second.nIters;
out << endl;
}
out.close();
@@ -142,62 +243,8 @@ class Statistics
static StatisticMap stats_;
static unsigned maxIterations;
static unsigned totalOfIterations;
static vector<CompressInfo> compressInfo_;
};
class Util
{
public:
static void normalize (ParamSet& v)
{
double sum = 0.0;
for (unsigned i = 0; i < v.size(); i++) {
sum += v[i];
}
assert (sum != 0.0);
for (unsigned i = 0; i < v.size(); i++) {
v[i] /= sum;
}
}
static double getL1dist (const ParamSet& v1, const ParamSet& v2)
{
assert (v1.size() == v2.size());
double dist = 0.0;
for (unsigned i = 0; i < v1.size(); i++) {
dist += abs (v1[i] - v2[i]);
}
return dist;
}
static double getMaxNorm (const ParamSet& v1, const ParamSet& v2)
{
assert (v1.size() == v2.size());
double max = 0.0;
for (unsigned i = 0; i < v1.size(); i++) {
double diff = abs (v1[i] - v2[i]);
if (diff > max) {
max = diff;
}
}
return max;
}
static bool isInteger (const string& s)
{
stringstream ss1 (s);
stringstream ss2;
int integer;
ss1 >> integer;
ss2 << integer;
return (ss1.str() == ss2.str());
}
};
//unsigned Statistics::totalOfIterations = 0;
#endif
#endif //BP_SHARED_H