commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From er...@apache.org
Subject svn commit: r927009 - in /commons/proper/math/trunk/src: main/java/org/apache/commons/math/ main/java/org/apache/commons/math/analysis/interpolation/ main/java/org/apache/commons/math/optimization/fitting/ main/java/org/apache/commons/math/util/ site/x...
Date Wed, 24 Mar 2010 11:14:08 GMT
Author: erans
Date: Wed Mar 24 11:14:07 2010
New Revision: 927009

URL: http://svn.apache.org/viewvc?rev=927009&view=rev
Log:
Issues 356 and 357.

Added:
    commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/BicubicSplineInterpolatingFunction.java
    commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/BivariateRealGridInterpolator.java
    commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/SmoothingBicubicSplineInterpolator.java
    commons/proper/math/trunk/src/test/java/org/apache/commons/math/analysis/interpolation/BicubicSplineInterpolatingFunctionTest.java
    commons/proper/math/trunk/src/test/java/org/apache/commons/math/analysis/interpolation/SmoothingBicubicSplineInterpolatorTest.java
Modified:
    commons/proper/math/trunk/src/main/java/org/apache/commons/math/MessagesResources_fr.java
    commons/proper/math/trunk/src/main/java/org/apache/commons/math/optimization/fitting/CurveFitter.java
    commons/proper/math/trunk/src/main/java/org/apache/commons/math/util/MathUtils.java
    commons/proper/math/trunk/src/site/xdoc/changes.xml
    commons/proper/math/trunk/src/site/xdoc/userguide/analysis.xml
    commons/proper/math/trunk/src/test/java/org/apache/commons/math/util/MathUtilsTest.java

Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math/MessagesResources_fr.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/MessagesResources_fr.java?rev=927009&r1=927008&r2=927009&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math/MessagesResources_fr.java (original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/MessagesResources_fr.java Wed Mar 24 11:14:07 2010
@@ -182,7 +182,13 @@ public class MessagesResources_fr
 
     // org.apache.commons.math.analysis.interpolation.SplineInterpolator
     { "points {0} and {1} are not strictly increasing ({2} >= {3})",
-      "les points {0} et {1} ne sont pas strictements croissants ({2} >= {3})" },
+      "les points {0} et {1} ne sont pas strictement croissants ({2} >= {3})" },
+    { "points {0} and {1} are not strictly decreasing ({2} <= {3})",
+      "les points {0} et {1} ne sont pas strictement d\u00e9croissants ({2} <= {3})" },
+    { "points {0} and {1} are not increasing ({2} > {3})",
+      "les points {0} et {1} ne sont pas croissants ({2} > {3})" },
+    { "points {0} and {1} are not decreasing ({2} < {3})",
+      "les points {0} et {1} ne sont pas d\u00e9croissants ({2} < {3})" },
 
     // org.apache.commons.math.analysis.interpolation.LoessInterpolator
     { "bandwidth must be in the interval [0,1], but got {0}",

Added: commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/BicubicSplineInterpolatingFunction.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/BicubicSplineInterpolatingFunction.java?rev=927009&view=auto
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/BicubicSplineInterpolatingFunction.java (added)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/BicubicSplineInterpolatingFunction.java Wed Mar 24 11:14:07 2010
@@ -0,0 +1,286 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.math.analysis.interpolation;
+
+import org.apache.commons.math.MathException;
+import org.apache.commons.math.util.MathUtils;
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.DimensionMismatchException;
+import org.apache.commons.math.analysis.BivariateRealFunction;
+
+/**
+ * Function that implements the
+ * <a href="http://en.wikipedia.org/wiki/Bicubic_interpolation">
+ * bicubic spline interpolation</a>.
+ *
+ * @version $Revision$ $Date$
+ */
+public class BicubicSplineInterpolatingFunction
+    implements BivariateRealFunction {
+    /**
+     * Matrix to compute the spline coefficients from the function values
+     * and function derivatives values
+     */
+    private final static double[][] aInv = {
+        { 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
+        { 0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0 },
+        { -3,3,0,0,-2,-1,0,0,0,0,0,0,0,0,0,0 },
+        { 2,-2,0,0,1,1,0,0,0,0,0,0,0,0,0,0 },
+        { 0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0 },
+        { 0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0 },
+        { 0,0,0,0,0,0,0,0,-3,3,0,0,-2,-1,0,0 },
+        { 0,0,0,0,0,0,0,0,2,-2,0,0,1,1,0,0 },
+        { -3,0,3,0,0,0,0,0,-2,0,-1,0,0,0,0,0 },
+        { 0,0,0,0,-3,0,3,0,0,0,0,0,-2,0,-1,0 },
+        { 9,-9,-9,9,6,3,-6,-3,6,-6,3,-3,4,2,2,1 },
+        { -6,6,6,-6,-3,-3,3,3,-4,4,-2,2,-2,-2,-1,-1 },
+        { 2,0,-2,0,0,0,0,0,1,0,1,0,0,0,0,0 },
+        { 0,0,0,0,2,0,-2,0,0,0,0,0,1,0,1,0 },
+        { -6,6,6,-6,-4,-2,4,2,-3,3,-3,3,-2,-1,-2,-1 },
+        { 4,-4,-4,4,2,2,-2,-2,2,-2,2,-2,1,1,1,1 }
+    };
+
+    /** Samples x-coordinates */
+    private final double[] xval;
+    /** Samples y-coordinates */
+    private final double[] yval;
+    /** Set of cubic splines pacthing the whole data grid */
+    private final BicubicSplineFunction[][] splines;
+
+    /**
+     * @param x Sample values of the x-coordinate, in increasing order
+     * @param y Sample values of the y-coordinate, in increasing order
+     * @param z Values of the function on every grid point
+     * @param dZdX Values of the partial derivative of function with respect
+     * to x on every grid point
+     * @param dZdY Values of the partial derivative of function with respect
+     * to y on every grid point
+     * @param dZdXdY Values of the cross partial derivative of function on
+     * every grid point
+     * @throws DimensionMismatchException if the various arrays do not contain
+     * the expected number of elements.
+     * @throws IllegalArgumentException if {@code x} or {@code y} are not strictly
+     * increasing.
+     */
+    public BicubicSplineInterpolatingFunction(double[] x,
+                                              double[] y,
+                                              double[][] z,
+                                              double[][] dZdX,
+                                              double[][] dZdY,
+                                              double[][] dZdXdY)
+        throws MathException {
+        final int xLen = x.length;
+        final int yLen = y.length;
+
+        if (xLen == 0 || yLen == 0 || z.length == 0 || z[0].length == 0) {
+            throw MathRuntimeException.createIllegalArgumentException("no data");
+        }
+        if (xLen != z.length) {
+            throw new DimensionMismatchException(xLen, z.length);
+        }
+        if (xLen != dZdX.length) {
+            throw new DimensionMismatchException(xLen, dZdX.length);
+        }
+        if (xLen != dZdY.length) {
+            throw new DimensionMismatchException(xLen, dZdY.length);
+        }
+        if (xLen != dZdXdY.length) {
+            throw new DimensionMismatchException(xLen, dZdXdY.length);
+        }
+
+        MathUtils.checkOrder(x, 1, true);
+        MathUtils.checkOrder(y, 1, true);
+        
+        xval = x.clone();
+        yval = y.clone();
+
+        final int lastI = xLen - 1;
+        final int lastJ = yLen - 1;
+        splines = new BicubicSplineFunction[lastI][lastJ];
+
+        for (int i = 0; i < lastI; i++) {
+            if (z[i].length != yLen) {
+                throw new DimensionMismatchException(z[i].length, yLen);
+            }
+            if (dZdX[i].length != yLen) {
+                throw new DimensionMismatchException(dZdX[i].length, yLen);
+            }
+            if (dZdY[i].length != yLen) {
+                throw new DimensionMismatchException(dZdY[i].length, yLen);
+            }
+            if (dZdXdY[i].length != yLen) {
+                throw new DimensionMismatchException(dZdXdY[i].length, yLen);
+            }
+            final int ip1 = i + 1;
+            for (int j = 0; j < lastJ; j++) {
+                final int jp1 = j + 1;
+                final double[] beta = new double[] {
+                    z[i][j],      z[ip1][j],      z[i][jp1],      z[ip1][jp1],
+                    dZdX[i][j],   dZdX[ip1][j],   dZdX[i][jp1],   dZdX[ip1][jp1],
+                    dZdY[i][j],   dZdY[ip1][j],   dZdY[i][jp1],   dZdY[ip1][jp1],
+                    dZdXdY[i][j], dZdXdY[ip1][j], dZdXdY[i][jp1], dZdXdY[ip1][jp1]
+                };
+
+                splines[i][j] = new BicubicSplineFunction(computeSplineCoefficients(beta));
+            }
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public double value(double x, double y) {
+        final int i = searchIndex(x, xval);
+        if (i == -1) {
+            throw MathRuntimeException.createIllegalArgumentException("{0} out of [{1}, {2}] range",
+                                                                      x, xval[0], xval[xval.length - 1]);
+        }
+        final int j = searchIndex(y, yval);
+        if (j == -1) {
+            throw MathRuntimeException.createIllegalArgumentException("{0} out of [{1}, {2}] range",
+                                                                      y, yval[0], yval[yval.length - 1]);
+        }
+
+        final double xN = (x - xval[i]) / (xval[i + 1] - xval[i]);
+        final double yN = (y - yval[j]) / (yval[j + 1] - yval[j]);
+
+        return splines[i][j].value(xN, yN);
+    }
+
+    /**
+     * @param c coordinate
+     * @param val coordinate samples
+     * @return the index in {@code val} corresponding to the interval
+     * containing {@code c}, or {@code -1} if {@code c} is out of the
+     * range defined by the end values of {@code val}
+     */
+    private int searchIndex(double c, double[] val) {
+        if (c < val[0]) {
+            return -1;
+        }
+
+        for (int i = 1, max = val.length; i < max; i++) {
+            if (c <= val[i]) {
+                return i - 1;
+            }
+        }
+
+        return -1;
+    }
+
+    /**
+     * Compute the spline coefficients from the list of function values and
+     * function partial derivatives values at the four corners of a grid
+     * element. They must be specified in the following order:
+     * <ul>
+     *  <li>f(0,0)</li>
+     *  <li>f(1,0)</li>
+     *  <li>f(0,1)</li>
+     *  <li>f(1,1)</li>
+     *  <li>fx(0,0)</li>
+     *  <li>fx(1,0)</li>
+     *  <li>fx(0,1)</li>
+     *  <li>fx(1,1)</li>
+     *  <li>fy(0,0)</li>
+     *  <li>fy(1,0)</li>
+     *  <li>fy(0,1)</li>
+     *  <li>fy(1,1)</li>
+     *  <li>fxy(0,0)</li>
+     *  <li>fxy(1,0)</li>
+     *  <li>fxy(0,1)</li>
+     *  <li>fxy(1,1)</li>
+     * </ul>
+     * @param beta List of function values and function partial derivatives
+     * values
+     * @return the spline coefficients
+     */
+    private double[] computeSplineCoefficients(double[] beta) {
+        final double[] a = new double[16];
+        
+        for (int i = 0; i < 16; i++) {
+            double result = 0;
+            final double[] row = aInv[i];
+            for (int j = 0; j < 16; j++) {
+                result += row[j] * beta[j];
+            }
+            a[i] = result;
+        }
+
+        return a;
+    }
+}
+
+/**
+ * 2D-spline function.
+ */
+class BicubicSplineFunction
+    implements BivariateRealFunction {
+    /** Coefficients */
+    private final double
+        a00, a01, a02, a03,
+        a10, a11, a12, a13,
+        a20, a21, a22, a23,
+        a30, a31, a32, a33;
+
+    /**
+     * @param a Spline coefficients
+     */
+    public BicubicSplineFunction(double[] a) {
+        this.a00 = a[0];
+        this.a10 = a[1];
+        this.a20 = a[2];
+        this.a30 = a[3];
+        this.a01 = a[4];
+        this.a11 = a[5];
+        this.a21 = a[6];
+        this.a31 = a[7];
+        this.a02 = a[8];
+        this.a12 = a[9];
+        this.a22 = a[10];
+        this.a32 = a[11];
+        this.a03 = a[12];
+        this.a13 = a[13];
+        this.a23 = a[14];
+        this.a33 = a[15];
+    }
+
+    /**
+     * @param x x-coordinate of the interpolation point
+     * @param y y-coordinate of the interpolation point
+     * @return the interpolated value.
+     */
+    public double value(double x, double y) {
+        if (x < 0 || x > 1) {
+            throw MathRuntimeException.createIllegalArgumentException("{0} out of [{1}, {2}] range",
+                                                                      x, 0, 1);
+        }
+        if (y < 0 || y > 1) {
+            throw MathRuntimeException.createIllegalArgumentException("{0} out of [{1}, {2}] range",
+                                                                      y, 0, 1);
+        }
+        
+        final double x2 = x * x;
+        final double x3 = x2 * x;
+        final double y2 = y * y;
+        final double y3 = y2 * y;
+        
+        return a00 + a01 * y + a02 * y2 + a03 * y3
+            + a10 * x + a11 * x * y + a12 * x * y2 + a13 * x * y3
+            + a20 * x2 + a21 * x2 * y + a22 * x2 * y2 + a23 * x2 * y3
+            + a30 * x3 + a31 * x3 * y + a32 * x3 * y2 + a33 * x3 * y3;
+    }
+}

Added: commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/BivariateRealGridInterpolator.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/BivariateRealGridInterpolator.java?rev=927009&view=auto
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/BivariateRealGridInterpolator.java (added)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/BivariateRealGridInterpolator.java Wed Mar 24 11:14:07 2010
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.math.analysis.interpolation;
+
+import org.apache.commons.math.MathException;
+import org.apache.commons.math.analysis.BivariateRealFunction;
+
+/**
+ * Interface representing a bivariate real interpolating function where the
+ * sample points must be specified on a regular grid.
+ *
+ * @version $Revision$ $Date$
+ */
+public interface BivariateRealGridInterpolator {
+
+    /**
+     * Computes an interpolating function for the data set.
+     *
+     * @param xval all the x-coordinates of the interpolation points, sorted
+     * in increasing order.
+     * @param yval all the y-coordinates of the interpolation points, sorted
+     * in increasing order.
+     * @param zval the values of the interpolation points on all the grid knots:
+     * {@code zval[i][j] = f(xval[i], yval[j])}
+     * @return a function which interpolates the data set
+     * @throws MathException if arguments violate assumptions made by the
+     *         interpolation algorithm
+     */
+    BivariateRealFunction interpolate(double[] xval, double[] yval, double[][] zval)
+        throws MathException;
+}

Added: commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/SmoothingBicubicSplineInterpolator.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/SmoothingBicubicSplineInterpolator.java?rev=927009&view=auto
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/SmoothingBicubicSplineInterpolator.java (added)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/SmoothingBicubicSplineInterpolator.java Wed Mar 24 11:14:07 2010
@@ -0,0 +1,170 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.math.analysis.interpolation;
+
+import org.apache.commons.math.DimensionMismatchException;
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.MathException;
+import org.apache.commons.math.util.MathUtils;
+import org.apache.commons.math.analysis.UnivariateRealFunction;
+import org.apache.commons.math.analysis.BivariateRealFunction;
+import org.apache.commons.math.analysis.polynomials.PolynomialSplineFunction;
+
+/**
+ * Generates a bicubic interpolation function.
+ * Before interpolating, smoothing of the input data is performed using
+ * splines.
+ * See <b>Handbook on splines for the user</b>, ISBN 084939404X,
+ * chapter 2.
+ *
+ * @version $Revision$ $Date$
+ */
+public class SmoothingBicubicSplineInterpolator
+    implements BivariateRealGridInterpolator {
+    /**
+     * {@inheritDoc}
+     */
+    public BivariateRealFunction interpolate(final double[] xval,
+                                             final double[] yval,
+                                             final double[][] zval)
+        throws MathException, IllegalArgumentException {
+        if (xval.length == 0 || yval.length == 0 || zval.length == 0) {
+            throw MathRuntimeException.createIllegalArgumentException("no data");
+        }
+        if (xval.length != zval.length) {
+            throw new DimensionMismatchException(xval.length, zval.length);
+        }
+
+        MathUtils.checkOrder(xval, 1, true);
+        MathUtils.checkOrder(yval, 1, true);
+        
+        final int xLen = xval.length;
+        final int yLen = yval.length;
+
+        // Samples (first index is y-coordinate, i.e. subarray variable is x)
+        // 0 <= i < xval.length
+        // 0 <= j < yval.length
+        // zX[j][i] = f(xval[i], yval[j])
+        final double[][] zX = new double[yLen][xLen];
+        for (int i = 0; i < xLen; i++) {
+            if (zval[i].length != yLen) {
+                throw new DimensionMismatchException(zval[i].length, yLen);
+            }
+
+            for (int j = 0; j < yLen; j++) {
+                zX[j][i] = zval[i][j];
+            }
+        }
+
+        final SplineInterpolator spInterpolator = new SplineInterpolator();
+
+        // For each line y[j] (0 <= j < yLen), construct a 1D spline with
+        // respect to variable x
+        final PolynomialSplineFunction[] ySplineX = new PolynomialSplineFunction[yLen];
+        for (int j = 0; j < yLen; j++) {
+            ySplineX[j] = spInterpolator.interpolate(xval, zX[j]);
+        }
+
+        // For every knot (xval[i], yval[j]) of the grid, calculate corrected
+        // values zY_1
+        final double[][] zY_1 = new double[xLen][yLen];
+        for (int j = 0; j < yLen; j++) {
+            final PolynomialSplineFunction f = ySplineX[j];
+            for (int i = 0; i < xLen; i++) {
+                zY_1[i][j] = f.value(xval[i]);
+            }
+        }
+
+        // For each line x[i] (0 <= i < xLen), construct a 1D spline with
+        // respect to variable y generated by array zY_1[i]
+        final PolynomialSplineFunction[] xSplineY = new PolynomialSplineFunction[xLen];
+        for (int i = 0; i < xLen; i++) {
+            xSplineY[i] = spInterpolator.interpolate(yval, zY_1[i]);
+        }
+
+        // For every knot (xval[i], yval[j]) of the grid, calculate corrected
+        // values zY_2
+        final double[][] zY_2 = new double[xLen][yLen];
+        for (int i = 0; i < xLen; i++) {
+            final PolynomialSplineFunction f = xSplineY[i];
+            for (int j = 0; j < yLen; j++) {
+                zY_2[i][j] = f.value(yval[j]);
+            }
+        }
+
+        // Partial derivatives with respect to x at the grid knots
+        final double[][] dZdX = new double[xLen][yLen];
+        for (int j = 0; j < yLen; j++) {
+            final UnivariateRealFunction f = ySplineX[j].derivative();
+            for (int i = 0; i < xLen; i++) {
+                dZdX[i][j] = f.value(xval[i]);
+            }
+        }
+
+        // Partial derivatives with respect to y at the grid knots
+        final double[][] dZdY = new double[xLen][yLen];
+        for (int i = 0; i < xLen; i++) {
+            final UnivariateRealFunction f = xSplineY[i].derivative();
+            for (int j = 0; j < yLen; j++) {
+                dZdY[i][j] = f.value(yval[j]);
+            }
+        }
+
+        // Cross partial derivatives
+        final double[][] dZdXdY = new double[xLen][yLen];
+        for (int i = 0; i < xLen ; i++) {
+            final int nI = nextIndex(i, xLen);
+            final int pI = previousIndex(i);
+            for (int j = 0; j < yLen; j++) {
+                final int nJ = nextIndex(j, yLen);
+                final int pJ = previousIndex(j);
+                dZdXdY[i][j] =  (zY_2[nI][nJ] - zY_2[nI][pJ]
+                                 - zY_2[pI][nJ] + zY_2[pI][pJ])
+                    / ((xval[nI] - xval[pI]) * (yval[nJ] - yval[pJ])) ;
+            }
+        }
+
+        // Create the interpolating splines
+        return new BicubicSplineInterpolatingFunction(xval, yval, zY_2,
+                                                      dZdX, dZdY, dZdXdY);
+    }
+
+    /**
+     * Compute the next index of an array, clipping if necessary.
+     * It is assumed (but not checked) that {@code i} is larger than or equal to 0}.
+     *
+     * @param i Index
+     * @param max Upper limit of the array
+     * @return the next index
+     */
+    private int nextIndex(int i, int max) {
+        final int index = i + 1;
+        return index < max ? index : index - 1;
+    }
+    /**
+     * Compute the previous index of an array, clipping if necessary.
+     * It is assumed (but not checked) that {@code i} is smaller than the size of the array.
+     *
+     * @param i Index
+     * @param max Upper limit of the array
+     * @return the previous index
+     */
+    private int previousIndex(int i) {
+        final int index = i - 1;
+        return index >= 0 ? index : 0;
+    }
+}

Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math/optimization/fitting/CurveFitter.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/optimization/fitting/CurveFitter.java?rev=927009&r1=927008&r2=927009&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math/optimization/fitting/CurveFitter.java (original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/optimization/fitting/CurveFitter.java Wed Mar 24 11:14:07 2010
@@ -103,6 +103,13 @@ public class CurveFitter {
         return observations.toArray(new WeightedObservedPoint[observations.size()]);
     }
 
+    /**
+     * Remove all observations.
+     */
+    public void clearObservations() {
+        observations.clear();
+    }
+
     /** Fit a curve.
      * <p>This method compute the coefficients of the curve that best
      * fit the sample of observed points previously given through calls

Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math/util/MathUtils.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/util/MathUtils.java?rev=927009&r1=927008&r2=927009&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math/util/MathUtils.java (original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/util/MathUtils.java Wed Mar 24 11:14:07 2010
@@ -1788,5 +1788,45 @@ public final class MathUtils {
         return max;
     }
 
+    /**
+     * Checks that the given array is sorted.
+     *
+     * @param val Values
+     * @param dir Order direction (-1 for decreasing, 1 for increasing)
+     * @param strict Whether the order should be strict
+     * @throws IllegalArgumentException if the array is not sorted.
+     */
+    public static void checkOrder(double[] val, int dir, boolean strict) {
+        double previous = val[0];
 
+        for (int i = 1, max = val.length; i < max; i++) {
+            if (dir > 0) {
+                if (strict) {
+                    if (val[i] <= previous) {
+                        throw MathRuntimeException.createIllegalArgumentException("points {0} and {1} are not strictly increasing ({2} >= {3})",
+                                                                                  i - 1, i, previous, val[i]);
+                    }
+                } else {
+                    if (val[i] < previous) {
+                        throw MathRuntimeException.createIllegalArgumentException("points {0} and {1} are not increasing ({2} > {3})",
+                                                                                  i - 1, i, previous, val[i]);
+                    }
+                }
+            } else {
+                if (strict) {
+                    if (val[i] >= previous) {
+                        throw MathRuntimeException.createIllegalArgumentException("points {0} and {1} are not strictly decreasing ({2} <= {3})",
+                                                                                  i - 1, i, previous, val[i]);
+                    }
+                } else {
+                    if (val[i] > previous) {
+                        throw MathRuntimeException.createIllegalArgumentException("points {0} and {1} are not decreasing ({2} < {3})",
+                                                                                  i - 1, i, previous, val[i]);
+                    }
+                }
+            }
+
+            previous = val[i];
+        }
+    }
 }

Modified: commons/proper/math/trunk/src/site/xdoc/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/site/xdoc/changes.xml?rev=927009&r1=927008&r2=927009&view=diff
==============================================================================
--- commons/proper/math/trunk/src/site/xdoc/changes.xml (original)
+++ commons/proper/math/trunk/src/site/xdoc/changes.xml Wed Mar 24 11:14:07 2010
@@ -51,6 +51,12 @@ The <action> type attribute can be add,u
        protected fields have been removed from AbstractLeastSquaresOptimizer, AbstractScalarDifferentiableOptimizer
        and AbstractLinearOptimizer; and the isOptimal(SimplexTableau) method has been removed from
        SimplexSolver. ">
+      <action dev="erans" type="update" issue="MATH-356">
+        Added method to clear the list of observations.
+      </action>
+      <action dev="erans" type="add" issue="MATH-357">
+        Implementation of bicubic interpolation.
+      </action>
       <action dev="psteitz" type="update" issue="MATH-332" due-to="Mikkel Meyer Andersen">
         Added density functions to remaining continuous distributions (F, T, Weibull, Cauchy).
         As of Math 2.1, all continuous distributions implement density functions.  The HasDensity

Modified: commons/proper/math/trunk/src/site/xdoc/userguide/analysis.xml
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/site/xdoc/userguide/analysis.xml?rev=927009&r1=927008&r2=927009&view=diff
==============================================================================
--- commons/proper/math/trunk/src/site/xdoc/userguide/analysis.xml (original)
+++ commons/proper/math/trunk/src/site/xdoc/userguide/analysis.xml Wed Mar 24 11:14:07 2010
@@ -307,6 +307,34 @@ System.out println("f(" + interpolationX
           It has been described in William Dudziak's <a
           href="http://www.dudziak.com/microsphere.pdf">MS thesis</a>.
         </p>
+        <p>
+          A <a href="../apidocs/org/apache/commons/math/analysis/interpolation/BivariateRealGridInterpolator.html">
+          org.apache.commons.math.analysis.interpolation.BivariateRealGridInterpolator</a>
+          is used to find a bivariate real-valued function <code>f</code> which
+          for a given set of tuples
+          (<code>x<sub>i</sub></code>,<code>y<sub>j</sub></code>,<code>z<sub>ij</sub></code>)
+          yields <code>f(x<sub>i</sub>,y<sub>j</sub>)=z<sub>ij</sub></code> to the best accuracy
+          possible. The result is provided as an object implementing the
+          <a href="../apidocs/org/apache/commons/math/analysis/BivariateRealFunction.html">
+          org.apache.commons.math.analysis.BivariateRealFunction</a> interface. It can therefore
+          be evaluated at any point, including a point not belonging to the original set.
+          The array <code>x<sub>i</sub></code> and <code>y<sub>j</sub></code> must be sorted in
+          increasing order in order to define a two-dimensional regular grid.
+        </p>
+        <p>
+          In <a href="../apidocs/org/apache/commons/math/analysis/interpolation/BicubicSplineInterpolatingFunction.html">
+          bicubic interpolation</a>, the interpolation function is a 3rd-degree polynomial of two
+          variables. The coefficients are computed from the function values sampled on a regular grid,
+          as well as the values of the partial derivatives of the function at those grid points.
+        </p>
+        <p>
+          From two-dimensional data sampled on a regular grid, the
+          <a href="../apidocs/org/apache/commons/math/analysis/interpolation/SmoothingBicubicSplineInterpolator.html">
+          org.apache.commons.math.analysis.interpolation.SmoothingBicubicSplineInterpolator</a>
+          computes a <a href="../apidocs/org/apache/commons/math/analysis/interpolation/BicubicSplineInterpolatingFunction.html">
+          bicubic interpolating function</a>. The data is first smoothed, along each grid dimension,
+          using one-dimensional splines.
+        </p>
       </subsection>
       <subsection name="4.4 Integration" href="integration">
         <p>

Added: commons/proper/math/trunk/src/test/java/org/apache/commons/math/analysis/interpolation/BicubicSplineInterpolatingFunctionTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math/analysis/interpolation/BicubicSplineInterpolatingFunctionTest.java?rev=927009&view=auto
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math/analysis/interpolation/BicubicSplineInterpolatingFunctionTest.java (added)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math/analysis/interpolation/BicubicSplineInterpolatingFunctionTest.java Wed Mar 24 11:14:07 2010
@@ -0,0 +1,259 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.math.analysis.interpolation;
+
+import org.apache.commons.math.MathException;
+import org.apache.commons.math.DimensionMismatchException;
+import org.apache.commons.math.analysis.BivariateRealFunction;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Testcase for the bicubic function.
+ * 
+ * @version $Revision: 821626 $ $Date: 2009-10-04 23:57:30 +0200 (Sun, 04 Oct 2009) $ 
+ */
+public final class BicubicSplineInterpolatingFunctionTest {
+    /**
+     * Test preconditions.
+     */
+    @Test
+    public void testPreconditions() throws MathException {
+        double[] xval = new double[] {3, 4, 5, 6.5};
+        double[] yval = new double[] {-4, -3, -1, 2.5};
+        double[][] zval = new double[xval.length][yval.length];
+
+        BivariateRealFunction bcf = new BicubicSplineInterpolatingFunction(xval, yval, zval,
+                                                                           zval, zval, zval);
+        
+        double[] wxval = new double[] {3, 2, 5, 6.5};
+        try {
+            bcf = new BicubicSplineInterpolatingFunction(wxval, yval, zval, zval, zval, zval);
+            Assert.fail("an exception should have been thrown");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        double[] wyval = new double[] {-4, -1, -1, 2.5};
+        try {
+            bcf = new BicubicSplineInterpolatingFunction(xval, wyval, zval, zval, zval, zval);
+            Assert.fail("an exception should have been thrown");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        double[][] wzval = new double[xval.length][yval.length - 1];
+        try {
+            bcf = new BicubicSplineInterpolatingFunction(xval, yval, wzval, zval, zval, zval);
+            Assert.fail("an exception should have been thrown");
+        } catch (DimensionMismatchException e) {
+            // Expected
+        }
+        try {
+            bcf = new BicubicSplineInterpolatingFunction(xval, yval, zval, wzval, zval, zval);
+            Assert.fail("an exception should have been thrown");
+        } catch (DimensionMismatchException e) {
+            // Expected
+        }
+        try {
+            bcf = new BicubicSplineInterpolatingFunction(xval, yval, zval, zval, wzval, zval);
+            Assert.fail("an exception should have been thrown");
+        } catch (DimensionMismatchException e) {
+            // Expected
+        }
+        try {
+            bcf = new BicubicSplineInterpolatingFunction(xval, yval, zval, zval, zval, wzval);
+            Assert.fail("an exception should have been thrown");
+        } catch (DimensionMismatchException e) {
+            // Expected
+        }
+
+        wzval = new double[xval.length - 1][yval.length];
+        try {
+            bcf = new BicubicSplineInterpolatingFunction(xval, yval, wzval, zval, zval, zval);
+            Assert.fail("an exception should have been thrown");
+        } catch (DimensionMismatchException e) {
+            // Expected
+        }
+        try {
+            bcf = new BicubicSplineInterpolatingFunction(xval, yval, zval, wzval, zval, zval);
+            Assert.fail("an exception should have been thrown");
+        } catch (DimensionMismatchException e) {
+            // Expected
+        }
+        try {
+            bcf = new BicubicSplineInterpolatingFunction(xval, yval, zval, zval, wzval, zval);
+            Assert.fail("an exception should have been thrown");
+        } catch (DimensionMismatchException e) {
+            // Expected
+        }
+        try {
+            bcf = new BicubicSplineInterpolatingFunction(xval, yval, zval, zval, zval, wzval);
+            Assert.fail("an exception should have been thrown");
+        } catch (DimensionMismatchException e) {
+            // Expected
+        }
+    }
+
+    /**
+     * Test for a plane.
+     * <p>
+     * z = 2 x - 3 y + 5
+     */
+    @Test
+    public void testPlane() throws MathException {
+        double[] xval = new double[] {3, 4, 5, 6.5};
+        double[] yval = new double[] {-4, -3, -1, 2, 2.5};
+        // Function values
+        BivariateRealFunction f = new BivariateRealFunction() {
+                public double value(double x, double y) {
+                    return 2 * x - 3 * y + 5;
+                }
+            };
+        double[][] zval = new double[xval.length][yval.length];
+        for (int i = 0; i < xval.length; i++) {
+            for (int j = 0; j < yval.length; j++) {
+                zval[i][j] = f.value(xval[i], yval[j]);
+            }
+        }
+        // Partial derivatives with respect to x
+        double[][] dZdX = new double[xval.length][yval.length];
+        for (int i = 0; i < xval.length; i++) {
+            for (int j = 0; j < yval.length; j++) {
+                dZdX[i][j] = 2;
+            }
+        }
+        // Partial derivatives with respect to y
+        double[][] dZdY = new double[xval.length][yval.length];
+        for (int i = 0; i < xval.length; i++) {
+            for (int j = 0; j < yval.length; j++) {
+                dZdY[i][j] = -3;
+            }
+        }
+        // Partial cross-derivatives
+        double[][] dZdXdY = new double[xval.length][yval.length];
+        for (int i = 0; i < xval.length; i++) {
+            for (int j = 0; j < yval.length; j++) {
+                dZdXdY[i][j] = 0;
+            }
+        }
+
+        BivariateRealFunction bcf = new BicubicSplineInterpolatingFunction(xval, yval, zval,
+                                                                           dZdX, dZdY, dZdXdY);
+        double x, y;
+        double expected, result;
+
+        x = 4;
+        y = -3;
+        expected = f.value(x, y);
+        result = bcf.value(x, y);
+        Assert.assertEquals("On sample point",
+                            expected, result, 1e-15);
+
+        x = 4.5;
+        y = -1.5;
+        expected = f.value(x, y);
+        result = bcf.value(x, y);
+        Assert.assertEquals("Half-way between sample points (middle of the patch)",
+                            expected, result, 0.3);
+
+        x = 3.5;
+        y = -3.5;
+        expected = f.value(x, y);
+        result = bcf.value(x, y);
+        Assert.assertEquals("Half-way between sample points (border of the patch)",
+                            expected, result, 0.3);
+    }
+
+    /**
+     * Test for a paraboloid.
+     * <p>
+     * z = 2 x<sup>2</sup> - 3 y<sup>2</sup> + 4 x y - 5
+     */
+    @Test
+    public void testParaboloid() throws MathException {
+        double[] xval = new double[] {3, 4, 5, 6.5};
+        double[] yval = new double[] {-4, -3, -1, 2, 2.5};
+        // Function values
+        BivariateRealFunction f = new BivariateRealFunction() {
+                public double value(double x, double y) {
+                    return 2 * x * x - 3 * y * y + 4 * x * y - 5;
+                }
+            };
+        double[][] zval = new double[xval.length][yval.length];
+        for (int i = 0; i < xval.length; i++) {
+            for (int j = 0; j < yval.length; j++) {
+                zval[i][j] = f.value(xval[i], yval[j]);
+            }
+        }
+        // Partial derivatives with respect to x
+        double[][] dZdX = new double[xval.length][yval.length];
+        BivariateRealFunction dfdX = new BivariateRealFunction() {
+                public double value(double x, double y) {
+                    return 4 * (x + y);
+                }
+            };
+        for (int i = 0; i < xval.length; i++) {
+            for (int j = 0; j < yval.length; j++) {
+                dZdX[i][j] = dfdX.value(xval[i], yval[j]);
+            }
+        }
+        // Partial derivatives with respect to y
+        double[][] dZdY = new double[xval.length][yval.length];
+        BivariateRealFunction dfdY = new BivariateRealFunction() {
+                public double value(double x, double y) {
+                    return 4 * x - 6 * y;
+                }
+            };
+        for (int i = 0; i < xval.length; i++) {
+            for (int j = 0; j < yval.length; j++) {
+                dZdY[i][j] = dfdY.value(xval[i], yval[j]);
+            }
+        }
+        // Partial cross-derivatives
+        double[][] dZdXdY = new double[xval.length][yval.length];
+        for (int i = 0; i < xval.length; i++) {
+            for (int j = 0; j < yval.length; j++) {
+                dZdXdY[i][j] = 4;
+            }
+        }
+
+        BivariateRealFunction bcf = new BicubicSplineInterpolatingFunction(xval, yval, zval,
+                                                                           dZdX, dZdY, dZdXdY);
+        double x, y;
+        double expected, result;
+        
+        x = 4;
+        y = -3;
+        expected = f.value(x, y);
+        result = bcf.value(x, y);
+        Assert.assertEquals("On sample point",
+                            expected, result, 1e-15);
+
+        x = 4.5;
+        y = -1.5;
+        expected = f.value(x, y);
+        result = bcf.value(x, y);
+        Assert.assertEquals("Half-way between sample points (middle of the patch)",
+                            expected, result, 2);
+
+        x = 3.5;
+        y = -3.5;
+        expected = f.value(x, y);
+        result = bcf.value(x, y);
+        Assert.assertEquals("Half-way between sample points (border of the patch)",
+                            expected, result, 2);
+    }
+}

Added: commons/proper/math/trunk/src/test/java/org/apache/commons/math/analysis/interpolation/SmoothingBicubicSplineInterpolatorTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math/analysis/interpolation/SmoothingBicubicSplineInterpolatorTest.java?rev=927009&view=auto
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math/analysis/interpolation/SmoothingBicubicSplineInterpolatorTest.java (added)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math/analysis/interpolation/SmoothingBicubicSplineInterpolatorTest.java Wed Mar 24 11:14:07 2010
@@ -0,0 +1,176 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.math.analysis.interpolation;
+
+import org.apache.commons.math.MathException;
+import org.apache.commons.math.DimensionMismatchException;
+import org.apache.commons.math.analysis.BivariateRealFunction;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Testcase for the bicubic interpolator.
+ * 
+ * @version $Revision: 821626 $ $Date: 2009-10-04 23:57:30 +0200 (Sun, 04 Oct 2009) $ 
+ */
+public final class SmoothingBicubicSplineInterpolatorTest {
+    /**
+     * Test preconditions.
+     */
+    @Test
+    public void testPreconditions() throws MathException {
+        double[] xval = new double[] {3, 4, 5, 6.5};
+        double[] yval = new double[] {-4, -3, -1, 2.5};
+        double[][] zval = new double[xval.length][yval.length];
+
+        BivariateRealGridInterpolator interpolator = new SmoothingBicubicSplineInterpolator();
+        
+        BivariateRealFunction p = interpolator.interpolate(xval, yval, zval);
+        
+        double[] wxval = new double[] {3, 2, 5, 6.5};
+        try {
+            p = interpolator.interpolate(wxval, yval, zval);
+            Assert.fail("an exception should have been thrown");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        double[] wyval = new double[] {-4, -3, -1, -1};
+        try {
+            p = interpolator.interpolate(xval, wyval, zval);
+            Assert.fail("an exception should have been thrown");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        double[][] wzval = new double[xval.length][yval.length + 1];
+        try {
+            p = interpolator.interpolate(xval, wyval, zval);
+            Assert.fail("an exception should have been thrown");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        wzval = new double[xval.length - 1][yval.length];
+        try {
+            p = interpolator.interpolate(xval, yval, wzval);
+            Assert.fail("an exception should have been thrown");
+        } catch (DimensionMismatchException e) {
+            // Expected
+        }
+        wzval = new double[xval.length][yval.length - 1];
+        try {
+            p = interpolator.interpolate(xval, yval, wzval);
+            Assert.fail("an exception should have been thrown");
+        } catch (DimensionMismatchException e) {
+            // Expected
+        }
+    }
+
+    /**
+     * Test of interpolator for a plane.
+     * <p>
+     * z = 2 x - 3 y + 5
+     */
+    @Test
+    public void testPlane() throws MathException {
+        BivariateRealFunction f = new BivariateRealFunction() {
+                public double value(double x, double y) {
+                    return 2 * x - 3 * y + 5;
+                }
+            };
+
+        BivariateRealGridInterpolator interpolator = new SmoothingBicubicSplineInterpolator();
+
+        double[] xval = new double[] {3, 4, 5, 6.5};
+        double[] yval = new double[] {-4, -3, -1, 2, 2.5};
+        double[][] zval = new double[xval.length][yval.length];
+        for (int i = 0; i < xval.length; i++) {
+            for (int j = 0; j < yval.length; j++) {
+                zval[i][j] = f.value(xval[i], yval[j]);
+            }
+        }
+
+        BivariateRealFunction p = interpolator.interpolate(xval, yval, zval);
+        double x, y;
+        double expected, result;
+        
+        x = 4;
+        y = -3;
+        expected = f.value(x, y);
+        result = p.value(x, y);
+        Assert.assertEquals("On sample point", expected, result, 1e-15);
+
+        x = 4.5;
+        y = -1.5;
+        expected = f.value(x, y);
+        result = p.value(x, y);
+        Assert.assertEquals("half-way between sample points (middle of the patch)", expected, result, 0.3);
+
+        x = 3.5;
+        y = -3.5;
+        expected = f.value(x, y);
+        result = p.value(x, y);
+        Assert.assertEquals("half-way between sample points (border of the patch)", expected, result, 0.3);
+    }
+
+    /**
+     * Test of interpolator for a paraboloid.
+     * <p>
+     * z = 2 x<sup>2</sup> - 3 y<sup>2</sup> + 4 x y - 5
+     */
+    @Test
+    public void testParaboloid() throws MathException {
+        BivariateRealFunction f = new BivariateRealFunction() {
+                public double value(double x, double y) {
+                    return 2 * x * x - 3 * y * y + 4 * x * y - 5;
+                }
+            };
+
+        BivariateRealGridInterpolator interpolator = new SmoothingBicubicSplineInterpolator();
+
+        double[] xval = new double[] {3, 4, 5, 6.5};
+        double[] yval = new double[] {-4, -3, -2, -1, 0.5, 2.5};
+        double[][] zval = new double[xval.length][yval.length];
+        for (int i = 0; i < xval.length; i++) {
+            for (int j = 0; j < yval.length; j++) {
+                zval[i][j] = f.value(xval[i], yval[j]);
+            }
+        }
+
+        BivariateRealFunction p = interpolator.interpolate(xval, yval, zval);
+        double x, y;
+        double expected, result;
+        
+        x = 5;
+        y = 0.5;
+        expected = f.value(x, y);
+        result = p.value(x, y);
+        Assert.assertEquals("On sample point", expected, result, 1e-13);
+
+        x = 4.5;
+        y = -1.5;
+        expected = f.value(x, y);
+        result = p.value(x, y);
+        Assert.assertEquals("half-way between sample points (middle of the patch)", expected, result, 0.2);
+
+        x = 3.5;
+        y = -3.5;
+        expected = f.value(x, y);
+        result = p.value(x, y);
+        Assert.assertEquals("half-way between sample points (border of the patch)", expected, result, 0.2);
+    }
+}

Modified: commons/proper/math/trunk/src/test/java/org/apache/commons/math/util/MathUtilsTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math/util/MathUtilsTest.java?rev=927009&r1=927008&r2=927009&view=diff
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math/util/MathUtilsTest.java (original)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math/util/MathUtilsTest.java Wed Mar 24 11:14:07 2010
@@ -1381,4 +1381,35 @@ public final class MathUtilsTest extends
         assertEquals(4, MathUtils.distanceInf(p1, p2));
     }
 
+    public void testCheckOrder() {
+        MathUtils.checkOrder(new double[] {-15, -5.5, -1, 2, 15}, 1, true);
+        MathUtils.checkOrder(new double[] {-15, -5.5, -1, 2, 2}, 1, false);
+        MathUtils.checkOrder(new double[] {3, -5.5, -11, -27.5}, -1, true);
+        MathUtils.checkOrder(new double[] {3, 0, 0, -5.5, -11, -27.5}, -1, false);
+
+        try {
+            MathUtils.checkOrder(new double[] {-15, -5.5, -1, -1, 2, 15}, 1, true);
+            fail("an exception should have been thrown");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            MathUtils.checkOrder(new double[] {-15, -5.5, -1, -2, 2}, 1, false);
+            fail("an exception should have been thrown");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            MathUtils.checkOrder(new double[] {3, 3, -5.5, -11, -27.5}, -1, true);
+            fail("an exception should have been thrown");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            MathUtils.checkOrder(new double[] {3, -1, 0, -5.5, -11, -27.5}, -1, false);
+            fail("an exception should have been thrown");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+    }
 }



Mime
View raw message