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 de.intevation.flys.artifacts.model.QW; 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: 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@3733: protected QW [] qws; sascha@3733: protected String function; sascha@3733: protected double [] coeffs; 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@3733: public Curve(QW [] qws, String function, double [] coeffs) { sascha@3733: this.qws = qws; sascha@3733: this.function = function; sascha@3733: this.coeffs = coeffs; sascha@3733: } sascha@3733: sascha@3733: public QW [] getQWs() { sascha@3733: return qws; 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: sascha@3733: @Override sascha@3733: public double value(double x) { sascha@3733: if (x < qws[0].getQ()) return Double.NaN; sascha@3733: return (x <= qws[qws.length-1].getQ() 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: 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@3733: 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: double [] qs = new double[qws.length]; sascha@3733: double [] ws = new double[qws.length]; sascha@3733: for (int i = 0; i < qws.length; ++i) { sascha@3733: QW qw = qws[i]; sascha@3733: qs[i] = qw.getQ(); sascha@3733: ws[i] = qw.getW(); sascha@3733: } 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 :