view artifacts/src/main/java/org/dive4elements/river/artifacts/model/fixings/LevenbergMarquardtFittingOperation.java @ 9648:c5a496bf1b0b

Fixed: Duplizieren einer Fixierungsanalyse schlägt fehl.
author Gernot Belger <g.belger@bjoernsen.de>
date Wed, 04 Dec 2019 16:10:28 +0100
parents 0380717105ba
children
line wrap: on
line source
/** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
 * Software engineering by
 *  Björnsen Beratende Ingenieure GmbH
 *  Dr. Schumacher Ingenieurbüro für Wasser und Umwelt
 *
 * This file is Free Software under the GNU AGPL (>=v3)
 * and comes with ABSOLUTELY NO WARRANTY! Check out the
 * documentation coming with Dive4Elements River for details.
 */
package org.dive4elements.river.artifacts.model.fixings;

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;
import org.dive4elements.river.artifacts.math.fitting.Function;

/**
 * @author Gernot Belger
 */
final class LevenbergMarquardtFittingOperation extends AbstractFittingOperation implements IFittingOperation {

    private static Logger log = Logger.getLogger(LevenbergMarquardtFittingOperation.class);

    public LevenbergMarquardtFittingOperation(final Function function) {
        super(function);
    }

    @Override
    public Fitting execute(final List<FittingData> data) {

        final Function function = getFunction();

        for (double tolerance = 1e-10; tolerance < 1e-1; tolerance *= 10d) {

            final LevenbergMarquardtOptimizer lmo = new LevenbergMarquardtOptimizer();
            lmo.setCostRelativeTolerance(tolerance);
            lmo.setOrthoTolerance(tolerance);
            lmo.setParRelativeTolerance(tolerance);

            try {
                final CurveFitter cf = new CurveFitter(lmo);

                for (final FittingData fittingData : data)
                    cf.addObservedPoint(fittingData.q, fittingData.w);

                final double[] parameters = cf.fit(function, function.getInitialGuess());

                return createFitting(parameters, lmo.getChiSquare(), data);
            }
            catch (final MathException me) {
                if (log.isDebugEnabled()) {
                    log.debug("tolerance " + tolerance + " + failed.", me);
                }
            }
        }

        return null;
    }
}

http://dive4elements.wald.intevation.org