void MH_Move::iterate(owned_ptr<Model>& P,MoveStats& Stats,int) { #ifndef NDEBUG clog<<" [MH] move = "<<name<<endl; #endif iterations++; owned_ptr<Model> P2 = P; double ratio = 1; try { ratio = (*proposal)(*P2); } catch (myexception& e) { std::ostringstream o; o<<" [MH] move = "<<name<<" (during proposal)\n"; e.prepend(o.str()); throw e; } int n = 1; Proposal2* p2 = dynamic_cast<Proposal2*>(&(*proposal)); int n_indices = -1; if (p2) { n_indices = p2->get_indices().size(); n = 2; } Result result(n); #ifndef NDEBUG show_parameters(std::cerr,*P); std::cerr<<P->probability()<<" = "<<P->likelihood()<<" + "<<P->prior()<<endl; std::cerr<<endl; show_parameters(std::cerr,*P2); std::cerr<<P2->probability()<<" = "<<P2->likelihood()<<" + "<<P2->prior(); std::cerr<<endl<<endl; #endif #ifndef NDEBUG // Check that we have not strayed outside the bounds. for(int i=0;i<P->n_parameters();i++) { if (not P->parameter_is_modifiable(i)) continue; if (not P->get_parameter_value(i).is_double()) continue; if (not P->has_bounds(i)) continue; Bounds<double> range = P->get_bounds(i); if (not range.in_range(P->get_parameter_value(i).as_double())) throw myexception()<<"Parameter "<<P->parameter_name(i)<<" = "<<P->get_parameter_value(i).as_double()<<" is NOT in range "<<range; if (not range.in_range(P2->get_parameter_value(i).as_double())) throw myexception()<<"Parameter "<<P->parameter_name(i)<<" = "<<P->get_parameter_value(i).as_double()<<" is NOT in range "<<range; } #endif // Accept or Reject if (accept_MH(*P,*P2,ratio)) { result.totals[0] = 1; if (n == 2) { int first_index = p2->get_indices()[0]; if (n_indices == 1 and P->get_parameter_value(first_index).is_double()) { double v1 = P->get_parameter_value(first_index).as_double(); double v2 = P2->get_parameter_value(first_index).as_double(); // cerr<<"v1 = "<<v1<<" v2 = "<<v2<<"\n"; result.totals[1] = std::abs(v2-v1); } else if (n_indices > 1 and P->get_parameter_value(first_index).is_double()) //currently this can only be a dirichlet proposal { double total = 0; for(int i=0;i<n_indices;i++) { int j = p2->get_indices()[i]; double v1 = P->get_parameter_value(j).as_double(); double v2 = P2->get_parameter_value(j).as_double(); total += std::abs(log(v1/v2)); } result.totals[1] = total; } } P = P2; } Stats.inc(name,result); }