Esempio n. 1
0
void regridder::regrid(void)
{
	std::cout << "# Regridding, time step: ";
	// loop through all time steps
	for (int t=0; t<nc_data.get_t_len(); t++)
	{
		std::cout << t;
		std::cout.flush();
		// loop through all the base triangles
		for (int i=0; i<tg.get_number_of_base_tris(); i++)
		{
			// walk the tree doing the regridding as we go
			QT_TRI_NODE* root_node = tg.get_base_tri(i);
			regrid_node(root_node, &nc_data, z_level, t, ds);
		}
		// timestep counter
		int e = t;
		if (t == 0)
			std::cout << "\b";
		while (e > 0)
		{
			e = e / 10;
			std::cout << "\b";
		}
	}
	std::cout << std::endl;
	
	// smooth if necessary
	if (smooth_weight != 1.0)
		smooth_data();
}
std::vector<double> simpleMovingAverage(vector<double> & data, int windowsize)
{
	/*==============================================================
		This Function smooths a vector of n elements using a moving
		average n elements wide (referred to here as the 
		windowsize).

		This function is fast as it relies on the degeneracy of the
		problem: in the middle of the vector (sufficiently far from 
		the ends) the calculation of the average can be computed:

		Smth_n = (data_n+w/2+1 + w*average(d_n-1) - d_n-w/2-1) / w

		With this degeneracy we can simply store the previous 
		calculated average and "slide" this along the vector to
		simplify calculation.

		The complex part is what to do at the end of the vector.

		The window size must be odd to compute this properly, but 
		the function accepts any integer input. If the input is 
		even, then it will decrement the windowsize by 1.
	==============================================================*/

	//You need an odd size window
	if (windowsize % 2 == 0)
	{
		--windowsize;
	}

	//double to store the previous averaged result
	double previous = 0.0;

	//integer division
	int halfWindow = windowsize / 2;
	int dataSize = static_cast<int>(data.size());

	//vector of new smoothed data
	vector<double> smooth_data(dataSize, NULL);

	//For loop to do the smoothing
	for (auto i = 0; i < dataSize; i++)
	{
		//First elemet is just ths same
		if (i == 0)
		{
			smooth_data.at(i) = data.at(i);
		}

		//Next the smoothing depends on how far we are along
		else if (i < (halfWindow))
		{
			vector<double>::iterator end = data.begin() + 2 * i + 1;
			smooth_data.at(i) = iteratorAverage(data.begin(), end);
		}

		//Standard general smoothing format
		else if ((i < dataSize - (halfWindow)))
		{
			if (previous)
			{
				smooth_data.at(i) = ((windowsize * previous) - data.at(i - 1 - halfWindow) + data.at(i + (halfWindow))) / windowsize;
				previous = smooth_data.at(i);
			}
			else
			{
				smooth_data.at(i) = iteratorAverage(data.begin() + i - (halfWindow), data.begin() + i + (halfWindow)+1);
				previous = smooth_data.at(i);
			}
		}

		//Approaching the end of the data set
		else if ((i < dataSize - 1))
		{
			vector<double>::iterator start = data.begin() + 1 + i - (dataSize - i);
			smooth_data.at(i) = iteratorAverage(start, data.end());
		}

		//Final element
		else
		{
			smooth_data.at(i) = data.at(i);
		}
	}

	//Return the smoothed vector
	return smooth_data;

}