Mercurial > dive4elements > river
comparison artifacts/src/main/java/org/dive4elements/river/artifacts/model/sq/Fitting.java @ 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 |
parents | af13ceeba52a |
children | 48f6780c372d |
comparison
equal
deleted
inserted
replaced
6760:ae419fc225b4 | 6761:9479cb7c8cd5 |
---|---|
7 */ | 7 */ |
8 | 8 |
9 package org.dive4elements.river.artifacts.model.sq; | 9 package org.dive4elements.river.artifacts.model.sq; |
10 | 10 |
11 import org.dive4elements.river.artifacts.math.fitting.Function; | 11 import org.dive4elements.river.artifacts.math.fitting.Function; |
12 import org.dive4elements.river.artifacts.math.fitting.Linear; | |
12 | 13 |
13 import java.util.ArrayList; | 14 import java.util.ArrayList; |
14 import java.util.List; | 15 import java.util.List; |
15 | 16 |
16 import org.apache.commons.math.MathException; | 17 import org.apache.commons.math.MathException; |
17 | 18 |
18 import org.apache.commons.math.optimization.fitting.CurveFitter; | 19 import org.apache.commons.math.optimization.fitting.CurveFitter; |
19 | 20 |
21 import org.apache.commons.math.optimization.general.AbstractLeastSquaresOptimizer; | |
22 import org.apache.commons.math.optimization.general.GaussNewtonOptimizer; | |
20 import org.apache.commons.math.optimization.general.LevenbergMarquardtOptimizer; | 23 import org.apache.commons.math.optimization.general.LevenbergMarquardtOptimizer; |
21 | 24 |
22 import org.apache.log4j.Logger; | 25 import org.apache.log4j.Logger; |
23 | 26 |
24 public class Fitting | 27 public class Fitting |
25 implements Outlier.Callback | 28 implements Outlier.Callback |
26 { | 29 { |
30 // XXX: Hack to force linear fitting! | |
31 private static final boolean USE_NON_LINEAR_FITTING = | |
32 Boolean.getBoolean("minfo.sq.fitting.nonlinear"); | |
33 | |
27 private static Logger log = Logger.getLogger(Fitting.class); | 34 private static Logger log = Logger.getLogger(Fitting.class); |
28 | 35 |
29 public interface Callback { | 36 public interface Callback { |
30 | 37 |
31 void afterIteration( | 38 void afterIteration( |
73 } | 80 } |
74 | 81 |
75 @Override | 82 @Override |
76 public void initialize(List<SQ> sqs) throws MathException { | 83 public void initialize(List<SQ> sqs) throws MathException { |
77 | 84 |
78 LevenbergMarquardtOptimizer lmo = | 85 AbstractLeastSquaresOptimizer optimizer = getOptimizer(); |
79 new LevenbergMarquardtOptimizer(); | |
80 | 86 |
81 CurveFitter cf = new CurveFitter(lmo); | 87 CurveFitter cf = new CurveFitter(optimizer); |
88 double [] values = new double[2]; | |
82 for (SQ sq: sqs) { | 89 for (SQ sq: sqs) { |
83 cf.addObservedPoint(sq.getQ(), sq.getS()); | 90 values[0] = sq.getQ(); |
91 values[1] = sq.getS(); | |
92 transformInputValues(values); | |
93 cf.addObservedPoint(values[0], values[1]); | |
84 } | 94 } |
85 | 95 |
86 coeffs = cf.fit( | 96 coeffs = cf.fit( |
87 function, function.getInitialGuess()); | 97 function, function.getInitialGuess()); |
88 | 98 |
99 transformCoeffsBack(coeffs); | |
100 | |
89 instance = function.instantiate(coeffs); | 101 instance = function.instantiate(coeffs); |
90 | 102 |
91 chiSqr = lmo.getChiSquare(); | 103 chiSqr = optimizer.getChiSquare(); |
104 } | |
105 | |
106 protected Function getFunction(Function function) { | |
107 return USE_NON_LINEAR_FITTING | |
108 ? function | |
109 : Linear.INSTANCE; | |
110 } | |
111 | |
112 protected void transformInputValues(double [] values) { | |
113 if (!USE_NON_LINEAR_FITTING) { | |
114 for (int i = 0; i < values.length; ++i) { | |
115 values[i] = Math.log(values[i]); | |
116 } | |
117 } | |
118 } | |
119 | |
120 protected AbstractLeastSquaresOptimizer getOptimizer() { | |
121 return USE_NON_LINEAR_FITTING | |
122 ? new LevenbergMarquardtOptimizer() | |
123 : new GaussNewtonOptimizer(false); | |
124 } | |
125 | |
126 protected void transformCoeffsBack(double [] coeffs) { | |
127 if (!USE_NON_LINEAR_FITTING && coeffs.length > 0) { | |
128 coeffs[0] = Math.exp(coeffs[0]); | |
129 } | |
92 } | 130 } |
93 | 131 |
94 @Override | 132 @Override |
95 public double eval(SQ sq) { | 133 public double eval(SQ sq) { |
96 double s = instance.value(sq.q); | 134 double s = instance.value(sq.q); |