Mercurial > dive4elements > river
diff artifacts/src/main/java/org/dive4elements/river/artifacts/model/fixings/Fitting.java @ 9646:0380717105ba
Implemented alternative fitting strategy for Log-Linear function.
author | Gernot Belger <g.belger@bjoernsen.de> |
---|---|
date | Mon, 02 Dec 2019 17:56:15 +0100 |
parents | bc50ecfc58c5 |
children |
line wrap: on
line diff
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/model/fixings/Fitting.java Mon Dec 02 17:21:43 2019 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/model/fixings/Fitting.java Mon Dec 02 17:56:15 2019 +0100 @@ -12,13 +12,10 @@ import java.util.Date; 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.commons.math.stat.descriptive.moment.StandardDeviation; import org.apache.log4j.Logger; import org.dive4elements.river.artifacts.math.GrubbsOutlier; import org.dive4elements.river.artifacts.math.fitting.Function; +import org.dive4elements.river.artifacts.math.fitting.LogLinearAlternative; public class Fitting { private static Logger log = Logger.getLogger(Fitting.class); @@ -28,20 +25,6 @@ QWD create(double q, double w, double deltaW, boolean isOutlier); } - private static final class FittingData { - public final FixingColumnWithData event; - public final double w; - public final double q; - public final boolean isInterpolated; - - public FittingData(final FixingColumnWithData event, final double w, final double q, final boolean isInterpolated) { - this.event = event; - this.w = w; - this.q = q; - this.isInterpolated = isInterpolated; - } - } - private final double chiSqr; private final double[] parameters; @@ -101,37 +84,14 @@ final List<FittingData> outliers = new ArrayList<>(data.size()); org.dive4elements.river.artifacts.math.Function instance = null; - LevenbergMarquardtOptimizer lmo = null; - double[] parameters = null; + Fitting fitting = null; + final IFittingOperation operation = createOperation(function); for (;;) { - parameters = null; - - for (double tolerance = 1e-10; tolerance < 1e-1; tolerance *= 10d) { - - lmo = new LevenbergMarquardtOptimizer(); - lmo.setCostRelativeTolerance(tolerance); - lmo.setOrthoTolerance(tolerance); - lmo.setParRelativeTolerance(tolerance); - - try { - final CurveFitter cf = new CurveFitter(lmo); + fitting = operation.execute(data); - for (final FittingData fittingData : data) - cf.addObservedPoint(fittingData.q, fittingData.w); - - parameters = cf.fit(function, function.getInitialGuess()); - break; - } - catch (final MathException me) { - if (log.isDebugEnabled()) { - log.debug("tolerance " + tolerance + " + failed.", me); - } - } - } - - if (parameters == null) { + if (fitting == null) { /* * log.debug("Parameters is null"); * for (int i = 0, N = xs.size(); i < N; ++i) { @@ -142,6 +102,7 @@ } // This is the parameterized function for a given km. + final double[] parameters = fitting.getParameters(); instance = function.instantiate(parameters); if (!checkOutliers) @@ -180,30 +141,24 @@ } /* - * calculate dW of used values against the resulting function and add them to results , also calculate standard * - * deviation + * calculate dW of used values against the resulting function and add them to results */ - final StandardDeviation stdDev = new StandardDeviation(); - double maxQ = -Double.MAX_VALUE; - for (final FittingData fittingData : data) { final QWD qwd = createQWD(fittingData, instance, false); qwds.add(qwd); resultColumns.addQWD(fittingData.event, km, qwd); - - stdDev.increment(qwd.getDeltaW()); - - final double q = qwd.getQ(); - if (q > maxQ) - maxQ = q; } - final double standardDeviation = stdDev.getResult(); + return fitting; + } - final double chiSqr = lmo.getChiSquare(); + private static IFittingOperation createOperation(final Function function) { - return new Fitting(parameters, standardDeviation, chiSqr, maxQ); + if (function instanceof LogLinearAlternative) + return new LogLinearFittingOperation((LogLinearAlternative) function); + + return new LevenbergMarquardtFittingOperation(function); } private static QWD createQWD(final FittingData data, final org.dive4elements.river.artifacts.math.Function function, final boolean isOutlier) {