Mercurial > dive4elements > river
view artifacts/src/main/java/org/dive4elements/river/artifacts/math/StdDevOutlier.java @ 6714:b265cd6cfda5
issue748: Change StandardDeviation implmentation to what BFG calls Standard Deviation
Which is actually a calculation that removes outliers based on
Standard Error
Developed and analyized together with Tom.
author | Andre Heinecke <aheinecke@intevation.de> |
---|---|
date | Tue, 30 Jul 2013 17:32:28 +0200 |
parents | af13ceeba52a |
children | 5e38e2924c07 |
line wrap: on
line source
/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde * Software engineering by Intevation GmbH * * This file is Free Software under the GNU AGPL (>=v3) * and comes with ABSOLUTELY NO WARRANTY! Check out the * documentation coming with Dive4Elements River for details. */ package org.dive4elements.river.artifacts.math; import java.util.List; import org.apache.log4j.Logger; /* XXX: * Warning: This class is called StdDevOutlier because it caculates the * Standard Deviation method for outlier removal as the BFG calls it. * But the actual calculation used to remove the outliers calculates * the Standard Error and not the Standard Deviation! */ public class StdDevOutlier { public static final double DEFAULT_FACTOR = 3; private static Logger log = Logger.getLogger(StdDevOutlier.class); protected StdDevOutlier() { } public static Integer findOutlier(List<Double> values) { return findOutlier(values, DEFAULT_FACTOR, null); } public static Integer findOutlier( List<Double> values, double factor, double [] stdErrResult ) { boolean debug = log.isDebugEnabled(); if (debug) { log.debug("factor for std dev test (that calculates std err): " + factor); } int N = values.size(); if (debug) { log.debug("Values to check: " + N); } if (N < 3) { return null; } double maxValue = -Double.MAX_VALUE; int maxIndex = -1; double squareSumResiduals = 0; for (Double db: values) { squareSumResiduals += Math.pow(db, 2); } double stdErr = Math.sqrt(squareSumResiduals / (N - 2)); double accepted = factor * stdErr; for (int i = N-1; i >= 0; --i) { double value = Math.abs(values.get(i)); if (value > maxValue) { maxValue = value; maxIndex = i; } } if (debug) { log.debug("std err: " + stdErr); log.debug("accepted: " + accepted); log.debug("max value: " + maxValue); } if (stdErrResult != null) { stdErrResult[0] = stdErr; } return maxValue > accepted ? maxIndex : null; } } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :