void bayesian_kriging_test::test_interpolation() {
	Parameter params;
	SourceList sources;
	DestinationList destinations;
	using namespace shyft::timeseries;
	using namespace shyft::core;
	using namespace shyfttest;
	size_t n_s = 2;
	size_t n_d = 4;
	size_t n_times = 2; // Daily interpolations for three years
	shyft::timeseries::utctime dt = 10;
	vector<utctime> times; times.reserve(n_times);
	for (size_t i = 0; i < n_times; ++i)
		times.emplace_back(dt*i);
	const point_timeaxis time_axis(times);
	build_sources_and_dests(n_s, n_s, n_d, n_d, n_times, dt, time_axis, true, sources, destinations);
	const std::clock_t start = std::clock();
	btk_interpolation<average_accessor<shyfttest::xpts_t, point_timeaxis>>(begin(sources), end(sources), begin(destinations), end(destinations), time_axis, params);
	const std::clock_t total = std::clock() - start;
	std::cout << "Calling compute with n_sources, n_dests, and n_times = " << n_s*n_s << ", " << n_d*n_d << ", " << n_times << " took: " << 1000 * (total) / (double)(CLOCKS_PER_SEC) << " ms" << std::endl;
	MCell d = destinations[destinations.size() - 1];
	std::cout << "Temp at altitude " << d.mid_point().z << " is " << d.temperature(0) << std::endl;
	d = destinations[0];
	if (getenv("SHYFT_BTK_VERBOSE")) {
		std::cout << "Temp at altitude " << d.mid_point().z << " is " << d.temperature(0) << std::endl;
		for (auto d : destinations) {
			std::cout << d.mid_point().z << std::endl;
			std::cout << "Max/Min: " << *std::max_element(d.temperatures.begin(), d.temperatures.end()) <<
				", " << *std::min_element(d.temperatures.begin(), d.temperatures.end()) << std::endl;
		}
	}
}
void build_sources_and_dests(const size_t num_sources_x, const size_t num_sources_y,
	const size_t num_dests_x, const size_t num_dests_y,
	const size_t ts_size, const shyft::timeseries::utctimespan dt,
	const point_timeaxis& time_axis, bool insert_nans, SourceList& sources, DestinationList& dests,bool randomize=false) {
	const double x_min = 0.0; // [m]
	const double x_max = 100000.0; // [m]
	const double y_min = 0.0; // [m]
	const double y_max = 1000000.0; // [m]

	sources.reserve(num_sources_x*num_sources_y);
	dests.reserve(num_dests_x*num_dests_y);
	geo_point pt;
	double lower_bound = 0.0;
	double upper_bound = 10.0;
	std::uniform_real_distribution<double> unif(lower_bound, upper_bound);
	std::default_random_engine re;
    vector<utctime> times;times.reserve(ts_size);
    for (size_t l = 0; l < ts_size; ++l)
        times.emplace_back(l*dt);
    times.emplace_back(shyft::core::max_utctime);
    point_timeaxis dta(times);
    geo_point p0(x_min,y_min,0.0);
    const double max_distance=geo_point::xy_distance(p0,geo_point(x_max,y_max,0.0));
    auto base_temp=[&unif,&re,randomize,&p0,max_distance](geo_point p1)->double {
        if(randomize)
            return unif(re);
        return 10+ 2.0*geo_point::xy_distance(p0,p1)/max_distance;
    };
	for (size_t i = 0; i < num_sources_x; ++i) {
		pt.x = x_min + i*(x_max - x_min) / (num_sources_x - 1);
		for (size_t j = 0; j < num_sources_y; ++j) {
			pt.y = y_min + j*(y_max - y_min) / (num_sources_y - 1);
			pt.z = 500 * std::sin(pt.x / x_max) + std::sin(pt.y / y_max) / 2;
			vector<double> pts; pts.reserve(ts_size);
			double b_t = base_temp(pt);
			for (size_t l = 0; l < ts_size; ++l)
				pts.emplace_back( b_t + pt.z*(0.6 / 100));
			sources.emplace_back(pt, xpts_t(dta,pts));
		}
	}
	for (size_t i = 0; i < num_dests_x; ++i) {
		pt.x = x_min + i*(x_max - x_min) / (num_dests_x - 1);
		for (size_t j = 0; j < num_dests_y; ++j) {
			pt.y = y_min + j*(y_max - y_min) / (num_dests_y - 1);
			pt.z = 500 * (std::sin(pt.x / x_max) + std::sin(pt.y / y_max)) / 2;
			dests.emplace_back(pt, time_axis);
		}
	}
}
void build_sources_and_dests(const size_t num_sources_x, const size_t num_sources_y,
	const size_t num_dests_x, const size_t num_dests_y,
	const size_t ts_size, const shyft::timeseries::utctimespan dt,
	const point_timeaxis& time_axis, bool insert_nans, SourceList& sources, DestinationList& dests) {
	const double x_min = 0.0; // [m]
	const double x_max = 100000.0; // [m]
	const double y_min = 0.0; // [m]
	const double y_max = 1000000.0; // [m]

	sources.reserve(num_sources_x*num_sources_y);
	dests.reserve(num_dests_x*num_dests_y);
	geo_point pt;
	double lower_bound = 0.0;
	double upper_bound = 10.0;
	std::uniform_real_distribution<double> unif(lower_bound, upper_bound);
	std::default_random_engine re;
    vector<utctime> times;times.reserve(ts_size);
    for (size_t l = 0; l < ts_size; ++l)
        times.emplace_back(l*dt);
    times.emplace_back(shyft::core::max_utctime);
    point_timeaxis dta(times);
	for (size_t i = 0; i < num_sources_x; ++i) {
		pt.x = x_min + i*(x_max - x_min) / (num_sources_x - 1);
		for (size_t j = 0; j < num_sources_y; ++j) {
			pt.y = y_min + j*(y_max - y_min) / (num_sources_y - 1);
			pt.z = 500 * std::sin(pt.x / x_max) + std::sin(pt.y / y_max) / 2;
			vector<double> pts; pts.reserve(ts_size);
			double b_t = unif(re);
			//std::cout << "Base temp at pos (i,j) = " << i << ", " << j << ") = " << b_t << std::endl;
			for (size_t l = 0; l < ts_size; ++l)
				pts.emplace_back( b_t + pt.z*(0.6 / 100));
			sources.emplace_back(pt, xpts_t(dta,pts));
		}
	}
	for (size_t i = 0; i < num_dests_x; ++i) {
		pt.x = x_min + i*(x_max - x_min) / (num_dests_x - 1);
		for (size_t j = 0; j < num_dests_y; ++j) {
			pt.y = y_min + j*(y_max - y_min) / (num_dests_y - 1);
			pt.z = 500 * (std::sin(pt.x / x_max) + std::sin(pt.y / y_max)) / 2;
			dests.emplace_back(pt, time_axis);
		}
	}
}