Mercurial > dive4elements > river
diff flys-artifacts/src/main/java/org/dive4elements/river/artifacts/model/sq/Fitting.java @ 5831:bd047b71ab37
Repaired internal references
author | Sascha L. Teichmann <teichmann@intevation.de> |
---|---|
date | Thu, 25 Apr 2013 12:06:39 +0200 |
parents | flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/sq/Fitting.java@aaf810d4ec82 |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/src/main/java/org/dive4elements/river/artifacts/model/sq/Fitting.java Thu Apr 25 12:06:39 2013 +0200 @@ -0,0 +1,149 @@ +package org.dive4elements.river.artifacts.model.sq; + +import org.dive4elements.river.artifacts.math.fitting.Function; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.math.MathException; + +import org.apache.commons.math.optimization.fitting.CurveFitter; + +import org.apache.commons.math.optimization.general.LevenbergMarquardtOptimizer; + +import org.apache.log4j.Logger; + +public class Fitting +implements Outlier.Callback +{ + private static Logger log = Logger.getLogger(Fitting.class); + + public interface Callback { + + void afterIteration( + double [] parameters, + SQ [] measurements, + SQ [] outliers, + double standardDeviation, + double chiSqr); + } // interfacte + + protected Function function; + + protected double [] coeffs; + + protected org.dive4elements.river.artifacts.math.Function instance; + + protected double stdDevFactor; + protected double chiSqr; + + protected Callback callback; + + public Fitting() { + } + + public Fitting(Function function, double stdDevFactor) { + this(); + this.function = function; + this.stdDevFactor = stdDevFactor; + } + + public Function getFunction() { + return function; + } + + public void setFunction(Function function) { + this.function = function; + } + + public double getStdDevFactor() { + return stdDevFactor; + } + + public void setStdDevFactor(double stdDevFactor) { + this.stdDevFactor = stdDevFactor; + } + + @Override + public void initialize(List<SQ> sqs) throws MathException { + + LevenbergMarquardtOptimizer lmo = + new LevenbergMarquardtOptimizer(); + + CurveFitter cf = new CurveFitter(lmo); + for (SQ sq: sqs) { + cf.addObservedPoint(sq.getQ(), sq.getS()); + } + + coeffs = cf.fit( + function, function.getInitialGuess()); + + instance = function.instantiate(coeffs); + + chiSqr = lmo.getChiSquare(); + } + + @Override + public double eval(SQ sq) { + double s = instance.value(sq.q); + return sq.s - s; + } + + @Override + public void iterationFinished( + double standardDeviation, + SQ outlier, + List<SQ> remainings + ) { + if (log.isDebugEnabled()) { + log.debug("iterationFinished ----"); + log.debug(" num remainings: " + remainings.size()); + log.debug(" has outlier: " + outlier != null); + log.debug(" standardDeviation: " + standardDeviation); + log.debug(" Chi^2: " + chiSqr); + log.debug("---- iterationFinished"); + } + callback.afterIteration( + coeffs, + remainings.toArray(new SQ[remainings.size()]), + outlier != null ? new SQ [] { outlier} : new SQ [] {}, + standardDeviation, + chiSqr); + } + + protected static final List<SQ> onlyValid(List<SQ> sqs) { + + List<SQ> good = new ArrayList<SQ>(sqs.size()); + + for (SQ sq: sqs) { + if (sq.isValid()) { + good.add(sq); + } + } + + return good; + } + + public boolean fit(List<SQ> sqs, String method, Callback callback) { + + sqs = onlyValid(sqs); + + if (sqs.size() < 2) { + log.warn("Too less points for fitting."); + return false; + } + + this.callback = callback; + + try { + Outlier.detectOutliers(this, sqs, stdDevFactor, method); + } + catch (MathException me) { + log.warn(me); + return false; + } + + return true; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :