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; }
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; }