Exemple #1
0
std::map<STM::ParName, double> Metropolis::do_sample(int n, bool saveDeviance)
// n is the number of samples to take
// returns a map of acceptance rates keyed by parameter name
{
	// 	shuffle the order of parameters
	std::vector<STM::ParName> parNames (parameters.active_names());
	std::random_shuffle(parNames.begin(), parNames.end(), 
			[this](int n){ return gsl_rng_uniform_int(rng.get(), n); });
	
	std::map<STM::ParName, int> numAccepted;
	for(const auto & par : parNames)
		numAccepted[par] = 0;

	for(int i = 0; i < n; i++)
	{
		for(int j = 0; j < thinSize; j++)
		{
			// step through each parameter
			for(const auto & par : parNames) {
				STM::ParPair proposal = propose_parameter(par);
				numAccepted[par] += select_parameter(proposal);
			}
		}
		parameters.increment();
		currentSamples.push_back(parameters.current_state());
		if(saveDeviance)
			sampleDeviance.push_back(std::pair<double, int>(-2 * currentLL, 1));

		//		if desired, some debugging output
		if(outputLevel >= EngineOutputLevel::Verbose) {
			std::cerr << "  iteration " << parameters.iteration() - 1 << 
					"    posterior probability: " << currentPosteriorProb <<
					"    likelihood: " << currentLL << "\n";
			if(outputLevel >= EngineOutputLevel::ExtraVerbose) {
			std::ios_base::fmtflags oldflags = std::cerr.flags();
				std::streamsize oldprecision = std::cerr.precision();

				std::cerr << std::fixed << std::setprecision(3) << " ";
				STM::ParMap st = parameters.current_state();
				int coln = 0;
				for(auto pa : st) {
					std::cerr << std::setw(6) << pa.first << std::setw(8) << pa.second;
					if(++coln >= 7) {
						std::cerr << "\n ";
						coln = 0;
					}
				}
				std::cerr << std::endl;
			
				std::cerr.flags (oldflags);
				std::cerr.precision (oldprecision);
			}
		}
}

	std::map<STM::ParName, double> acceptanceRates;
	for(const auto & par : parNames)
		acceptanceRates[par] = double(numAccepted[par]) / (n*thinSize);
	return acceptanceRates;
}
Exemple #2
0
void Metropolis::regression_adapt(int numSteps, int stepSize)
{
	std::vector<STM::ParName> parNames (parameters.names());
	
	std::map<STM::ParName, std::map<std::string, double *> > regressionData;
	for(const auto & par : parNames)
	{
		regressionData[par]["log_variance"] = new double [numSteps];
		regressionData[par]["variance"] = new double [numSteps];
		regressionData[par]["acceptance"] = new double [numSteps];
	}
	
	for(int i = 0; i < numSteps; i++)
	{
		// compute acceptance rates for the current variance term
		parameters.set_acceptance_rates(do_sample(stepSize));
	
		for(const auto & par : parNames)
		{
			// save regression data for each parameter
			regressionData[par]["log_variance"][i] = std::log(parameters.sampler_variance(par));
			regressionData[par]["variance"][i] = parameters.sampler_variance(par);
			regressionData[par]["acceptance"][i] = parameters.acceptance_rate(par);
			
			// choose new variances at random for each parameter; drawn from a gamma with mean 2.38 and sd 2
			parameters.set_sampler_variance(par, gsl_ran_gamma(rng.get(), 1.4161, 1.680672));
		}
	
	}
	
	// perform regression for each parameter and clean up
	for(const auto & par : parNames)
	{
		// first compute the correlation for variance and log_variance, use whichever is higher
		double corVar = gsl_stats_correlation(regressionData[par]["variance"], 1,
				regressionData[par]["acceptance"], 1, numSteps);
		double corLogVar = gsl_stats_correlation(regressionData[par]["log_variance"], 1,
				regressionData[par]["acceptance"], 1, numSteps);

		double beta0, beta1, cov00, cov01, cov11, sumsq, targetVariance;
		if(corVar >= corLogVar)
		{
			gsl_fit_linear(regressionData[par]["variance"], 1, 
					regressionData[par]["acceptance"], 1, numSteps, &beta0, &beta1, 
					&cov00, &cov01, &cov11, &sumsq);
			targetVariance = (parameters.optimal_acceptance_rate() - beta0)/beta1;
		} else
		{
			gsl_fit_linear(regressionData[par]["log_variance"], 1, 
					regressionData[par]["acceptance"], 1, numSteps, &beta0, &beta1,
					&cov00, &cov01, &cov11, &sumsq);
			targetVariance = std::exp((parameters.optimal_acceptance_rate() - beta0)/beta1);
		}
		parameters.set_sampler_variance(par, targetVariance);

		delete [] regressionData[par]["log_variance"];
		delete [] regressionData[par]["variance"];
		delete [] regressionData[par]["acceptance"];
	}
}
Exemple #3
0
QString ScriptAdapterGenerator::funCodeGenerator(const QString&  filtername,const RichParameterSet& set) const
{
	QString code;
	code += "function (" + parNames(set) + ")\n";
	code += "{\n";
	code += "\tvar tmpRichPar = new IRichParameterSet();\n";
	code += "\tif (!_initParameterSet(\""+ filtername + "\",tmpRichPar)) return false;\n";
	for(int ii = 0; ii < set.paramList.size();++ii)
		code += "\ttmpRichPar.set" + set.paramList[ii]->val->typeName() + "(\"" + set.paramList[ii]->name + "\",arguments[" + QString::number(ii) + "]);\n";
	code += "\treturn _applyFilter(\"" + filtername + "\",tmpRichPar);\n";
	code += "};\n";
	return code;
}
Exemple #4
0
void Metropolis::auto_adapt()
{
	if(outputLevel >= EngineOutputLevel::Normal) 
	{
		std::cerr << timestamp() << " Starting automatic adaptation" << std::endl;
	}
	std::vector<STM::ParName> parNames (parameters.names());
	
	// disable thinning for the adaptation phase
	int oldThin = thinSize;
	thinSize = 1;
	
	regression_adapt(10, 100); // use the first two loops to try a regression approach	
	int nLoops = 2;
	
	while(nLoops < minAdaptationLoops or ((not parameters.adapted()) and nLoops < maxAdaptationLoops))	
	{
		nLoops++;
		parameters.set_acceptance_rates(do_sample(adaptationSampleSize));

		for(const auto & par : parNames) {
			double ratio;
			if(parameters.acceptance_rate(par) == 0) 
				ratio = 1e-2;
			else
				ratio = parameters.acceptance_rate(par) / parameters.optimal_acceptance_rate();
			parameters.set_sampler_variance(par, ratio*parameters.sampler_variance(par));
		}
		
		if(outputLevel >= EngineOutputLevel::Talkative) {
			std::cerr << "\n    " << timestamp() << " iter " << parameters.iteration() << "\n";
			parameters.print_adaptation(isatty(fileno(stderr)), 2);
// 			std::cerr << "    " << parameters.str_acceptance_rates(isatty(fileno(stderr))) << "\n";
// 			std::cerr << "    sampler variance:\n";
// 			std::cerr << "    " << parameters.str_sampling_variance(isatty(fileno(stderr))) << std::endl;
		}
		currentSamples.clear();
		if(saveResumeData)
			serialize_all();
	}
	parameters.reset(); // adaptation samples are not included in the burnin period
	if(outputLevel >= EngineOutputLevel::Normal) {
		std::cerr << timestamp() << " Adaptation completed successfully" << std::endl;
	}
	
	thinSize = oldThin;
}
Exemple #5
0
QString ScriptAdapterGenerator::funCodeGenerator( const QString& filterName,MLXMLPluginInfo& xmlInfo ) const
{
	QString code;
	QString names = parNames(filterName,xmlInfo);

	code += "function (" + names + ")\n";
	code += "{\n";
	MLXMLPluginInfo::XMLMapList mplist = xmlInfo.filterParametersExtendedInfo(filterName);
	if (names.indexOf(optName()) != -1)
	{
		QString defValues;
		for(int ii = 0;ii < mplist.size();++ii)
		{
			MLXMLPluginInfo::XMLMap mp = mplist[ii];
			if (mp[MLXMLElNames::paramIsImportant] == "false")
				defValues += mp[MLXMLElNames::paramName] + " : " + mp[MLXMLElNames::paramDefExpr] + ", ";
		}
		code += "\t" + optName() + " = __mergeOptions(" + optName() + ",{" + defValues + "});\n";
	}
	
	code += "\tvar environ = new Env;\n";

	QString ariet = xmlInfo.filterAttribute(filterName,MLXMLElNames::filterArity);
	bool isSingle = (ariet == MLXMLElNames::singleMeshArity);
	//if is singleMeshAriety i have to jump the first argument because is the meshID
	int arg = (int) isSingle;
	for(int ii = 0; ii < mplist.size();++ii)
	{
		MLXMLPluginInfo::XMLMap mp = mplist[ii];
		bool isenum = false;
		QString num = QString::number(ii);
		QString values = mp[MLXMLElNames::paramType];
		if (values.contains(MLXMLElNames::enumType))
		{
			QRegExp rem(MLXMLElNames::enumType + " \\{");
			values.remove(rem);
			rem.setPattern("\\}");
			values.remove(rem);
			MLXMLPluginInfo::XMLMap valuesMap = MLXMLPluginInfo::mapFromString(values,QRegExp("\\|"),QRegExp("\\:"));
			code += "\tfunction enumfun_" + num + "()\n\t{\t\n";
			for(MLXMLPluginInfo::XMLMap::iterator it = valuesMap.begin();it != valuesMap.end();++it)
			{
				code += "\t\tthis[\"" + it.key() + "\"] = " + it.value() + ";\n";
				code += "\t\tthis[parseInt(" + it.value() + ")] = \"" + it.key() + "\";\n";
			}
			code += "\t}\n";
			code += "\tfunction get_" + num + "(ff,ii)\n\t{\t\n";
			code += "\t\tif (typeof(ii) == \"number\") return ff[ff[ii]];\n";
			code += "\t\telse if (typeof(ii) == \"string\") return ff[ii];\n";
			code += "\t\t\telse return undefined;\n";
			code += "\t}\n";

			code += "\tvar enumtype_" + num + " = new enumfun_" + num + "();\n";
			isenum = true;
		}
		if (mp[MLXMLElNames::paramIsImportant] == "true")
		{
			QString argument =  "arguments[" + QString::number(arg) + "]";
			if (isenum)
			{
				code += "\tvar argenum_" + num + " = get_" + num + "(enumtype_" + num + "," + argument + ");\n";
				code += "\tenviron.insertExpressionBinding(\"" + mp[MLXMLElNames::paramName] + "\",argenum_" + num + ");\n";
			}
			else
				//code += "\tprint(" + argument + ");\n";
				code += "\tenviron.insertExpressionBinding(\"" + mp[MLXMLElNames::paramName] + "\"," + argument + ");\n";
			++arg;
		}
		else
		{
			if (isenum)
			{
				//code += "\tvar argenum_" + num + " = enumtype_" + num + "[" + argument + "];\n";
				code += "\tvar " + mp[MLXMLElNames::paramName] + " = get_" + num + "(enumtype_" + num + "," + optName() + "." + /*mp[MLXMLElNames::paramType] + "_" +*/ mp[MLXMLElNames::paramName] + ");\n";
				code += "\tenviron.insertExpressionBinding(\"" + mp[MLXMLElNames::paramName] + "\", " + mp[MLXMLElNames::paramName] + ");\n";
			}
			else
			{
				code += "\tvar " + mp[MLXMLElNames::paramName] + " = " + optName() + "." + /*mp[MLXMLElNames::paramType] + "_" +*/ mp[MLXMLElNames::paramName] + ";\n";
				code += "\tenviron.insertExpressionBinding(\"" + mp[MLXMLElNames::paramName] + "\", " + mp[MLXMLElNames::paramName] + ");\n";
			}
		}
	}
	code += "\tvar environWrap = new EnvWrap(environ);\n";
	if (isSingle)
	{
		code += "\tvar oldInd=" + meshDocVarName() + ".setCurrent(" + meshID() + ");\n";
		code += "\tif (oldInd == -1) return false;\n"; 
	}
	code += "\tvar result = _applyFilter(\"" + filterName + "\",environWrap);\n";
	if (isSingle)
		code += "\t" +meshDocVarName() + ".setCurrent(oldInd);\n";
	code += "\treturn result;\n";
	code += "};\n";
	return code;
}