# HG changeset patch # User Sascha L. Teichmann # Date 1347128373 0 # Node ID 893b2477208f7244184b5a10050ec105abf359e7 # Parent fe29b0226faff8bd82cdbfe4c32a5eeeaf7d4dcc Some first models needed for the extreme waterlevels. flys-artifacts/trunk@5406 c6561f87-3c4e-4783-a992-168aeb5c3f6f diff -r fe29b0226faf -r 893b2477208f flys-artifacts/ChangeLog --- 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 + + 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 * src/main/java/de/intevation/flys/artifacts/states/DefaultState.java, diff -r fe29b0226faf -r 893b2477208f flys-artifacts/src/main/java/de/intevation/flys/artifacts/math/NaNFunction.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 : diff -r fe29b0226faf -r 893b2477208f flys-artifacts/src/main/java/de/intevation/flys/artifacts/math/UnivariateRealFunctionFunction.java --- /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 : diff -r fe29b0226faf -r 893b2477208f flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/extreme/Curve.java --- /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 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 :