Mercurial > dive4elements > river
view flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/extreme/Curve.java @ 3733:893b2477208f
Some first models needed for the extreme waterlevels.
flys-artifacts/trunk@5406 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Sat, 08 Sep 2012 18:19:33 +0000 |
parents | |
children | 976be312a84c |
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 de.intevation.flys.artifacts.model.QW; 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 QW [] qws; protected String function; protected double [] coeffs; // 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(QW [] qws, String function, double [] coeffs) { this.qws = qws; this.function = function; this.coeffs = coeffs; } public QW [] getQWs() { return qws; } public String getFunction() { return function; } public double [] getCoeffs() { return coeffs; } @Override public double value(double x) { if (x < qws[0].getQ()) return Double.NaN; return (x <= qws[qws.length-1].getQ() ? 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; } protected synchronized Function getSpline() { Function sp; if (spline != null) { if ((sp = spline.get()) != null) { return sp; } } spline = new SoftReference(sp = createSpline()); return sp; } protected Function createSpline() { SplineInterpolator interpolator = new SplineInterpolator(); double [] qs = new double[qws.length]; double [] ws = new double[qws.length]; for (int i = 0; i < qws.length; ++i) { QW qw = qws[i]; qs[i] = qw.getQ(); ws[i] = qw.getW(); } 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 :