teichmann@5863: /* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde teichmann@5863: * Software engineering by Intevation GmbH teichmann@5863: * teichmann@5863: * This file is Free Software under the GNU AGPL (>=v3) teichmann@5863: * and comes with ABSOLUTELY NO WARRANTY! Check out the teichmann@5863: * documentation coming with Dive4Elements River for details. teichmann@5863: */ teichmann@5863: teichmann@5831: package org.dive4elements.river.artifacts.math; rrenkert@4794: rrenkert@4794: import java.util.List; rrenkert@4794: rrenkert@4794: import org.apache.commons.math.stat.descriptive.moment.StandardDeviation; rrenkert@4794: rrenkert@4794: import org.apache.log4j.Logger; rrenkert@4794: rrenkert@4794: public class StdDevOutlier rrenkert@4794: { rrenkert@4794: public static final double DEFAULT_FACTOR = 3; rrenkert@4794: rrenkert@4794: private static Logger log = Logger.getLogger(StdDevOutlier.class); rrenkert@4794: rrenkert@4794: protected StdDevOutlier() { rrenkert@4794: } rrenkert@4794: rrenkert@4794: public static Integer findOutlier(List values) { rrenkert@4794: return findOutlier(values, DEFAULT_FACTOR, null); rrenkert@4794: } rrenkert@4794: teichmann@4795: public static Integer findOutlier( teichmann@4795: List values, teichmann@4816: double factor, teichmann@4795: double [] stdDevResult teichmann@4795: ) { rrenkert@4794: boolean debug = log.isDebugEnabled(); rrenkert@4794: rrenkert@4794: if (debug) { rrenkert@4794: log.debug("factor for std dev: " + factor); rrenkert@4794: } rrenkert@4794: rrenkert@4794: int N = values.size(); rrenkert@4794: rrenkert@4794: if (debug) { rrenkert@4794: log.debug("Values to check: " + N); rrenkert@4794: } rrenkert@4794: teichmann@4795: if (N < 3) { rrenkert@4794: return null; rrenkert@4794: } rrenkert@4794: rrenkert@4794: StandardDeviation stdDev = new StandardDeviation(); rrenkert@4794: rrenkert@4794: double maxValue = -Double.MAX_VALUE; rrenkert@4794: int maxIndex = -1; teichmann@4795: for (int i = N-1; i >= 0; --i) { rrenkert@4794: double value = Math.abs(values.get(i)); rrenkert@4794: stdDev.increment(value); rrenkert@4794: if (value > maxValue) { rrenkert@4794: maxValue = value; teichmann@4795: maxIndex = i; rrenkert@4794: } rrenkert@4794: } rrenkert@4794: rrenkert@4794: double sd = stdDev.getResult(); rrenkert@4794: rrenkert@4794: double accepted = factor * sd; rrenkert@4794: rrenkert@4794: if (debug) { rrenkert@4794: log.debug("std dev: " + stdDev); rrenkert@4794: log.debug("accepted: " + accepted); rrenkert@4794: log.debug("max value: " + maxValue); rrenkert@4794: } teichmann@4795: rrenkert@4794: if (stdDevResult != null) { rrenkert@4794: stdDevResult[0] = sd; rrenkert@4794: } teichmann@4795: rrenkert@4794: return maxValue > accepted ? maxIndex : null; rrenkert@4794: } rrenkert@4794: } rrenkert@4794: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :