"observation is out of range for calcualtion");
ValidationUtils.guardGreaterOrEqualDouble(1000000, minMax.getMax().getComponent(i),
"observation is out of range for calcualtion");
}
DiagonalNormalDistributionMixture res = initializeOneCompoenent(observations, minMax.getDimension());
invokeStepListener(res);
double resL = Double.NEGATIVE_INFINITY;
double newL = countLnL(observations, res);
int iteration = 0;
while (newL - resL > 0.01 && res.getNumComponents() < maxComponents && iteration < 100) {
++iteration;
resL = newL;
// find the maximum weight
double splitValue = 0;
int splitCompIdx = 0;
int splitDimIdx = 0;
for (int i = 0; i < res.getNumComponents(); ++i) {
DiagonalNormalDistribution comp = res.getComponents().get(i);
for (int j = 0; j < comp.getDimension(); ++j) {
if (res.getWeights().get(i) * res.getComponents().get(i).getSigma().getComponent(j) > splitValue) {
splitValue = res.getWeights().get(i) * res.getComponents().get(i).getSigma().getComponent(j);
splitCompIdx = i;
splitDimIdx = j;
}
}
}
// split the component with highest weight
DiagonalNormalDistributionMixture.Builder builder = new DiagonalNormalDistributionMixture.Builder();
for (int i = 0; i < res.getNumComponents(); ++i) {
if (i == splitCompIdx) {
DiagonalNormalDistribution comp = res.getComponents().get(i);
double[] mi1 = new double[res.getDimension()];
double[] mi2 = new double[res.getDimension()];
for (int j = 0; j < comp.getDimension(); ++j) {
if (j == splitDimIdx) {
mi1[j] = comp.getMi().getComponent(j) + comp.getSigma().getComponent(j) / 2;
mi2[j] = comp.getMi().getComponent(j) - comp.getSigma().getComponent(j) / 2;
}
else {
mi1[j] = comp.getMi().getComponent(j);
mi2[j] = comp.getMi().getComponent(j);
}
}
builder.addComponent(res.getWeights().get(i) / 2, Vector.create(mi1), comp.getSigma());
builder.addComponent(res.getWeights().get(i) / 2, Vector.create(mi2), comp.getSigma());
}
else {
if (res.getWeights().get(i) >= minWeight) {
builder.addComponent(res.getWeights().get(i), res.getComponents().get(i));
}
}
}
DiagonalNormalDistributionMixture newMixture = builder.build();
// iterations for the new mixture
double help = Double.NEGATIVE_INFINITY;
int emiteration = 0;
while (emiteration < 5 || newL - help > 0.01) {
++emiteration;
help = newL;
newMixture = nextIteration(observations, newMixture);
newL = countLnL(observations, newMixture);
if (getMinWeigth(newMixture) < minWeight) {
newMixture = newMixture.createSignificantComponentMixture(minWeight);
newL = countLnL(observations, newMixture);
}
// assign new L value if possible
if (newL > resL) {
res = newMixture;