view flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/extreme/Curve.java @ 4259:5cc9453456a7

First complete but untested version of the 'Auslagerung extremer Wasserspiegellagen' calculation.
author Sascha L. Teichmann <teichmann@intevation.de>
date Thu, 25 Oct 2012 17:25:37 +0200
parents 467efea19d15
children 2e8e00026059
line wrap: on
line source
package de.intevation.flys.artifacts.model.extreme;

import de.intevation.flys.artifacts.math.Function;
import de.intevation.flys.artifacts.math.NaNFunction;
import de.intevation.flys.artifacts.math.UnivariateRealFunctionFunction;

import de.intevation.flys.artifacts.math.fitting.FunctionFactory;

import java.io.Serializable;

import java.lang.ref.SoftReference;

import org.apache.commons.math.analysis.interpolation.SplineInterpolator;

import org.apache.commons.math.exception.MathIllegalArgumentException;

import org.apache.log4j.Logger;

public class Curve
implements   Serializable, Function
{
    private static Logger log = Logger.getLogger(Curve.class);

    protected double [] qs;
    protected double [] ws;
    protected String    function;
    protected double [] coeffs;
    protected double    chiSqr;

    // The spline is pretty heavy weight so cache it with a soft ref only.
    protected transient SoftReference<Function> spline;
    protected transient Function                extrapolation;

    public Curve() {
    }

    public Curve(
        double [] qs,
        double [] ws,
        String    function,
        double [] coeffs,
        double    chiSqr
    ) {
        this.qs       = qs;
        this.ws       = ws;
        this.function = function;
        this.coeffs   = coeffs;
    }

    public double [] getQs() {
        return qs;
    }

    public double [] getWs() {
        return ws;
    }

    public String getFunction() {
        return function;
    }

    public double [] getCoeffs() {
        return coeffs;
    }

    @Override
    public double value(double x) {
        if (x < qs[0]) return Double.NaN;
        return (x <= qs[qs.length-1]
            ? getSpline()
            : getExtrapolation()).value(x);
    }

    protected synchronized Function getExtrapolation() {
        if (extrapolation == null) {
            de.intevation.flys.artifacts.math.fitting.Function
                f = FunctionFactory.getInstance().getFunction(function);

            extrapolation = f != null
                ? f.instantiate(coeffs)
                : NaNFunction.INSTANCE;
        }
        return extrapolation;
    }

    /**
     * Gets the chiSqr for this instance.
     *
     * @return The chiSqr.
     */
    public double getChiSqr() {
        return this.chiSqr;
    }

    /**
     * Sets the chiSqr for this instance.
     *
     * @param chiSqr The chiSqr.
     */
    public void setChiSqr(double chiSqr) {
        this.chiSqr = chiSqr;
    }

    protected synchronized Function getSpline() {
        Function sp;
        if (spline != null) {
            if ((sp = spline.get()) != null) {
                return sp;
            }
        }
        spline = new SoftReference<Function>(sp = createSpline());
        return sp;
    }

    protected Function createSpline() {
        SplineInterpolator interpolator = new SplineInterpolator();
        try {
            return new UnivariateRealFunctionFunction(
                interpolator.interpolate(qs, ws));
        }
        catch (MathIllegalArgumentException miae) {
            log.debug("creation on spline failed", miae);
            return NaNFunction.INSTANCE;
        }
    }
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :

http://dive4elements.wald.intevation.org