sascha@3733: package de.intevation.flys.artifacts.model.extreme; sascha@3733: sascha@3733: import de.intevation.flys.artifacts.math.Function; sascha@3733: import de.intevation.flys.artifacts.math.NaNFunction; sascha@3733: import de.intevation.flys.artifacts.math.UnivariateRealFunctionFunction; sascha@3733: sascha@3733: import de.intevation.flys.artifacts.math.fitting.FunctionFactory; sascha@3733: sascha@3733: import java.io.Serializable; sascha@3733: sascha@3733: import java.lang.ref.SoftReference; sascha@3733: sascha@3733: import org.apache.commons.math.analysis.interpolation.SplineInterpolator; sascha@3733: sascha@3733: import org.apache.commons.math.exception.MathIllegalArgumentException; sascha@3733: sascha@3733: import org.apache.log4j.Logger; sascha@3733: felix@4311: /** An extrapolating W/Q function/curve. */ sascha@3733: public class Curve sascha@3733: implements Serializable, Function sascha@3733: { sascha@3733: private static Logger log = Logger.getLogger(Curve.class); sascha@3733: sascha@3737: protected double [] qs; sascha@3737: protected double [] ws; sascha@3733: protected String function; sascha@3733: protected double [] coeffs; teichmann@4259: protected double chiSqr; sascha@3733: sascha@3733: // The spline is pretty heavy weight so cache it with a soft ref only. sascha@3733: protected transient SoftReference spline; sascha@3733: protected transient Function extrapolation; sascha@3733: sascha@3733: public Curve() { sascha@3733: } sascha@3733: sascha@3737: public Curve( sascha@3737: double [] qs, sascha@3737: double [] ws, sascha@3737: String function, teichmann@4259: double [] coeffs, teichmann@4259: double chiSqr sascha@3737: ) { sascha@3737: this.qs = qs; sascha@3737: this.ws = ws; sascha@3733: this.function = function; sascha@3733: this.coeffs = coeffs; sascha@3733: } sascha@3733: sascha@3737: public double [] getQs() { sascha@3737: return qs; sascha@3737: } sascha@3737: sascha@3737: public double [] getWs() { sascha@3737: return ws; sascha@3733: } sascha@3733: sascha@3733: public String getFunction() { sascha@3733: return function; sascha@3733: } sascha@3733: sascha@3733: public double [] getCoeffs() { sascha@3733: return coeffs; sascha@3733: } sascha@3733: felix@4307: felix@4307: /** Calculate value at given x. */ sascha@3733: @Override sascha@3733: public double value(double x) { sascha@3737: if (x < qs[0]) return Double.NaN; sascha@3737: return (x <= qs[qs.length-1] sascha@3733: ? getSpline() sascha@3733: : getExtrapolation()).value(x); sascha@3733: } sascha@3733: sascha@3733: protected synchronized Function getExtrapolation() { sascha@3733: if (extrapolation == null) { sascha@3733: de.intevation.flys.artifacts.math.fitting.Function sascha@3733: f = FunctionFactory.getInstance().getFunction(function); sascha@3733: sascha@3733: extrapolation = f != null sascha@3733: ? f.instantiate(coeffs) sascha@3733: : NaNFunction.INSTANCE; sascha@3733: } sascha@3733: return extrapolation; sascha@3733: } sascha@3733: teichmann@4259: /** teichmann@4259: * Gets the chiSqr for this instance. teichmann@4259: * teichmann@4259: * @return The chiSqr. teichmann@4259: */ teichmann@4259: public double getChiSqr() { teichmann@4259: return this.chiSqr; teichmann@4259: } teichmann@4259: teichmann@4259: /** teichmann@4259: * Sets the chiSqr for this instance. teichmann@4259: * teichmann@4259: * @param chiSqr The chiSqr. teichmann@4259: */ teichmann@4259: public void setChiSqr(double chiSqr) { teichmann@4259: this.chiSqr = chiSqr; teichmann@4259: } teichmann@4259: sascha@3733: protected synchronized Function getSpline() { sascha@3733: Function sp; sascha@3733: if (spline != null) { sascha@3733: if ((sp = spline.get()) != null) { sascha@3733: return sp; sascha@3733: } sascha@3733: } sascha@3742: spline = new SoftReference(sp = createSpline()); sascha@3733: return sp; sascha@3733: } sascha@3733: sascha@3733: protected Function createSpline() { sascha@3733: SplineInterpolator interpolator = new SplineInterpolator(); sascha@3733: try { sascha@3733: return new UnivariateRealFunctionFunction( sascha@3733: interpolator.interpolate(qs, ws)); sascha@3733: } sascha@3733: catch (MathIllegalArgumentException miae) { sascha@3733: log.debug("creation on spline failed", miae); sascha@3733: return NaNFunction.INSTANCE; sascha@3733: } sascha@3733: } sascha@3733: } sascha@3733: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :