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 :

http://dive4elements.wald.intevation.org