150 lines
2.8 KiB
C++
150 lines
2.8 KiB
C++
|
#include <cassert>
|
||
|
#include <cmath>
|
||
|
|
||
|
#include <iostream>
|
||
|
|
||
|
#include "BPNodeInfo.h"
|
||
|
#include "BPSolver.h"
|
||
|
|
||
|
BPNodeInfo::BPNodeInfo (BayesNode* node)
|
||
|
{
|
||
|
node_ = node;
|
||
|
ds_ = node->getDomainSize();
|
||
|
piValsCalc_ = false;
|
||
|
ldValsCalc_ = false;
|
||
|
nPiMsgsRcv_ = 0;
|
||
|
nLdMsgsRcv_ = 0;
|
||
|
piVals_.resize (ds_, 1);
|
||
|
ldVals_.resize (ds_, 1);
|
||
|
const BnNodeSet& childs = node->getChilds();
|
||
|
for (unsigned i = 0; i < childs.size(); i++) {
|
||
|
cmsgs_.insert (make_pair (childs[i], false));
|
||
|
}
|
||
|
const BnNodeSet& parents = node->getParents();
|
||
|
for (unsigned i = 0; i < parents.size(); i++) {
|
||
|
pmsgs_.insert (make_pair (parents[i], false));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
ParamSet
|
||
|
BPNodeInfo::getBeliefs (void) const
|
||
|
{
|
||
|
double sum = 0.0;
|
||
|
ParamSet beliefs (ds_);
|
||
|
for (unsigned xi = 0; xi < ds_; xi++) {
|
||
|
double prod = piVals_[xi] * ldVals_[xi];
|
||
|
beliefs[xi] = prod;
|
||
|
sum += prod;
|
||
|
}
|
||
|
assert (sum);
|
||
|
//normalize the beliefs
|
||
|
for (unsigned xi = 0; xi < ds_; xi++) {
|
||
|
beliefs[xi] /= sum;
|
||
|
}
|
||
|
return beliefs;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
bool
|
||
|
BPNodeInfo::readyToSendPiMsgTo (const BayesNode* child) const
|
||
|
{
|
||
|
for (unsigned i = 0; i < inChildLinks_.size(); i++) {
|
||
|
if (inChildLinks_[i]->getSource() != child
|
||
|
&& !inChildLinks_[i]->messageWasSended()) {
|
||
|
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()) {
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
double
|
||
|
BPNodeInfo::getPiValue (unsigned idx) const
|
||
|
{
|
||
|
assert (idx >=0 && idx < ds_);
|
||
|
return piVals_[idx];
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
void
|
||
|
BPNodeInfo::setPiValue (unsigned idx, Param value)
|
||
|
{
|
||
|
assert (idx >=0 && idx < ds_);
|
||
|
piVals_[idx] = value;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
double
|
||
|
BPNodeInfo::getLambdaValue (unsigned idx) const
|
||
|
{
|
||
|
assert (idx >=0 && idx < ds_);
|
||
|
return ldVals_[idx];
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
void
|
||
|
BPNodeInfo::setLambdaValue (unsigned idx, Param value)
|
||
|
{
|
||
|
assert (idx >=0 && idx < ds_);
|
||
|
ldVals_[idx] = value;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
double
|
||
|
BPNodeInfo::getBeliefChange (void)
|
||
|
{
|
||
|
double change = 0.0;
|
||
|
if (oldBeliefs_.size() == 0) {
|
||
|
oldBeliefs_ = getBeliefs();
|
||
|
change = 9999999999.0;
|
||
|
} else {
|
||
|
ParamSet currentBeliefs = getBeliefs();
|
||
|
for (unsigned xi = 0; xi < ds_; xi++) {
|
||
|
change += abs (currentBeliefs[xi] - oldBeliefs_[xi]);
|
||
|
}
|
||
|
oldBeliefs_ = currentBeliefs;
|
||
|
}
|
||
|
return change;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
bool
|
||
|
BPNodeInfo::receivedBottomInfluence (void) const
|
||
|
{
|
||
|
// if all lambda values are equal, then neither
|
||
|
// this node neither its descendents have evidence,
|
||
|
// we can use this to don't send lambda messages his parents
|
||
|
bool childInfluenced = false;
|
||
|
for (unsigned xi = 1; xi < ds_; xi++) {
|
||
|
if (ldVals_[xi] != ldVals_[0]) {
|
||
|
childInfluenced = true;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
return childInfluenced;
|
||
|
}
|
||
|
|