Example #1
0
void DifferentialEvolution::initialize_population(RunManagerAbstract &run_manager, int d)
{
	ostream &fout_restart = file_manager.get_ofstream("rst");
	int iter = 0;

	RestartController::write_start_iteration(fout_restart, solver_type_name, iter, iter);
	Parameters ctl_pars;
	for (int i = 0; i < d; ++i)
	{
		ctl_pars.clear();
		initialize_vector(ctl_pars);
		par_transform.ctl2model_ip(ctl_pars);
		run_manager.add_run(ctl_pars);
	}
	RestartController::write_upgrade_runs_built(fout_restart);
	// make innitial population vector model runs
	cout << endl;
	cout << "  performing initial population model runs... ";
	cout.flush();
	run_manager.run();
	gen_1.copy(run_manager.get_runstorage_ref());

	// get the best_run to track phi
	int r_status;
	int n_par = par_list.size();
	best_phi = std::numeric_limits<double>::max();

	Parameters tmp_pars;
	Observations tmp_obs;
	ModelRun tmp_run(obj_func_ptr);
	for (int i_run = 0; i_run < d; ++i_run)
	{
		bool r_status = gen_1.get_run(i_run, tmp_pars, tmp_obs);
		if (r_status > 0)
		{
			par_transform.model2ctl_ip(tmp_pars);
			tmp_run.update_ctl(tmp_pars, tmp_obs);
			double tmp_phi = tmp_run.get_phi(DynamicRegularization::get_unit_reg_instance());
			if (tmp_phi < best_phi)
			{
				best_phi = tmp_phi;
				best_run_idx = i_run;
			}
		}
	}

}
Example #2
0
void DifferentialEvolution::solve(RunManagerAbstract &run_manager,
	RestartController &restart_controller,
	int max_gen, double f, double cr, bool dither_f, ModelRun &cur_run)
{
	ostream &os = file_manager.rec_ofstream();
	ostream &fout_restart = file_manager.get_ofstream("rst");

	for (int iter = 0; iter < max_gen && best_phi > std::numeric_limits<double>::min(); ++iter)
	{
		RestartController::write_start_iteration(fout_restart, solver_type_name, iter+1, iter+1);

		Parameters tmp_pars;
		Observations tmp_obs;

		// write header for iteration
		cout << endl;
		output_file_writer.iteration_report(cout, iter+1, run_manager.get_total_runs(), "differntial evolution");
		os << endl;
		output_file_writer.iteration_report(os, iter + 1, run_manager.get_total_runs(), "differntial evolution");
		// write initial phi report for this iteration
		bool run_target_ok = gen_1.get_run(best_run_idx, tmp_pars, tmp_obs);
		par_transform.model2ctl_ip(tmp_pars);
		map<string, double> phi_comps = obj_func_ptr->phi_report(tmp_obs, tmp_pars, DynamicRegularization::get_unit_reg_instance());
		output_file_writer.phi_report(cout, iter, run_manager.get_nruns(), phi_comps, DynamicRegularization::get_unit_reg_instance().get_weight(), false);
		output_file_writer.phi_report(os, iter, run_manager.get_nruns(), phi_comps, DynamicRegularization::get_unit_reg_instance().get_weight(), false);

		run_manager.reinitialize();
		mutation(run_manager, f, dither_f, cr);
		RestartController::write_upgrade_runs_built(fout_restart);
		// make trial vector model runs
		cout << endl;
		cout << "  performing trial vector model runs... ";
		cout.flush();
		run_manager.run();
		os << endl;
		best_run_idx = recombination(run_manager);
		os << endl;
	
		run_target_ok = gen_1.get_run(best_run_idx, tmp_pars, tmp_obs);
		par_transform.model2ctl_ip(tmp_pars);
		// write parameter file for this iteration
		output_file_writer.write_par(file_manager.open_ofile_ext("par"), tmp_pars, *(par_transform.get_offset_ptr()),
			*(par_transform.get_scale_ptr()));
		file_manager.close_file("par");
		// write final phi report for this iteration
		phi_comps = obj_func_ptr->phi_report(tmp_obs, tmp_pars, DynamicRegularization::get_unit_reg_instance());
		output_file_writer.phi_report(cout, iter, run_manager.get_nruns(), phi_comps, DynamicRegularization::get_unit_reg_instance().get_weight(), true);
		cout << endl;
		output_file_writer.phi_report(os, iter, run_manager.get_nruns(), phi_comps, DynamicRegularization::get_unit_reg_instance().get_weight(), true);
		os << endl;
	}
}
Example #3
0
bool Jacobian_1to1::calculate(ModelRun &init_model_run, vector<string> numeric_par_names, vector<string> obs_names, ParamTransformSeq &par_transform,
		const ParameterGroupInfo &group_info, const ParameterInfo &ctl_par_info, 
		RunManagerAbstract &run_manager, const PriorInformation &prior_info, set<string> &out_of_bound_par, bool phiredswh_flag, bool calc_init_obs)
{
	int i_run;
	string *par_name;
	double par_value;
	Parameters model_parameters(par_transform.ctl2model_cp(init_model_run.get_ctl_pars()));
	Observations observations(init_model_run.get_obs_template());
	base_numeric_parameters = par_transform.ctl2numeric_cp( init_model_run.get_ctl_pars());
	run_manager.reinitialize(file_manager.build_filename("rnj"));
	const vector<string> &model_par_name_vec = run_manager.get_par_name_vec();
	const vector<string> &obs_name_vec = run_manager.get_obs_name_vec();
	size_t n_par = model_par_name_vec.size();

	failed_parameter_names.clear();
	// compute runs for to jacobain calculation as it is influenced by derivative type( forward or central)
	vector<JacobianRun> del_numeric_par_vec;
	if (calc_init_obs) {
		del_numeric_par_vec.push_back(JacobianRun("", 0));
		run_manager.add_run(model_parameters);
	}
	Parameters new_derivative_pars;
	bool success;
	Parameters base_derivative_parameters = par_transform.numeric2derivative_cp(base_numeric_parameters);
	//Loop through derivative parameters and build the parameter sets necessary for computing the jacobian
	for (auto &i_name : numeric_par_names)
	{
		assert(base_derivative_parameters.find(i_name) != base_derivative_parameters.end());
		vector<JacobianRun> tmp_del_numeric_par_vec;
		double derivative_par_value = base_derivative_parameters.get_rec(i_name);
		success = get_derivative_parameters(i_name, derivative_par_value, par_transform, group_info, ctl_par_info,
			tmp_del_numeric_par_vec, phiredswh_flag);
		if (success && !tmp_del_numeric_par_vec.empty())
		{
			del_numeric_par_vec.insert(del_numeric_par_vec.end(), tmp_del_numeric_par_vec.begin(), tmp_del_numeric_par_vec.end());
			// update changed model parameters in model_parameters
			for (const auto &par : tmp_del_numeric_par_vec)
			{
				Parameters org_pars;
				Parameters new_pars;
				org_pars.insert(make_pair(par.par_name, model_parameters.get_rec(par.par_name)));
				new_pars.insert(make_pair(par.par_name, par.numeric_value));
				par_transform.derivative2model_ip(new_pars);
				for (auto &ipar : new_pars)
				{
					model_parameters[ipar.first] = ipar.second;
				}
				run_manager.add_run(model_parameters);
				for (const auto &ipar : org_pars)
				{
					model_parameters[ipar.first] = ipar.second;
				}
			}
		}
		else 
		{
			failed_parameter_names.insert(i_name);
		}
	}
	ofstream &fout_restart = file_manager.get_ofstream("rst");
	fout_restart << "jacobian_model_runs_begin_group_id " << run_manager.get_cur_groupid() << endl;
	// make model runs
	run_manager.run();
	fout_restart << "jacobian_model_runs_end_group_id " << run_manager.get_cur_groupid() << endl;

	// calculate jacobian
	base_sim_obs_names = obs_names;

	if(matrix.rows() != base_sim_obs_names.size() || matrix.cols() !=numeric_par_names.size())
	{
		matrix.resize(base_sim_obs_names.size(), numeric_par_names.size());
	}
	// initialize prior information
	prior_info_sen.clear();

	unordered_map<string, int> par2col_map = get_par2col_map();
	unordered_map<string, int>::iterator found;
	unordered_map<string, int>::iterator not_found = par2col_map.end();

	i_run = 0;
	// if initial run was performed, get the newly calculated values

	if (calc_init_obs) {
		Parameters tmp_pars;
		Observations tmp_obs;
		bool success = run_manager.get_run(i_run, tmp_pars, tmp_obs);
		if (!success)
		{
			throw(PestError("Error: Base parameter run failed.  Can not compute the Jacobian"));
		}
		par_transform.model2ctl_ip(tmp_pars);
		init_model_run.update_ctl(tmp_pars, tmp_obs);
		++i_run;
	}

	base_numeric_parameters =  par_transform.ctl2numeric_cp(init_model_run.get_ctl_pars());
	// process the parameter pertubation runs
	int nruns = del_numeric_par_vec.size();
	list<pair<ModelRun, double> > run_list;
	base_numeric_par_names.clear();
	ModelRun tmp_model_run = init_model_run;
	int icol = 0;
	vector<string>par_name_vec;
	for(; i_run<nruns; ++i_run)
	{
		par_name = &del_numeric_par_vec[i_run].par_name;
		Parameters tmp_pars;
		Observations tmp_obs;
		bool success = run_manager.get_run(i_run, tmp_pars, tmp_obs);
		if (success)
		{

			par_name_vec.clear();
			par_name_vec.push_back(*par_name);
			par_transform.model2ctl_ip(tmp_pars);
			tmp_model_run.update_ctl(tmp_pars, tmp_obs);
			Parameters numeric_pars(tmp_pars, par_name_vec);
			par_transform.ctl2numeric_ip(numeric_pars);
			par_value = numeric_pars.get_rec(*par_name);
			run_list.push_back(make_pair(tmp_model_run, par_value));
		}

		if(i_run+1>=nruns || *par_name !=  del_numeric_par_vec[i_run+1].par_name)
		{
			if (!run_list.empty())
			{
				base_numeric_par_names.push_back(*par_name);
				double base_numeric_par_value = base_numeric_parameters.get_rec(*par_name);
				run_list.push_front(make_pair(init_model_run, base_numeric_par_value));
				calc_derivative(*par_name, icol, run_list, par_transform, group_info, ctl_par_info, prior_info);
				icol++;
			}
			else
			{
				failed_parameter_names.insert(*par_name);
			}
			run_list.clear();
		}
	}
	matrix.conservativeResize(base_sim_obs_names.size(), base_numeric_par_names.size());
	// clean up
	fout_restart << "jacobian_saved" << endl;
	run_manager.free_memory();
	return true;
}
Example #4
0
int DifferentialEvolution::recombination(RunManagerAbstract &run_manager)
{
	ostream &os = file_manager.rec_ofstream();

	int best_run_idx = 0;
	ModelRun run_target(obj_func_ptr);
	ModelRun run_canidate(obj_func_ptr);
	Parameters tmp_pars_targ;
	Observations tmp_obs_targ;
	Parameters tmp_pars_can;
	Observations tmp_obs_can;

	best_phi = std::numeric_limits<double>::max();

	int d = gen_1.get_nruns();
	int n_good_runs_targ = gen_1.get_num_good_runs();
	int n_good_runs_can = run_manager.get_num_good_runs();
	double phi_sum_targ = 0.0;
	double phi_sum_can = 0.0;
	double phi_sum_new = 0.0;
	double phi_max_targ = 0.0;
	double phi_max_can = 0.0;
	double phi_max_new = 0.0;
	double phi_min_targ = std::numeric_limits<double>::max();
	double phi_min_can = std::numeric_limits<double>::max();
	double phi_min_new = std::numeric_limits<double>::max();

	os << "  population phi values:" << endl;
	os << "              parent         canidate" << endl;
	os << "    id        phi            phi" << endl;
	os << "    ----     ---------      ---------" << endl;
	for (int i_run = 0; i_run < d; ++i_run)
	{
		double new_phi = std::numeric_limits<double>::max();
		bool run_target_ok = gen_1.get_run(i_run, tmp_pars_targ, tmp_obs_targ);
		bool  run_canidate_ok = run_manager.get_run(i_run, tmp_pars_can, tmp_obs_can);
		if (!run_canidate_ok && !run_target_ok)
		{
			//keep current target
			new_phi = std::numeric_limits<double>::max();
			++failed_runs_old;
			++failed_runs_new;
			os << "    " << left << setw(10) << i_run << setw(15) << "N/A" << setw(15) << "N/A";
			os << endl;

		}
		else if (!run_canidate_ok)
		{
			//keep current target
			++failed_runs_new;
			par_transform.model2ctl_ip(tmp_pars_targ);
			// compute phi
			run_target.update_ctl(tmp_pars_targ, tmp_obs_targ);
			double phi_target = run_target.get_phi(DynamicRegularization::get_unit_reg_instance());
			phi_sum_targ += phi_target;
			phi_sum_new += phi_target;
			phi_min_targ = min(phi_min_targ, phi_target);
			phi_max_targ = max(phi_max_targ, phi_target);
			os << "    " << left << setw(10) << i_run << setw(15) << phi_target << setw(15) << "N/A";
			os << endl;
		}
		else if (!run_target_ok)
		{
			gen_1.update_run(i_run, tmp_pars_can, tmp_obs_can);
			// compute phi
			par_transform.model2ctl_ip(tmp_pars_can);
			run_canidate.update_ctl(tmp_pars_can, tmp_obs_can);
			new_phi = run_canidate.get_phi(DynamicRegularization::get_unit_reg_instance());
			++failed_runs_old;
			phi_sum_can += new_phi;
			phi_sum_new += new_phi;
			phi_min_can = min(phi_min_targ, new_phi);
			phi_max_can = max(phi_max_targ, new_phi);
			os << "    " << left << setw(10) << i_run << setw(15) << "N/A" << setw(15) << new_phi;
			os << endl;
		}
		else
		{
			// process target parameters and observations
			par_transform.model2ctl_ip(tmp_pars_targ);
			run_target.update_ctl(tmp_pars_targ, tmp_obs_targ);
			double phi_target = run_target.get_phi(DynamicRegularization::get_unit_reg_instance());
			//process canidate parameters and observations
			par_transform.model2ctl_ip(tmp_pars_can);
			run_canidate.update_ctl(tmp_pars_can, tmp_obs_can);
			double phi_canidate = run_canidate.get_phi(DynamicRegularization::get_unit_reg_instance());
			new_phi = min(phi_target, phi_canidate);
			os << "    " << left << setw(10) << i_run;
			os << setw(15) << phi_target;
			os << setw(15) << phi_canidate;
			os << endl;
			if (phi_canidate < phi_target)
			{
				gen_1.update_run(i_run, tmp_pars_can, tmp_obs_can);
			}
			phi_sum_targ += phi_target;
			phi_sum_can += phi_canidate;
			phi_sum_new += new_phi;
			phi_min_can = min(phi_min_can, phi_canidate);
			phi_max_can = max(phi_max_can, phi_canidate);
			phi_min_targ = min(phi_min_targ, phi_target);
			phi_max_targ = max(phi_max_targ, phi_target);

		}
		phi_min_new = min(phi_min_new, new_phi);
		phi_max_new = max(phi_max_new, new_phi);
		if (new_phi < best_phi)
		{
			best_phi = new_phi;
			best_run_idx = i_run;
		}
	}
	double phi_avg_targ = std::numeric_limits<double>::max();
	double phi_avg_can = std::numeric_limits<double>::max();
	double phi_avg_new = std::numeric_limits<double>::max();
	int n_good_runs_new = gen_1.get_num_good_runs();
	if (n_good_runs_targ > 0)
	{
		phi_avg_targ = phi_sum_targ / n_good_runs_targ;
	}
	if (n_good_runs_can > 0)
	{
		phi_avg_can = phi_sum_can / n_good_runs_can;
	}
	if (n_good_runs_new > 0)
	{
		phi_avg_new = phi_sum_new / n_good_runs_new;
	}

	write_run_summary(cout, n_good_runs_targ, phi_avg_targ, phi_min_targ, phi_max_targ,
		n_good_runs_can, phi_avg_can, phi_min_can, phi_max_can,
		n_good_runs_new, phi_avg_new, phi_min_new, phi_max_new);
	cout << endl;
	os << endl;
	write_run_summary(os, n_good_runs_targ, phi_avg_targ, phi_min_targ, phi_max_targ,
		n_good_runs_can, phi_avg_can, phi_min_can, phi_max_can,
		n_good_runs_new, phi_avg_new, phi_min_new, phi_max_new);
	os << endl;
	
	return best_run_idx;
}
Example #5
0
void DifferentialEvolution::mutation(RunManagerAbstract &run_manager, double f, bool dither_f, double cr)
{
	int d = gen_1.get_nruns();
	int r_status;
	int n_par = par_list.size();
	std::uniform_int_distribution<int> uni_par(0, n_par-1);
	std::uniform_real_distribution<double> cr_prob(0.0, 1.0);
	std::uniform_real_distribution<double> dither_f_prob(.5, 1.0);
	vector<int> successful_run_ids;
	// generate a vector of successful runs
	for (int i_run = 0; i_run < d; ++i_run)
	{
		r_status = gen_1.get_run_status(i_run);
		if (r_status > 0)
		{
			successful_run_ids.push_back(i_run);
		}
	}
	int d_ok = successful_run_ids.size();
	std::uniform_int_distribution<int> uni_run_ok(0, d_ok-1);

	Parameters xa;
	Parameters xb;
	Parameters xc;
	Parameters x_trial;
	for (int i_run = 0; i_run < d; ++i_run)
	{
		int xa_id = successful_run_ids[uni_run_ok(rand_engine)];
		int xb_id = successful_run_ids[uni_run_ok(rand_engine)];
		while (xa_id == xb_id)
		{
			xb_id = successful_run_ids[uni_run_ok(rand_engine)];
		}
		int xc_id = successful_run_ids[uni_run_ok(rand_engine)];
		//initialize trail vector with the traget vector
		gen_1.get_parameters(i_run, x_trial);
		gen_1.get_parameters(xa_id, xa);
		gen_1.get_parameters(xb_id, xb);
		gen_1.get_parameters(xc_id, xb);
		par_transform.model2ctl_ip(xa);
		par_transform.model2ctl_ip(xb);
		par_transform.model2ctl_ip(xc);

		int par_id_chg = uni_par(rand_engine);
		for (int idx=0; idx<n_par; ++idx)
		{
			const string &ipar = par_list[idx];
			double a = xa[ipar];
			double b = xb[ipar];
			double c = xc[ipar];
			double delta = a - b;
			double tmp_f = f;
			if (dither_f)
			{
				tmp_f = dither_f_prob(rand_engine);
			}
			double c_p = c + tmp_f * (delta);
			double p_min = parameter_info[ipar].lower_bnd;
			double p_max = parameter_info[ipar].upper_bnd;
			// reflect purturbation if parameter is outside it's bounds
			while (c_p < p_min || c_p > p_max)
			{
				if (c_p < p_min)
				{
					c_p += p_min - c_p;
				}
				if (c_p > p_max)
				{
					c_p -= c_p - p_max;
				}
			}
			// do cross over
			//the trial vector was initialized with the target vector
			// so the parameters from the parent don't need to be set 
			double rand_cr = cr_prob(rand_engine);
			if (rand_cr > cr || idx == par_id_chg)
			{
				x_trial[ipar] = c_p;
			}
		}
		par_transform.ctl2model_ip(x_trial);
		run_manager.add_run(x_trial);
	}
}