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