Beispiel #1
0
    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);
    }