// Mixture package distributions; public class MixtureDistribution extends Distribution{ Distribution[] dist; int n, type; double minValue, maxValue, lowerValue, upperValue, stepSize; double[] prob; //Constructors public MixtureDistribution(Distribution[] d, double[] p){ setParameters(d, p); } public MixtureDistribution(Distribution d0, Distribution d1, double a){ setParameters(d0, d1, a); } public void setParameters(Distribution[] d, double[] p){ double minLower = Double.POSITIVE_INFINITY, maxUpper = Double.NEGATIVE_INFINITY, minWidth = Double.POSITIVE_INFINITY; double a, b, w; dist = d; prob = p; int t0 = dist[0].getType(), t; n = dist.length; boolean mixed = false; for (int i = 0; i < n; i++){ t = dist[i].getType(); if (t == DISCRETE) a = dist[i].getDomain().getLowerValue(); else a = dist[i].getDomain().getLowerBound(); if (a < minLower) minLower = a; if (t == DISCRETE) b = dist[i].getDomain().getUpperValue(); else b = dist[i].getDomain().getUpperBound(); if (b > maxUpper) maxUpper = b; w = dist[i].getDomain().getWidth(); if (w < minWidth) minWidth = w; if (t != t0) mixed = true; } if (mixed) t = 2; else t = t0; super.setParameters(minLower, maxUpper, minWidth, t); } public void setParameters(Distribution d0, Distribution d1, double a){ setParameters(new Distribution[]{d0, d1}, new double[]{1 - a, a}); } //Density public double getDensity(double x){ double d = 0; for (int i = 0; i < n; i++) d = d + prob[i] * dist[i].getDensity(x); return d; } //Mean public double getMean(){ double sum = 0; for (int i = 0; i < n; i++) sum = sum + prob[i] * dist[i].getMean(); return sum; } //Variance public double getVariance(){ double sum = 0, mu = getMean(), m; for (int i = 0; i < n; i++){ m = dist[i].getMean(); sum = sum + prob[i] * (dist[i].getVariance() + m * m); } return sum - mu * mu; } //Simulate public double simulate(){ double sum = 0, p = Math.random(); int i = -1; while (sum < p & i < n){ sum = sum + prob[i]; i = i + 1; } return dist[i].simulate(); } }