1 /* Copyright (C) 2006-2008 Joris Mooij [j dot mooij at science dot ru dot nl]
2 Radboud University Nijmegen, The Netherlands
4 This file is part of libDAI.
6 libDAI is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 libDAI is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with libDAI; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27 #include <dai/diffs.h>
37 const char *MF::Name
= "MF";
40 bool MF::checkProperties() {
41 if( !HasProperty("tol") )
43 if (!HasProperty("maxiter") )
45 if (!HasProperty("verbose") )
48 ConvertPropertyTo
<double>("tol");
49 ConvertPropertyTo
<size_t>("maxiter");
50 ConvertPropertyTo
<size_t>("verbose");
56 void MF::Regenerate() {
57 DAIAlgFG::Regenerate();
61 _beliefs
.reserve( nrVars() );
64 for( vector
<Var
>::const_iterator i
= vars().begin(); i
!= vars().end(); i
++ )
65 _beliefs
.push_back(Factor(*i
));
69 string
MF::identify() const {
70 stringstream
result (stringstream::out
);
71 result
<< Name
<< GetProperties();
77 assert( checkProperties() );
79 for( vector
<Factor
>::iterator qi
= _beliefs
.begin(); qi
!= _beliefs
.end(); qi
++ )
88 cout
<< "Starting " << identify() << "...";
90 size_t pass_size
= _beliefs
.size();
91 Diffs
diffs(pass_size
* 3, 1.0);
94 for( t
=0; t
< (MaxIter()*pass_size
) && diffs
.max() > Tol(); t
++ ) {
95 // choose random Var i
96 size_t i
= (size_t) (nrVars() * rnd_uniform());
100 for( _nb_cit I
= nb1(i
).begin(); I
!= nb1(i
).end(); I
++ ) {
103 for( _nb_cit j
= nb2(*I
).begin(); j
!= nb2(*I
).end(); j
++ ) // for all j in I \ i
105 henk
*= _beliefs
[*j
];
106 piet
= factor(*I
).log0();
108 piet
= piet
.part_sum(var(i
));
113 jan
.normalize( _normtype
);
115 if( jan
.hasNaNs() ) {
116 cout
<< "MF::run(): ERROR: jan has NaNs!" << endl
;
120 diffs
.push( dist( jan
, _beliefs
[i
], Prob::DISTLINF
) );
125 updateMaxDiff( diffs
.max() );
127 if( Verbose() >= 1 ) {
128 if( diffs
.max() > Tol() ) {
131 cout
<< "MF::run: WARNING: not converged within " << MaxIter() << " passes (" << toc() - tic
<< " clocks)...final maxdiff:" << diffs
.max() << endl
;
135 cout
<< "converged in " << t
/ pass_size
<< " passes (" << toc() - tic
<< " clocks)." << endl
;
143 Factor
MF::belief1 (size_t i
) const {
146 piet
.normalize( Prob::NORMPROB
);
151 Factor
MF::belief (const VarSet
&ns
) const {
153 return belief( *(ns
.begin()) );
155 assert( ns
.size() == 1 );
161 Factor
MF::belief (const Var
&n
) const {
162 return( belief1( findVar( n
) ) );
166 vector
<Factor
> MF::beliefs() const {
167 vector
<Factor
> result
;
168 for( size_t i
= 0; i
< nrVars(); i
++ )
169 result
.push_back( belief1(i
) );
174 Complex
MF::logZ() const {
177 for(size_t i
=0; i
< nrVars(); i
++ )
178 sum
-= belief1(i
).entropy();
179 for(size_t I
=0; I
< nrFactors(); I
++ ) {
181 for( _nb_cit j
= nb2(I
).begin(); j
!= nb2(I
).end(); j
++ ) // for all j in I
182 henk
*= _beliefs
[*j
];
183 henk
.normalize( Prob::NORMPROB
);
185 piet
= factor(I
).log0();
187 sum
-= Complex( piet
.totalSum() );
194 void MF::init( const VarSet
&ns
) {
195 for( size_t i
= 0; i
< nrVars(); i
++ ) {
197 _beliefs
[i
].fill( 1.0 );
202 } // end of namespace dai