-/* Copyright (C) 2006-2008 Joris Mooij [j dot mooij at science dot ru dot nl]
- Radboud University Nijmegen, The Netherlands
-
+/* Copyright (C) 2006-2008 Joris Mooij [joris dot mooij at tuebingen dot mpg dot de]
+ Radboud University Nijmegen, The Netherlands /
+ Max Planck Institute for Biological Cybernetics, Germany
+
This file is part of libDAI.
libDAI is free software; you can redistribute it and/or modify
#include <map>
#include <set>
#include <dai/mf.h>
-#include <dai/diffs.h>
#include <dai/util.h>
const char *MF::Name = "MF";
-bool MF::checkProperties() {
- if( !HasProperty("tol") )
- return false;
- if (!HasProperty("maxiter") )
- return false;
- if (!HasProperty("verbose") )
- return false;
-
- ConvertPropertyTo<double>("tol");
- ConvertPropertyTo<size_t>("maxiter");
- ConvertPropertyTo<size_t>("verbose");
+void MF::setProperties( const PropertySet &opts ) {
+ assert( opts.hasKey("tol") );
+ assert( opts.hasKey("maxiter") );
+
+ props.tol = opts.getStringAs<double>("tol");
+ props.maxiter = opts.getStringAs<size_t>("maxiter");
+ if( opts.hasKey("verbose") )
+ props.verbose = opts.getStringAs<size_t>("verbose");
+ else
+ props.verbose = 0U;
+ if( opts.hasKey("damping") )
+ props.damping = opts.getStringAs<double>("damping");
+ else
+ props.damping = 0.0;
+}
+
- return true;
+PropertySet MF::getProperties() const {
+ PropertySet opts;
+ opts.Set( "tol", props.tol );
+ opts.Set( "maxiter", props.maxiter );
+ opts.Set( "verbose", props.verbose );
+ opts.Set( "damping", props.damping );
+ return opts;
}
-void MF::create() {
- // clear beliefs
- _beliefs.clear();
- _beliefs.reserve( nrVars() );
+string MF::printProperties() const {
+ stringstream s( stringstream::out );
+ s << "[";
+ s << "tol=" << props.tol << ",";
+ s << "maxiter=" << props.maxiter << ",";
+ s << "verbose=" << props.verbose << ",";
+ s << "damping=" << props.damping << "]";
+ return s.str();
+}
+
+void MF::construct() {
// create beliefs
+ _beliefs.clear();
+ _beliefs.reserve( nrVars() );
for( size_t i = 0; i < nrVars(); ++i )
- _beliefs.push_back(Factor(var(i)));
+ _beliefs.push_back( Factor( var(i) ) );
}
string MF::identify() const {
- stringstream result (stringstream::out);
- result << Name << GetProperties();
- return result.str();
+ return string(Name) + printProperties();
}
void MF::init() {
- assert( checkProperties() );
-
for( vector<Factor>::iterator qi = _beliefs.begin(); qi != _beliefs.end(); qi++ )
qi->fill(1.0);
}
double MF::run() {
double tic = toc();
- if( Verbose() >= 1 )
+ if( props.verbose >= 1 )
cout << "Starting " << identify() << "...";
size_t pass_size = _beliefs.size();
Diffs diffs(pass_size * 3, 1.0);
size_t t=0;
- for( t=0; t < (MaxIter()*pass_size) && diffs.maxDiff() > Tol(); t++ ) {
+ for( t=0; t < (props.maxiter*pass_size) && diffs.maxDiff() > props.tol; t++ ) {
// choose random Var i
size_t i = (size_t) (nrVars() * rnd_uniform());
henk *= _beliefs[j];
piet = factor(I).log0();
piet *= henk;
- piet = piet.part_sum(var(i));
+ piet = piet.partSum(var(i));
piet = piet.exp();
jan *= piet;
}
- jan.normalize( _normtype );
+ jan.normalize();
if( jan.hasNaNs() ) {
- cout << "MF::run(): ERROR: jan has NaNs!" << endl;
+ cout << Name << "::run(): ERROR: jan has NaNs!" << endl;
return 1.0;
}
+ if( props.damping != 0.0 )
+ jan = (jan^(1.0 - props.damping)) * (_beliefs[i]^props.damping);
diffs.push( dist( jan, _beliefs[i], Prob::DISTLINF ) );
_beliefs[i] = jan;
}
- updateMaxDiff( diffs.maxDiff() );
+ _iters = t / pass_size;
+ if( diffs.maxDiff() > _maxdiff )
+ _maxdiff = diffs.maxDiff();
- if( Verbose() >= 1 ) {
- if( diffs.maxDiff() > Tol() ) {
- if( Verbose() == 1 )
+ if( props.verbose >= 1 ) {
+ if( diffs.maxDiff() > props.tol ) {
+ if( props.verbose == 1 )
cout << endl;
- cout << "MF::run: WARNING: not converged within " << MaxIter() << " passes (" << toc() - tic << " clocks)...final maxdiff:" << diffs.maxDiff() << endl;
+ cout << Name << "::run: WARNING: not converged within " << props.maxiter << " passes (" << toc() - tic << " seconds)...final maxdiff:" << diffs.maxDiff() << endl;
} else {
- if( Verbose() >= 2 )
- cout << "MF::run: ";
- cout << "converged in " << t / pass_size << " passes (" << toc() - tic << " clocks)." << endl;
+ if( props.verbose >= 2 )
+ cout << Name << "::run: ";
+ cout << "converged in " << t / pass_size << " passes (" << toc() - tic << " seconds)." << endl;
}
}
}
-Factor MF::beliefV (size_t i) const {
+Factor MF::beliefV( size_t i ) const {
Factor piet;
piet = _beliefs[i];
- piet.normalize( Prob::NORMPROB );
+ piet.normalize();
return(piet);
}
Factor henk;
foreach( const Neighbor &j, nbF(I) ) // for all j in I
henk *= _beliefs[j];
- henk.normalize( Prob::NORMPROB );
+ henk.normalize();
Factor piet;
piet = factor(I).log0();
piet *= henk;