Fixed tabs and trailing whitespaces
[libdai.git] / src / cbp.cpp
1 /* Copyright (C) 2009 Frederik Eaton [frederik at ofb dot net]
2
3 This file is part of libDAI.
4
5 libDAI is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 libDAI is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with libDAI; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20
21 #include <iostream>
22 #include <sstream>
23 #include <map>
24 #include <set>
25 #include <algorithm>
26
27 #include <dai/util.h>
28 #include <dai/properties.h>
29
30 #include <dai/bp.h>
31 #include <dai/cbp.h>
32 #include <dai/bbp.h>
33
34
35 namespace dai {
36
37
38 using namespace std;
39 using boost::shared_ptr;
40
41
42 const char *CBP::Name = "CBP";
43
44
45 void CBP::setBeliefs( const std::vector<Factor> &bs, double logZ ) {
46 size_t i = 0;
47 _beliefsV.clear();
48 _beliefsV.reserve( nrVars() );
49 _beliefsF.clear();
50 _beliefsF.reserve( nrFactors() );
51 for( i = 0; i < nrVars(); i++ )
52 _beliefsV.push_back( bs[i] );
53 for( ; i < nrVars() + nrFactors(); i++ )
54 _beliefsF.push_back( bs[i] );
55 _logZ = logZ;
56 }
57
58
59 void CBP::construct() {
60 _beliefsV.clear();
61 _beliefsV.reserve(nrVars());
62 for( size_t i = 0; i < nrVars(); i++ )
63 _beliefsV.push_back( Factor(var(i)).normalized() );
64
65 _beliefsF.clear();
66 _beliefsF.reserve(nrFactors());
67 for( size_t I = 0; I < nrFactors(); I++ ) {
68 Factor f = factor(I);
69 f.fill(1); f.normalize();
70 _beliefsF.push_back( f );
71 }
72
73 // to compute average level
74 _sum_level = 0;
75 _num_leaves = 0;
76
77 _maxdiff = 0;
78 _iters = 0;
79
80 if( props.clamp_outfile.length() > 0 ) {
81 _clamp_ofstream = shared_ptr<ofstream>(new ofstream( props.clamp_outfile.c_str(), ios_base::out|ios_base::trunc ));
82 *_clamp_ofstream << "# COUNT LEVEL VAR STATE" << endl;
83 }
84 }
85
86
87 /// Calculates a vector of mixtures p * b + (1-p) * c
88 static vector<Factor> mixBeliefs( Real p, const vector<Factor> &b, const vector<Factor> &c ) {
89 vector<Factor> out;
90 assert( b.size() == c.size() );
91 out.reserve( b.size() );
92 Real pc = 1 - p;
93 for( size_t i = 0; i < b.size(); i++ )
94 // probably already normalized, but do it again just in case
95 out.push_back( b[i].normalized() * p + c[i].normalized() * pc );
96 return out;
97 }
98
99
100 double CBP::run() {
101 size_t seed = props.rand_seed;
102 if( seed > 0)
103 rnd_seed( seed );
104
105 InfAlg *bp = getInfAlg();
106 bp->init();
107 bp->run();
108 _iters += bp->Iterations();
109
110 vector<Factor> beliefs_out;
111 Real lz_out;
112 size_t choose_count=0;
113 runRecurse( bp, bp->logZ(), vector<size_t>(0), _num_leaves, choose_count, _sum_level, lz_out, beliefs_out );
114 if( props.verbose >= 1 )
115 cerr << "CBP average levels = " << (_sum_level / _num_leaves) << ", leaves = " << _num_leaves << endl;
116 setBeliefs( beliefs_out, lz_out );
117 return 0.0;
118 }
119
120
121 /// \todo Eventually this allow other inference algorithms that BP to be selected, via a property
122 InfAlg* CBP::getInfAlg() {
123 PropertySet bpProps;
124 bpProps.Set("updates", props.updates);
125 bpProps.Set("tol", props.tol);
126 bpProps.Set("maxiter", props.maxiter);
127 bpProps.Set("verbose", props.verbose);
128 bpProps.Set("logdomain", false);
129 bpProps.Set("damping", 0.0);
130 BP *bp = new BP( *this, bpProps );
131 bp->recordSentMessages = true;
132 bp->init();
133 return bp;
134 }
135
136
137 void CBP::runRecurse( InfAlg *bp, double orig_logZ, vector<size_t> clamped_vars_list, size_t &num_leaves,
138 size_t &choose_count, double &sum_level, Real &lz_out, vector<Factor>& beliefs_out) {
139 // choose a variable/states to clamp:
140 size_t i;
141 vector<size_t> xis;
142 Real maxVar = 0.0;
143 bool found;
144 bool clampingVar = (Clamping() == Properties::ClampType::CLAMP_VAR);
145
146 if( Recursion() == Properties::RecurseType::REC_LOGZ && recTol() > 0 && exp( bp->logZ() - orig_logZ ) < recTol() )
147 found = false;
148 else
149 found = chooseNextClampVar( bp, clamped_vars_list, i, xis, &maxVar );
150
151 if( !found ) {
152 num_leaves++;
153 sum_level += clamped_vars_list.size();
154 beliefs_out = bp->beliefs();
155 lz_out = bp->logZ();
156 return;
157 }
158
159 choose_count++;
160 if( props.clamp_outfile.length() > 0 )
161 *_clamp_ofstream << choose_count << "\t" << clamped_vars_list.size() << "\t" << i << "\t" << xis[0] << endl;
162
163 if( clampingVar )
164 foreach( size_t xi, xis )
165 assert(/*0<=xi &&*/ xi < var(i).states() );
166 else
167 foreach( size_t xI, xis )
168 assert(/*0<=xI &&*/ xI < factor(i).states() );
169 // - otherwise, clamp and recurse, saving margin estimates for each
170 // clamp setting. afterwards, combine estimates.
171
172 // compute complement of 'xis'
173 vector<size_t> cmp_xis = complement( xis, clampingVar ? var(i).states() : factor(i).states() );
174
175 /// \todo could do this more efficiently with a nesting version of saveProbs/undoProbs
176 Real lz;
177 vector<Factor> b;
178 InfAlg *bp_c = bp->clone();
179 if( clampingVar ) {
180 bp_c->fg().clampVar( i, xis );
181 bp_c->init( var(i) );
182 } else {
183 bp_c->fg().clampFactor( i, xis );
184 bp_c->init( factor(i).vars() );
185 }
186 bp_c->run();
187 _iters += bp_c->Iterations();
188
189 lz = bp_c->logZ();
190 b = bp_c->beliefs();
191
192 Real cmp_lz;
193 vector<Factor> cmp_b;
194 InfAlg *cmp_bp_c = bp->clone();
195 if( clampingVar ) {
196 cmp_bp_c->fg().clampVar( i, cmp_xis );
197 cmp_bp_c->init(var(i));
198 } else {
199 cmp_bp_c->fg().clampFactor( i, cmp_xis );
200 cmp_bp_c->init( factor(i).vars() );
201 }
202 cmp_bp_c->run();
203 _iters += cmp_bp_c->Iterations();
204
205 cmp_lz = cmp_bp_c->logZ();
206 cmp_b = cmp_bp_c->beliefs();
207
208 double p = unSoftMax( lz, cmp_lz );
209 Real bp__d = 0.0;
210
211 if( Recursion() == Properties::RecurseType::REC_BDIFF && recTol() > 0 ) {
212 vector<Factor> combined_b( mixBeliefs( p, b, cmp_b ) );
213 Real new_lz = logSumExp( lz,cmp_lz );
214 bp__d = dist( bp->beliefs(), combined_b, nrVars() );
215 if( exp( new_lz - orig_logZ) * bp__d < recTol() ) {
216 num_leaves++;
217 sum_level += clamped_vars_list.size();
218 beliefs_out = combined_b;
219 lz_out = new_lz;
220 return;
221 }
222 }
223
224 // either we are not doing REC_BDIFF or the distance was large
225 // enough to recurse:
226 runRecurse( bp_c, orig_logZ, clamped_vars_list, num_leaves, choose_count, sum_level, lz, b );
227 runRecurse( cmp_bp_c, orig_logZ, clamped_vars_list, num_leaves, choose_count, sum_level, cmp_lz, cmp_b );
228
229 p = unSoftMax( lz, cmp_lz );
230
231 beliefs_out = mixBeliefs( p, b, cmp_b );
232 lz_out = logSumExp( lz, cmp_lz );
233
234 if( props.verbose >= 2 ) {
235 Real d = dist( bp->beliefs(), beliefs_out, nrVars() );
236 cerr << "Distance (clamping " << i << "): " << d;
237 if( Recursion() == Properties::RecurseType::REC_BDIFF )
238 cerr << "; bp_dual predicted " << bp__d;
239 cerr << "; max_adjoint = " << maxVar << "; logZ = " << lz_out << " (in " << bp->logZ() << ") (orig " << orig_logZ << "); p = " << p << "; level = " << clamped_vars_list.size() << endl;
240 }
241
242 delete bp_c;
243 delete cmp_bp_c;
244 }
245
246
247 // 'xis' must be sorted
248 bool CBP::chooseNextClampVar( InfAlg *bp, vector<size_t> &clamped_vars_list, size_t &i, vector<size_t> &xis, Real *maxVarOut ) {
249 Real tiny = 1.0e-14;
250 if( props.verbose >= 3 )
251 cerr << "clamped_vars_list" << clamped_vars_list << endl;
252 if( clamped_vars_list.size() >= maxClampLevel() )
253 return false;
254 if( ChooseMethod() == Properties::ChooseMethodType::CHOOSE_RANDOM ) {
255 if( Clamping() == Properties::ClampType::CLAMP_VAR ) {
256 int t = 0, t1 = 100;
257 do {
258 i = rnd( nrVars() );
259 t++;
260 } while( abs( bp->beliefV(i).p().max() - 1) < tiny && t < t1 );
261 if( t == t1 ) {
262 return false;
263 // die("Too many levels requested in CBP");
264 }
265 // only pick probable values for variable
266 size_t xi;
267 do {
268 xi = rnd( var(i).states() );
269 t++;
270 } while( bp->beliefV(i).p()[xi] < tiny && t < t1 );
271 assert( t < t1 );
272 xis.resize( 1, xi );
273 // assert(!_clamped_vars.count(i)); // not true for >2-ary variables
274 DAI_IFVERB(2, "CHOOSE_RANDOM at level " << clamped_vars_list.size() << " chose variable " << i << " state " << xis[0] << endl);
275 } else {
276 int t = 0, t1 = 100;
277 do {
278 i = rnd( nrFactors() );
279 t++;
280 } while( abs( bp->beliefF(i).p().max() - 1) < tiny && t < t1 );
281 if( t == t1 )
282 return false;
283 // die("Too many levels requested in CBP");
284 // only pick probable values for variable
285 size_t xi;
286 do {
287 xi = rnd( factor(i).states() );
288 t++;
289 } while( bp->beliefF(i).p()[xi] < tiny && t < t1 );
290 assert( t < t1 );
291 xis.resize( 1, xi );
292 // assert(!_clamped_vars.count(i)); // not true for >2-ary variables
293 DAI_IFVERB(2, endl<<"CHOOSE_RANDOM chose factor "<<i<<" state "<<xis[0]<<endl);
294 }
295 } else if( ChooseMethod() == Properties::ChooseMethodType::CHOOSE_MAXENT ) {
296 if( Clamping() == Properties::ClampType::CLAMP_VAR ) {
297 Real max_ent = -1.0;
298 int win_k = -1, win_xk = -1;
299 for( size_t k = 0; k < nrVars(); k++ ) {
300 Real ent=bp->beliefV(k).entropy();
301 if( max_ent < ent ) {
302 max_ent = ent;
303 win_k = k;
304 win_xk = bp->beliefV(k).p().argmax().first;
305 }
306 }
307 assert( win_k >= 0 );
308 assert( win_xk >= 0 );
309 i = win_k;
310 xis.resize( 1, win_xk );
311 DAI_IFVERB(2, endl<<"CHOOSE_MAXENT chose variable "<<i<<" state "<<xis[0]<<endl);
312 if( bp->beliefV(i).p()[xis[0]] < tiny ) {
313 DAI_IFVERB(2, "Warning: CHOOSE_MAXENT found unlikely state, not recursing");
314 return false;
315 }
316 } else {
317 Real max_ent = -1.0;
318 int win_k = -1, win_xk = -1;
319 for( size_t k = 0; k < nrFactors(); k++ ) {
320 Real ent = bp->beliefF(k).entropy();
321 if( max_ent < ent ) {
322 max_ent = ent;
323 win_k = k;
324 win_xk = bp->beliefF(k).p().argmax().first;
325 }
326 }
327 assert( win_k >= 0 );
328 assert( win_xk >= 0 );
329 i = win_k;
330 xis.resize( 1, win_xk );
331 DAI_IFVERB(2, endl<<"CHOOSE_MAXENT chose factor "<<i<<" state "<<xis[0]<<endl);
332 if( bp->beliefF(i).p()[xis[0]] < tiny ) {
333 DAI_IFVERB(2, "Warning: CHOOSE_MAXENT found unlikely state, not recursing");
334 return false;
335 }
336 }
337 } else if( ChooseMethod()==Properties::ChooseMethodType::CHOOSE_BP_L1 ||
338 ChooseMethod()==Properties::ChooseMethodType::CHOOSE_BP_CFN ) {
339 bool doL1 = (ChooseMethod() == Properties::ChooseMethodType::CHOOSE_BP_L1);
340 vector<size_t> state;
341 if( !doL1 && needGibbsState( BBP_cost_function() ) )
342 state = getGibbsState( *bp, 2*bp->Iterations() );
343 // try clamping each variable manually
344 assert( Clamping() == Properties::ClampType::CLAMP_VAR );
345 Real max_cost = 0.0;
346 int win_k = -1, win_xk = -1;
347 for( size_t k = 0; k < nrVars(); k++ ) {
348 for( size_t xk = 0; xk < var(k).states(); xk++ ) {
349 if( bp->beliefV(k)[xk] < tiny )
350 continue;
351 InfAlg *bp1 = bp->clone();
352 bp1->clamp( k, xk );
353 bp1->init( var(k) );
354 bp1->run();
355 Real cost = 0;
356 if( doL1 )
357 for( size_t j = 0; j < nrVars(); j++ )
358 cost += dist( bp->beliefV(j), bp1->beliefV(j), Prob::DISTL1 );
359 else
360 cost = getCostFn( *bp1, BBP_cost_function(), &state );
361 if( cost > max_cost || win_k == -1 ) {
362 max_cost = cost;
363 win_k = k;
364 win_xk = xk;
365 }
366 delete bp1;
367 }
368 }
369 assert( win_k >= 0 );
370 assert( win_xk >= 0 );
371 i = win_k;
372 xis.resize( 1, win_xk );
373 } else if( ChooseMethod() == Properties::ChooseMethodType::CHOOSE_BBP ) {
374 Real mvo;
375 if( !maxVarOut )
376 maxVarOut = &mvo;
377 bool clampingVar = (Clamping() == Properties::ClampType::CLAMP_VAR);
378 pair<size_t, size_t> cv = bbpFindClampVar( *bp, clampingVar, props.bbp_props, BBP_cost_function(), &mvo );
379
380 // if slope isn't big enough then don't clamp
381 if( mvo < minMaxAdj() )
382 return false;
383
384 size_t xi = cv.second;
385 i = cv.first;
386 #define VAR_INFO (clampingVar?"variable ":"factor ") \
387 << i << " state " << xi \
388 << " (p=" << (clampingVar?bp->beliefV(i)[xi]:bp->beliefF(i)[xi]) \
389 << ", entropy = " << (clampingVar?bp->beliefV(i):bp->beliefF(i)).entropy() \
390 << ", maxVar = "<< mvo << ")"
391 Prob b = ( clampingVar ? bp->beliefV(i).p() : bp->beliefF(i).p());
392 if( b[xi] < tiny ) {
393 cerr << "Warning, at level " << clamped_vars_list.size() << ", bbpFindClampVar found unlikely " << VAR_INFO << endl;
394 return false;
395 }
396 if( abs(b[xi] - 1) < tiny ) {
397 cerr << "Warning at level " << clamped_vars_list.size() << ", bbpFindClampVar found overly likely " << VAR_INFO << endl;
398 return false;
399 }
400
401 xis.resize( 1, xi );
402 if( clampingVar )
403 assert(/*0<=xi &&*/ xi < var(i).states() );
404 else
405 assert(/*0<=xi &&*/ xi < factor(i).states() );
406 DAI_IFVERB(2, "CHOOSE_BBP (num clamped = " << clamped_vars_list.size() << ") chose " << i << " state " << xi << endl);
407 } else
408 DAI_THROW(UNKNOWN_ENUM_VALUE);
409 clamped_vars_list.push_back( i );
410 return true;
411 }
412
413
414 void CBP::printDebugInfo() {
415 DAI_PV(_beliefsV);
416 DAI_PV(_beliefsF);
417 DAI_PV(_logZ);
418 }
419
420
421 //----------------------------------------------------------------
422
423
424 /** Function which takes a factor graph as input, runs Gibbs and BP_dual,
425 * creates and runs a BBP object, finds best variable, returns
426 * (variable,state) pair for clamping
427 */
428 pair<size_t, size_t> bbpFindClampVar( const InfAlg &in_bp, bool clampingVar, const PropertySet &bbp_props, bbp_cfn_t cfn, Real *maxVarOut ) {
429 BBP bbp( &in_bp, bbp_props );
430 initBBPCostFnAdj( bbp, in_bp, cfn, NULL );
431 bbp.run();
432
433 // find and return the (variable,state) with the largest adj_psi_V
434 size_t argmax_var = 0;
435 size_t argmax_var_state = 0;
436 Real max_var = 0;
437 if( clampingVar ) {
438 for( size_t i = 0; i < in_bp.fg().nrVars(); i++ ) {
439 Prob adj_psi_V = bbp.adj_psi_V(i);
440 if(0) {
441 // helps to account for amount of movement possible in variable
442 // i's beliefs? seems not..
443 adj_psi_V *= in_bp.beliefV(i).entropy();
444 }
445 if(0){
446 // adj_psi_V *= Prob(in_bp.fg().var(i).states(),1.0)-in_bp.beliefV(i).p();
447 adj_psi_V *= in_bp.beliefV(i).p();
448 }
449 // try to compensate for effect on same variable (doesn't work)
450 // adj_psi_V[gibbs.state()[i]] -= bp_dual.beliefV(i)[gibbs.state()[i]]/10;
451 pair<size_t,Real> argmax_state = adj_psi_V.argmax();
452
453 if( i == 0 || argmax_state.second > max_var ) {
454 argmax_var = i;
455 max_var = argmax_state.second;
456 argmax_var_state = argmax_state.first;
457 }
458 }
459 assert(/*0 <= argmax_var_state &&*/
460 argmax_var_state < in_bp.fg().var(argmax_var).states() );
461 } else {
462 for( size_t I = 0; I < in_bp.fg().nrFactors(); I++ ) {
463 Prob adj_psi_F = bbp.adj_psi_F(I);
464 if(0) {
465 // helps to account for amount of movement possible in variable
466 // i's beliefs? seems not..
467 adj_psi_F *= in_bp.beliefF(I).entropy();
468 }
469 // try to compensate for effect on same variable (doesn't work)
470 // adj_psi_V[gibbs.state()[i]] -= bp_dual.beliefV(i)[gibbs.state()[i]]/10;
471 pair<size_t,Real> argmax_state = adj_psi_F.argmax();
472
473 if( I == 0 || argmax_state.second > max_var ) {
474 argmax_var = I;
475 max_var = argmax_state.second;
476 argmax_var_state = argmax_state.first;
477 }
478 }
479 assert(/*0 <= argmax_var_state &&*/
480 argmax_var_state < in_bp.fg().factor(argmax_var).states() );
481 }
482 if( maxVarOut )
483 *maxVarOut = max_var;
484 return make_pair( argmax_var, argmax_var_state );
485 }
486
487
488 vector<size_t> complement( vector<size_t> &xis, size_t n_states ) {
489 vector<size_t> cmp_xis( 0 );
490 size_t j = 0;
491 for( size_t xi = 0; xi < n_states; xi++ ) {
492 while( j < xis.size() && xis[j] < xi )
493 j++;
494 if( j >= xis.size() || xis[j] > xi )
495 cmp_xis.push_back(xi);
496 }
497 assert( xis.size()+cmp_xis.size() == n_states );
498 return cmp_xis;
499 }
500
501
502 Real unSoftMax( Real a, Real b ) {
503 if( a > b )
504 return 1.0 / (1.0 + exp(b-a));
505 else
506 return exp(a-b) / (exp(a-b) + 1.0);
507 }
508
509
510 Real logSumExp( Real a, Real b ) {
511 if( a > b )
512 return a + log1p( exp( b-a ) );
513 else
514 return b + log1p( exp( a-b ) );
515 }
516
517
518 Real dist( const vector<Factor> &b1, const vector<Factor> &b2, size_t nv ) {
519 Real d = 0.0;
520 for( size_t k = 0; k < nv; k++ )
521 d += dist( b1[k], b2[k], Prob::DISTLINF );
522 return d;
523 }
524
525
526 } // end of namespace dai
527
528
529 /* {{{ GENERATED CODE: DO NOT EDIT. Created by
530 ./scripts/regenerate-properties include/dai/cbp.h src/cbp.cpp
531 */
532 namespace dai {
533
534 void CBP::Properties::set(const PropertySet &opts)
535 {
536 const std::set<PropertyKey> &keys = opts.allKeys();
537 std::set<PropertyKey>::const_iterator i;
538 for(i=keys.begin(); i!=keys.end(); i++) {
539 if(*i == "verbose") continue;
540 if(*i == "tol") continue;
541 if(*i == "updates") continue;
542 if(*i == "maxiter") continue;
543 if(*i == "rec_tol") continue;
544 if(*i == "max_levels") continue;
545 if(*i == "min_max_adj") continue;
546 if(*i == "choose") continue;
547 if(*i == "recursion") continue;
548 if(*i == "clamp") continue;
549 if(*i == "bbp_props") continue;
550 if(*i == "bbp_cfn") continue;
551 if(*i == "rand_seed") continue;
552 if(*i == "clamp_outfile") continue;
553 DAI_THROWE(UNKNOWN_PROPERTY_TYPE, "CBP: Unknown property " + *i);
554 }
555 if(!opts.hasKey("tol"))
556 DAI_THROWE(NOT_ALL_PROPERTIES_SPECIFIED,"CBP: Missing property \"tol\" for method \"CBP\"");
557 if(!opts.hasKey("updates"))
558 DAI_THROWE(NOT_ALL_PROPERTIES_SPECIFIED,"CBP: Missing property \"updates\" for method \"CBP\"");
559 if(!opts.hasKey("maxiter"))
560 DAI_THROWE(NOT_ALL_PROPERTIES_SPECIFIED,"CBP: Missing property \"maxiter\" for method \"CBP\"");
561 if(!opts.hasKey("rec_tol"))
562 DAI_THROWE(NOT_ALL_PROPERTIES_SPECIFIED,"CBP: Missing property \"rec_tol\" for method \"CBP\"");
563 if(!opts.hasKey("min_max_adj"))
564 DAI_THROWE(NOT_ALL_PROPERTIES_SPECIFIED,"CBP: Missing property \"min_max_adj\" for method \"CBP\"");
565 if(!opts.hasKey("choose"))
566 DAI_THROWE(NOT_ALL_PROPERTIES_SPECIFIED,"CBP: Missing property \"choose\" for method \"CBP\"");
567 if(!opts.hasKey("recursion"))
568 DAI_THROWE(NOT_ALL_PROPERTIES_SPECIFIED,"CBP: Missing property \"recursion\" for method \"CBP\"");
569 if(!opts.hasKey("clamp"))
570 DAI_THROWE(NOT_ALL_PROPERTIES_SPECIFIED,"CBP: Missing property \"clamp\" for method \"CBP\"");
571 if(!opts.hasKey("bbp_props"))
572 DAI_THROWE(NOT_ALL_PROPERTIES_SPECIFIED,"CBP: Missing property \"bbp_props\" for method \"CBP\"");
573 if(!opts.hasKey("bbp_cfn"))
574 DAI_THROWE(NOT_ALL_PROPERTIES_SPECIFIED,"CBP: Missing property \"bbp_cfn\" for method \"CBP\"");
575 if(opts.hasKey("verbose")) {
576 verbose = opts.getStringAs<size_t>("verbose");
577 } else {
578 verbose = 0;
579 }
580 tol = opts.getStringAs<double>("tol");
581 updates = opts.getStringAs<UpdateType>("updates");
582 maxiter = opts.getStringAs<size_t>("maxiter");
583 rec_tol = opts.getStringAs<double>("rec_tol");
584 if(opts.hasKey("max_levels")) {
585 max_levels = opts.getStringAs<size_t>("max_levels");
586 } else {
587 max_levels = 10;
588 }
589 min_max_adj = opts.getStringAs<double>("min_max_adj");
590 choose = opts.getStringAs<ChooseMethodType>("choose");
591 recursion = opts.getStringAs<RecurseType>("recursion");
592 clamp = opts.getStringAs<ClampType>("clamp");
593 bbp_props = opts.getStringAs<PropertySet>("bbp_props");
594 bbp_cfn = opts.getStringAs<bbp_cfn_t>("bbp_cfn");
595 if(opts.hasKey("rand_seed")) {
596 rand_seed = opts.getStringAs<size_t>("rand_seed");
597 } else {
598 rand_seed = 0;
599 }
600 if(opts.hasKey("clamp_outfile")) {
601 clamp_outfile = opts.getStringAs<std::string>("clamp_outfile");
602 } else {
603 clamp_outfile = "";
604 }
605 }
606 PropertySet CBP::Properties::get() const {
607 PropertySet opts;
608 opts.Set("verbose", verbose);
609 opts.Set("tol", tol);
610 opts.Set("updates", updates);
611 opts.Set("maxiter", maxiter);
612 opts.Set("rec_tol", rec_tol);
613 opts.Set("max_levels", max_levels);
614 opts.Set("min_max_adj", min_max_adj);
615 opts.Set("choose", choose);
616 opts.Set("recursion", recursion);
617 opts.Set("clamp", clamp);
618 opts.Set("bbp_props", bbp_props);
619 opts.Set("bbp_cfn", bbp_cfn);
620 opts.Set("rand_seed", rand_seed);
621 opts.Set("clamp_outfile", clamp_outfile);
622 return opts;
623 }
624 string CBP::Properties::toString() const {
625 stringstream s(stringstream::out);
626 s << "[";
627 s << "verbose=" << verbose << ",";
628 s << "tol=" << tol << ",";
629 s << "updates=" << updates << ",";
630 s << "maxiter=" << maxiter << ",";
631 s << "rec_tol=" << rec_tol << ",";
632 s << "max_levels=" << max_levels << ",";
633 s << "min_max_adj=" << min_max_adj << ",";
634 s << "choose=" << choose << ",";
635 s << "recursion=" << recursion << ",";
636 s << "clamp=" << clamp << ",";
637 s << "bbp_props=" << bbp_props << ",";
638 s << "bbp_cfn=" << bbp_cfn << ",";
639 s << "rand_seed=" << rand_seed << ",";
640 s << "clamp_outfile=" << clamp_outfile;
641 s << "]";
642 return s.str();
643 }
644 } // end of namespace dai
645 /* }}} END OF GENERATED CODE */