view flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/sq/Outlier.java @ 3187:1e2733f749b5

SQ: Added specialized outlier test for the S/Q relation. flys-artifacts/trunk@4802 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Tue, 26 Jun 2012 16:00:59 +0000
parents
children 1e46ced2bb57
line wrap: on
line source
package de.intevation.flys.artifacts.model.sq;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.math.stat.descriptive.moment.StandardDeviation;

public class Outlier
{
    public static final int MAX_ITERATIONS = 1000;

    public interface Callback {

        double eval(SQ sq);

        void iteration(int i);

        void outlier(SQ sq);

        void finished();

    } // interface Callback

    private static final class EvalSQ {
        protected SQ     sq;
        protected double value;

        public EvalSQ(SQ sq) {
            this.sq = sq;
        }
    } // class EvalSQ

    public static List<SQ> detectOutliers(
        Callback callback,
        List<SQ> sqs,
        double   stdDevFactor
    ) {
        List<EvalSQ> data = new ArrayList<EvalSQ>(sqs.size());

        for (SQ sq: sqs) {
            data.add(new EvalSQ(sq));
        }

        List<EvalSQ> good = new ArrayList<EvalSQ>(sqs.size());

        for (int i = 0; i < MAX_ITERATIONS && data.size() > 2; ++i) {

            StandardDeviation stdDev = new StandardDeviation();

            for (EvalSQ esq: data) {
                stdDev.increment(esq.value = callback.eval(esq.sq));
            }

            double accepted = stdDevFactor * stdDev.getResult();

            callback.iteration(i);

            for (EvalSQ esq: data) {
                if (Math.abs(esq.value) > accepted) {
                    callback.outlier(esq.sq);
                }
                else {
                    good.add(esq);
                }
            }

            if (good.size() == data.size()) {
                break;
            }

            List<EvalSQ> tmp = good;
            good = data;
            data = tmp;
            good.clear();
        }

        callback.finished();

        List<SQ> result = new ArrayList<SQ>(good.size());

        for (EvalSQ esq: good) {
            result.add(esq.sq);
        }

        return result;
    }
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org