# HG changeset patch # User Sascha L. Teichmann # Date 1343816385 0 # Node ID 8d0f06b76e09d188e44c73225d8e105ca6857fb0 # Parent b136113dad531aa9813ceb26538079e3a516f728 S/Q relation: Fixed flys/issue748 flys-artifacts/trunk@5164 c6561f87-3c4e-4783-a992-168aeb5c3f6f diff -r b136113dad53 -r 8d0f06b76e09 flys-artifacts/ChangeLog --- a/flys-artifacts/ChangeLog Tue Jul 31 16:46:36 2012 +0000 +++ b/flys-artifacts/ChangeLog Wed Aug 01 10:19:45 2012 +0000 @@ -1,3 +1,11 @@ +2012-08-01 Sascha L. Teichmann + + Fix for flys/issue748 + + * src/main/java/de/intevation/flys/artifacts/model/sq/Fitting.java, + src/main/java/de/intevation/flys/artifacts/model/sq/Outlier.java: + Only remove one data point per outlier removal iteration. + 2012-07-31 Sascha L. Teichmann * src/main/java/de/intevation/flys/artifacts/math/Outlier.java: diff -r b136113dad53 -r 8d0f06b76e09 flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/sq/Fitting.java --- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/sq/Fitting.java Tue Jul 31 16:46:36 2012 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/sq/Fitting.java Wed Aug 01 10:19:45 2012 +0000 @@ -35,18 +35,12 @@ protected de.intevation.flys.artifacts.math.Function instance; - protected List remainings; - protected List outliers; - - protected double standardDeviation; protected double stdDevFactor; protected double chiSqr; protected Callback callback; public Fitting() { - remainings = new ArrayList(); - outliers = new ArrayList(); } public Fitting(Function function, double stdDevFactor) { @@ -72,14 +66,13 @@ } @Override - public void initialize(Iterator good) throws MathException { + public void initialize(List sqs) throws MathException { LevenbergMarquardtOptimizer lmo = new LevenbergMarquardtOptimizer(); CurveFitter cf = new CurveFitter(lmo); - while (good.hasNext()) { - SQ sq = good.next(); + for (SQ sq: sqs) { cf.addObservedPoint(sq.getQ(), sq.getS()); } @@ -89,7 +82,6 @@ instance = function.instantiate(coeffs); chiSqr = lmo.getChiSquare(); - } @Override @@ -99,26 +91,15 @@ } @Override - public void outlier(SQ sq) { - outliers.add(sq); - } - - @Override - public void remaining(SQ sq) { - remainings.add(sq); - } - - @Override - public void standardDeviation(double standardDeviation) { - this.standardDeviation = standardDeviation; - } - - @Override - public void iterationFinished() { + public void iterationFinished( + double standardDeviation, + SQ outlier, + List remainings + ) { if (log.isDebugEnabled()) { log.debug("iterationFinished ----"); log.debug(" num remainings: " + remainings.size()); - log.debug(" num outliers: " + outliers.size()); + log.debug(" has outlier: " + outlier != null); log.debug(" standardDeviation: " + standardDeviation); log.debug(" Chi^2: " + chiSqr); log.debug("---- iterationFinished"); @@ -126,11 +107,9 @@ callback.afterIteration( coeffs, remainings.toArray(new SQ[remainings.size()]), - outliers.toArray(new SQ[outliers.size()]), + outlier != null ? new SQ [] { outlier} : new SQ [] {}, standardDeviation, chiSqr); - remainings.clear(); - outliers.clear(); } protected static final List onlyValid(List sqs) { diff -r b136113dad53 -r 8d0f06b76e09 flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/sq/Outlier.java --- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/sq/Outlier.java Tue Jul 31 16:46:36 2012 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/sq/Outlier.java Wed Aug 01 10:19:45 2012 +0000 @@ -14,33 +14,19 @@ { private static Logger log = Logger.getLogger(Outlier.class); - public static final int MAX_ITERATIONS = 1000; - public interface Callback { - void initialize(Iterator good) throws MathException; + void initialize(List sqs) throws MathException; double eval(SQ sq); - void outlier(SQ sq); - - void remaining(SQ sq); - - void standardDeviation(double stdDev); - - void iterationFinished(); + void iterationFinished( + double stdDev, + SQ outlier, + List remaining); } // interface Callback - private static final class EvalSQ { - protected SQ sq; - protected double value; - - public EvalSQ(SQ sq) { - this.sq = sq; - } - } // class EvalSQ - public static void detectOutliers( Callback callback, List sqs, @@ -54,79 +40,46 @@ log.debug("stdDevFactor: " + stdDevFactor); } - List data = new ArrayList(sqs.size()); + List data = new ArrayList(sqs); - for (SQ sq: sqs) { - data.add(new EvalSQ(sq)); - } + while (data.size() > 2) { - List good = new ArrayList(sqs.size()); - - for (int i = 0; i < MAX_ITERATIONS && data.size() > 2; ++i) { - - callback.initialize(asSQIterator(data)); + callback.initialize(data); StandardDeviation stdDev = new StandardDeviation(); - for (EvalSQ esq: data) { - stdDev.increment(esq.value = callback.eval(esq.sq)); + double maxValue = -Double.MAX_VALUE; + int maxIndex = -1; + + for (int i = data.size()-1; i >= 0; --i) { + double value = Math.abs(callback.eval(data.get(i))); + stdDev.increment(value); + if (value > maxValue) { + maxValue = value; + maxIndex = i; + } } double sd = stdDev.getResult(); - callback.standardDeviation(sd); - double accepted = stdDevFactor * sd; if (debug) { + log.debug("std dev: " + stdDev); log.debug("accepted: " + accepted); - } - - for (EvalSQ esq: data) { - if (debug) { - log.debug(" value: " + Math.abs(esq.value)); - } - - if (Math.abs(esq.value) > accepted) { - callback.outlier(esq.sq); - } - else { - callback.remaining(esq.sq); - good.add(esq); - } - } - - callback.iterationFinished(); - - if (good.size() == data.size()) { - break; + log.debug("max value: " + maxValue); } - List tmp = good; - good = data; - data = tmp; - good.clear(); - } - } + SQ outlier = maxValue > accepted + ? data.remove(maxIndex) + : null; - protected static Iterator asSQIterator(List esqs) { - final Iterator parent = esqs.iterator(); - return new Iterator() { - @Override - public boolean hasNext() { - return parent.hasNext(); - } + callback.iterationFinished(sd, outlier, data); - @Override - public SQ next() { - return parent.next().sq; + if (outlier == null) { + break; } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - }; + } } } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :