Mercurial > dive4elements > river
diff artifacts/src/main/java/org/dive4elements/river/artifacts/model/extreme/Curve.java @ 5838:5aa05a7a34b7
Rename modules to more fitting names.
author | Sascha L. Teichmann <teichmann@intevation.de> |
---|---|
date | Thu, 25 Apr 2013 15:23:37 +0200 |
parents | flys-artifacts/src/main/java/org/dive4elements/river/artifacts/model/extreme/Curve.java@bd047b71ab37 |
children | 4897a58c8746 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/model/extreme/Curve.java Thu Apr 25 15:23:37 2013 +0200 @@ -0,0 +1,144 @@ +package org.dive4elements.river.artifacts.model.extreme; + +import org.dive4elements.river.artifacts.math.Function; +import org.dive4elements.river.artifacts.math.NaNFunction; +import org.dive4elements.river.artifacts.math.UnivariateRealFunctionFunction; + +import org.dive4elements.river.artifacts.math.fitting.FunctionFactory; + +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; + +/** An extrapolating W/Q function/curve. */ +public class Curve +implements Serializable, Function +{ + private static Logger log = Logger.getLogger(Curve.class); + + protected double [] qs; + protected double [] ws; + protected String function; + protected double [] coeffs; + protected double chiSqr; + + /** Suggested maximum value for q to input. */ + protected double suggestedMaxQ; + + // 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( + double [] qs, + double [] ws, + String function, + double [] coeffs, + double chiSqr + ) { + this.qs = qs; + this.ws = ws; + this.function = function; + this.coeffs = coeffs; + this.suggestedMaxQ = Double.MAX_VALUE; + } + + public double [] getQs() { + return qs; + } + + public double [] getWs() { + return ws; + } + + public String getFunction() { + return function; + } + + public double [] getCoeffs() { + return coeffs; + } + + + public void setSuggestedMaxQ(double newMaxQ) { + this.suggestedMaxQ = newMaxQ; + } + + + public double getSuggestedMaxQ() { + return this.suggestedMaxQ; + } + + + /** Calculate value at given x. */ + @Override + public double value(double x) { + if (qs == null || x < qs[0]) return Double.NaN; + return (x <= qs[qs.length-1] + ? getSpline() + : getExtrapolation()).value(x); + } + + protected synchronized Function getExtrapolation() { + if (extrapolation == null) { + org.dive4elements.river.artifacts.math.fitting.Function + f = FunctionFactory.getInstance().getFunction(function); + + extrapolation = f != null + ? f.instantiate(coeffs) + : NaNFunction.INSTANCE; + } + return extrapolation; + } + + /** + * Gets the chiSqr for this instance. + * + * @return The chiSqr. + */ + public double getChiSqr() { + return this.chiSqr; + } + + /** + * Sets the chiSqr for this instance. + * + * @param chiSqr The chiSqr. + */ + public void setChiSqr(double chiSqr) { + this.chiSqr = chiSqr; + } + + protected synchronized Function getSpline() { + Function sp; + if (spline != null) { + if ((sp = spline.get()) != null) { + return sp; + } + } + spline = new SoftReference<Function>(sp = createSpline()); + return sp; + } + + protected Function createSpline() { + SplineInterpolator interpolator = new SplineInterpolator(); + 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 :