Mercurial > dive4elements > river
diff 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 diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/extreme/Curve.java Sat Sep 08 18:19:33 2012 +0000 @@ -0,0 +1,105 @@ +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 :