MixtureModel * PU_DivideAndConquer::performApproximation(
		Distribution * distribution)
{
	MixtureModel * result;
	std::vector<MixtureComponent *> result_components;
	std::vector<double> result_weights;

	std::vector<double> supportInterval_lmargins;
	std::vector<double> supportInterval_rmargins;
	// margin vectors are called by reference
	retrieveSupport(distribution, supportInterval_lmargins,
			supportInterval_rmargins);

	int k; // counter for the support intervals
	int total_support_intervals = supportInterval_lmargins.size();

	// the accuracy for each support interval will be
	// proportional to its probability mass
	int componentsUsed = 0;
	for (k = 0; k < total_support_intervals; k++)
	{
		// (F(b) - F(a)) * totalComponentNumber
		int intervalComponents = (int) (distribution->cdf(
				supportInterval_rmargins[k]) - distribution->cdf(
				supportInterval_lmargins[k])) * numberOfComponents;
		if (k == total_support_intervals - 1) // the last one
			intervalComponents = numberOfComponents - componentsUsed;
		else
			componentsUsed += intervalComponents;

		std::vector<MixtureComponent *> tmp_components;
		std::vector<double> tmp_weights;
		approximateInterval(tmp_components, tmp_weights, intervalComponents,
				supportInterval_lmargins[k], supportInterval_rmargins[k],
				distribution);
		unsigned int i;
		for (i = 0; i < tmp_components.size(); i++)
		{
			result_components.push_back(tmp_components[i]);
			result_weights.push_back(tmp_weights[i]);
		}
	}

	result = new MixtureModel(result_components, result_weights);
	return result;
}
Beispiel #2
0
MixtureModel * PiecewiseUniform::performApproximation(
		Distribution * distribution)
{
	MixtureModel * result;
	std::vector<MixtureComponent *> result_components;
	std::vector<double> result_weights;

	MixtureComponent * component;
	std::vector<double> supportInterval_lmargins;
	std::vector<double> supportInterval_rmargins;

	// margin vectors are called by reference
	retrieveSupport(distribution, supportInterval_lmargins,
			supportInterval_rmargins);

	int k; // counter for the support intervals
	int componentsUsed = 0;
	int total_support_intervals =
		supportInterval_lmargins.size();

	// the accuracy for each support interval will be
	// proportional to its probability mass
	for (k = 0; k < total_support_intervals; k++)
	{
		int intervalComponents;
		// (F(b) - F(a)) * totalComponentNumber
		intervalComponents
		= (int) (distribution->cdf(
				supportInterval_rmargins[k])
				- distribution->cdf(
						supportInterval_lmargins[k]))
						* numberOfComponents;
		if (k == total_support_intervals - 1) // the last one
			intervalComponents = numberOfComponents
			- componentsUsed;
		else
			componentsUsed += intervalComponents;

		int i;
		double x = supportInterval_lmargins[k];
		double weight;
		double step = (supportInterval_rmargins[k]
		                                        - supportInterval_lmargins[k])
		                                        / intervalComponents;

		double p = distribution->pdf(x);
		for (i = 0; i < intervalComponents; i++)
		{
			p = distribution->pdf(x + step);

			weight = distribution->cdf(x + step)
			- distribution->cdf(x);

			if (x + step >= supportInterval_rmargins[k])
				weight = 0;
			if (weight < 0) // negative results are just close to zero
				weight = 0;
			component = new Uniform(x, x + step);
			result_components.push_back(component);
			result_weights.push_back(weight);
			x += step;
		}
	}
	result
	= new MixtureModel(result_components,
			result_weights);
	return result;
}