Mercurial > dive4elements > river
changeset 6761:9479cb7c8cd5
flys/issue748: Force linear curve fitting. This is a real hack! Set the system property "minfo.sq.fitting.nonlinear" to re-enable the old behavior.
author | Sascha L. Teichmann <teichmann@intevation.de> |
---|---|
date | Tue, 06 Aug 2013 17:00:49 +0200 (2013-08-06) |
parents | ae419fc225b4 |
children | 34c15927f9d9 dd5355775ce1 |
files | artifacts/src/main/java/org/dive4elements/river/artifacts/model/sq/Fitting.java |
diffstat | 1 files changed, 43 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/model/sq/Fitting.java Tue Aug 06 16:57:47 2013 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/model/sq/Fitting.java Tue Aug 06 17:00:49 2013 +0200 @@ -9,6 +9,7 @@ package org.dive4elements.river.artifacts.model.sq; import org.dive4elements.river.artifacts.math.fitting.Function; +import org.dive4elements.river.artifacts.math.fitting.Linear; import java.util.ArrayList; import java.util.List; @@ -17,6 +18,8 @@ import org.apache.commons.math.optimization.fitting.CurveFitter; +import org.apache.commons.math.optimization.general.AbstractLeastSquaresOptimizer; +import org.apache.commons.math.optimization.general.GaussNewtonOptimizer; import org.apache.commons.math.optimization.general.LevenbergMarquardtOptimizer; import org.apache.log4j.Logger; @@ -24,6 +27,10 @@ public class Fitting implements Outlier.Callback { + // XXX: Hack to force linear fitting! + private static final boolean USE_NON_LINEAR_FITTING = + Boolean.getBoolean("minfo.sq.fitting.nonlinear"); + private static Logger log = Logger.getLogger(Fitting.class); public interface Callback { @@ -75,20 +82,51 @@ @Override public void initialize(List<SQ> sqs) throws MathException { - LevenbergMarquardtOptimizer lmo = - new LevenbergMarquardtOptimizer(); + AbstractLeastSquaresOptimizer optimizer = getOptimizer(); - CurveFitter cf = new CurveFitter(lmo); + CurveFitter cf = new CurveFitter(optimizer); + double [] values = new double[2]; for (SQ sq: sqs) { - cf.addObservedPoint(sq.getQ(), sq.getS()); + values[0] = sq.getQ(); + values[1] = sq.getS(); + transformInputValues(values); + cf.addObservedPoint(values[0], values[1]); } coeffs = cf.fit( function, function.getInitialGuess()); + transformCoeffsBack(coeffs); + instance = function.instantiate(coeffs); - chiSqr = lmo.getChiSquare(); + chiSqr = optimizer.getChiSquare(); + } + + protected Function getFunction(Function function) { + return USE_NON_LINEAR_FITTING + ? function + : Linear.INSTANCE; + } + + protected void transformInputValues(double [] values) { + if (!USE_NON_LINEAR_FITTING) { + for (int i = 0; i < values.length; ++i) { + values[i] = Math.log(values[i]); + } + } + } + + protected AbstractLeastSquaresOptimizer getOptimizer() { + return USE_NON_LINEAR_FITTING + ? new LevenbergMarquardtOptimizer() + : new GaussNewtonOptimizer(false); + } + + protected void transformCoeffsBack(double [] coeffs) { + if (!USE_NON_LINEAR_FITTING && coeffs.length > 0) { + coeffs[0] = Math.exp(coeffs[0]); + } } @Override