Search in sources :

Example 1 with Iter

use of de.lmu.ifi.dbs.elki.utilities.datastructures.histogram.DoubleStaticHistogram.Iter in project elki by elki-project.

the class LMCLUS method findAndEvaluateThreshold.

/**
 * Evaluate the histogram to find a suitable threshold
 *
 * @param histogram Histogram to evaluate
 * @return Position and goodness
 */
private double[] findAndEvaluateThreshold(DoubleDynamicHistogram histogram) {
    int n = histogram.getNumBins();
    double[] p1 = new double[n];
    double[] p2 = new double[n];
    double[] mu1 = new double[n];
    double[] mu2 = new double[n];
    double[] sigma1 = new double[n];
    double[] sigma2 = new double[n];
    double[] jt = new double[n];
    // Forward pass
    {
        MeanVariance mv = new MeanVariance();
        DoubleHistogram.Iter forward = histogram.iter();
        for (int i = 0; forward.valid(); i++, forward.advance()) {
            p1[i] = forward.getValue() + ((i > 0) ? p1[i - 1] : 0);
            mv.put(i, forward.getValue());
            mu1[i] = mv.getMean();
            sigma1[i] = mv.getNaiveStddev();
        }
    }
    // Backwards pass
    {
        MeanVariance mv = new MeanVariance();
        DoubleHistogram.Iter backwards = histogram.iter();
        // Seek to last
        backwards.seek(histogram.getNumBins() - 1);
        for (int j = n - 1; backwards.valid(); j--, backwards.retract()) {
            p2[j] = backwards.getValue() + ((j + 1 < n) ? p2[j + 1] : 0);
            mv.put(j, backwards.getValue());
            mu2[j] = mv.getMean();
            sigma2[j] = mv.getNaiveStddev();
        }
    }
    for (int i = 0; i < n; i++) {
        jt[i] = 1.0 + 2 * (p1[i] * (FastMath.log(sigma1[i]) - FastMath.log(p1[i])) + p2[i] * (FastMath.log(sigma2[i]) - FastMath.log(p2[i])));
    }
    int bestpos = -1;
    double bestgoodness = Double.NEGATIVE_INFINITY;
    double devPrev = jt[1] - jt[0];
    for (int i = 1; i < jt.length - 1; i++) {
        double devCur = jt[i + 1] - jt[i];
        // Local minimum found - calculate depth
        if (devCur >= 0 && devPrev <= 0) {
            double lowestMaxima = Double.POSITIVE_INFINITY;
            for (int j = i - 1; j > 0; j--) {
                if (jt[j - 1] < jt[j]) {
                    lowestMaxima = Math.min(lowestMaxima, jt[j]);
                    break;
                }
            }
            for (int j = i + 1; j < n - 2; j++) {
                if (jt[j + 1] < jt[j]) {
                    lowestMaxima = Math.min(lowestMaxima, jt[j]);
                    break;
                }
            }
            double localDepth = lowestMaxima - jt[i];
            final double mud = mu1[i] - mu2[i];
            double discriminability = mud * mud / (sigma1[i] * sigma1[i] + sigma2[i] * sigma2[i]);
            if (Double.isNaN(discriminability)) {
                discriminability = -1;
            }
            double goodness = localDepth * discriminability;
            if (goodness > bestgoodness) {
                bestgoodness = goodness;
                bestpos = i;
            }
        }
        devPrev = devCur;
    }
    Iter iter = histogram.iter();
    iter.seek(bestpos);
    return new double[] { iter.getRight(), bestgoodness };
}
Also used : MeanVariance(de.lmu.ifi.dbs.elki.math.MeanVariance) Iter(de.lmu.ifi.dbs.elki.utilities.datastructures.histogram.DoubleStaticHistogram.Iter) DBIDIter(de.lmu.ifi.dbs.elki.database.ids.DBIDIter)

Aggregations

DBIDIter (de.lmu.ifi.dbs.elki.database.ids.DBIDIter)1 MeanVariance (de.lmu.ifi.dbs.elki.math.MeanVariance)1 Iter (de.lmu.ifi.dbs.elki.utilities.datastructures.histogram.DoubleStaticHistogram.Iter)1