[PATCH] 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

Wald Commits scm-commit at wald.intevation.org
Tue Aug 6 17:00:55 CEST 2013


# HG changeset patch
# User Sascha L. Teichmann <teichmann at intevation.de>
# Date 1375801249 -7200
# Node ID 9479cb7c8cd5651d6979dfb85fe98ff0653f87af
# Parent  ae419fc225b4f0ebf1dd218b9388546716f92e64
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.

diff -r ae419fc225b4 -r 9479cb7c8cd5 artifacts/src/main/java/org/dive4elements/river/artifacts/model/sq/Fitting.java
--- 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


More information about the Dive4elements-commits mailing list