changeset 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 fe29b0226faf
children 0c217de0d84b
files flys-artifacts/ChangeLog flys-artifacts/src/main/java/de/intevation/flys/artifacts/math/NaNFunction.java flys-artifacts/src/main/java/de/intevation/flys/artifacts/math/UnivariateRealFunctionFunction.java flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/extreme/Curve.java
diffstat 4 files changed, 174 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/flys-artifacts/ChangeLog	Sat Sep 08 15:58:08 2012 +0000
+++ b/flys-artifacts/ChangeLog	Sat Sep 08 18:19:33 2012 +0000
@@ -1,3 +1,22 @@
+2012-09-08	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	Some models for representing results for the upcoming
+	"Auslagerung extremer Wasserspiegellagen". Work im progress.
+
+	* src/main/java/de/intevation/flys/artifacts/math/NaNFunction.java:
+	  New. Function always return NaNs.
+
+	* src/main/java/de/intevation/flys/artifacts/math/UnivariateRealFunctionFunction.java:
+	  New. Adapter to bridge between our Functions and UnivariateRealFunctions
+	  of Apache Common Math.
+
+	* src/main/java/de/intevation/flys/artifacts/model/extreme/Curve.java:
+	  New. Part of the result model of "Auslagerung extremer Wasserspiegellagen".
+	  Its a function for a given km that uses a spline interpolation
+	  for the tabulated Q range (which is effectively the same as the
+	  calculated discharge curve for this km) and an extrapolated
+	  function beyond the tabulated values.
+
 2012-09-08	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
 
 	* src/main/java/de/intevation/flys/artifacts/states/DefaultState.java,
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/math/NaNFunction.java	Sat Sep 08 18:19:33 2012 +0000
@@ -0,0 +1,16 @@
+package de.intevation.flys.artifacts.math;
+
+public final class NaNFunction
+implements         Function
+{
+    public static final Function INSTANCE = new NaNFunction();
+
+    private NaNFunction() {
+    }
+
+    @Override
+    public double value(double x) {
+        return Double.NaN;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/math/UnivariateRealFunctionFunction.java	Sat Sep 08 18:19:33 2012 +0000
@@ -0,0 +1,34 @@
+package de.intevation.flys.artifacts.math;
+
+import org.apache.commons.math.FunctionEvaluationException;
+
+import org.apache.commons.math.analysis.UnivariateRealFunction;
+
+public final class UnivariateRealFunctionFunction
+implements         Function
+{
+    private UnivariateRealFunction function;
+
+    public UnivariateRealFunctionFunction(UnivariateRealFunction function) {
+        this.function = function;
+    }
+
+    @Override
+    public double value(double x) {
+        try {
+            return function.value(x);
+        }
+        catch (FunctionEvaluationException fee) {
+            return Double.NaN;
+        }
+    }
+
+    public UnivariateRealFunction getFunction() {
+        return function;
+    }
+
+    public void setFunction(UnivariateRealFunction function) {
+        this.function = function;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /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