List of usage examples for org.apache.commons.math3.util MathArrays checkOrder
public static void checkOrder(double[] val) throws NonMonotonicSequenceException
From source file:es.uvigo.ei.sing.laimages.core.operations.BilinearInterpolator.java
@Override public BilinearInterpolatingFunction interpolate(double[] xval, double[] yval, double[][] fval) throws NoDataException, DimensionMismatchException, NonMonotonicSequenceException { if (xval.length == 0 || yval.length == 0 || fval.length == 0) { throw new NoDataException(); }/* w ww . ja v a 2 s. co m*/ if (xval.length != fval.length) { throw new DimensionMismatchException(xval.length, fval.length); } if (yval.length != fval[0].length) { throw new DimensionMismatchException(yval.length, fval[0].length); } MathArrays.checkOrder(xval); MathArrays.checkOrder(yval); return new BilinearInterpolatingFunction(xval, yval, fval); }
From source file:de.bund.bfr.math.LinearFunction.java
public LinearFunction(double[] x, double[] y) throws NullArgumentException, NoDataException, DimensionMismatchException, NonMonotonicSequenceException { if (x == null || y == null) { throw new NullArgumentException(); }/*from w w w . j ava2 s . co m*/ if (x.length == 0 || y.length == 0) { throw new NoDataException(); } if (y.length != x.length) { throw new DimensionMismatchException(y.length, x.length); } MathArrays.checkOrder(x); abscissa = MathArrays.copyOf(x); ordinate = MathArrays.copyOf(y); }
From source file:es.uvigo.ei.sing.laimages.core.operations.BilinearInterpolatingFunction.java
public BilinearInterpolatingFunction(double[] xval, double[] yval, double[][] fval) throws DimensionMismatchException, NoDataException, NonMonotonicSequenceException { if (xval.length == 0 || yval.length == 0 || fval.length == 0) { throw new NoDataException(); }// w ww . j av a 2 s. c o m if (xval.length != fval.length) { throw new DimensionMismatchException(xval.length, fval.length); } if (yval.length != fval[0].length) { throw new DimensionMismatchException(yval.length, fval[0].length); } MathArrays.checkOrder(xval); MathArrays.checkOrder(yval); this.xval = xval; this.yval = yval; this.fval = fval; }
From source file:au.gov.ga.conn4d.utils.BicubicSplineInterpolator.java
/** * {@inheritDoc}// ww w .j av a2 s . co m */ public BicubicSplineInterpolatingFunction interpolate(final double[] xval, final double[] yval, final float[][] fval) throws NoDataException, DimensionMismatchException, NonMonotonicSequenceException, NumberIsTooSmallException { if (xval.length == 0 || yval.length == 0 || fval.length == 0) { throw new NoDataException(); } if (xval.length != fval.length) { throw new DimensionMismatchException(xval.length, fval.length); } MathArrays.checkOrder(xval); MathArrays.checkOrder(yval); 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 // fX[j][i] = f(xval[i], yval[j]) final double[][] fX = new double[yLen][xLen]; for (int i = 0; i < xLen; i++) { if (fval[i].length != yLen) { throw new DimensionMismatchException(fval[i].length, yLen); } for (int j = 0; j < yLen; j++) { fX[j][i] = fval[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, fX[j]); } // For each line x[i] (0 <= i < xLen), construct a 1D spline with // respect to variable y generated by array fY_1[i] final PolynomialSplineFunction[] xSplineY = new PolynomialSplineFunction[xLen]; for (int i = 0; i < xLen; i++) { xSplineY[i] = spInterpolator.interpolate(yval, fval[i]); } // Partial derivatives with respect to x at the grid knots final double[][] dFdX = new double[xLen][yLen]; for (int j = 0; j < yLen; j++) { final UnivariateFunction f = ySplineX[j].derivative(); for (int i = 0; i < xLen; i++) { dFdX[i][j] = f.value(xval[i]); } } // Partial derivatives with respect to y at the grid knots final double[][] dFdY = new double[xLen][yLen]; for (int i = 0; i < xLen; i++) { final UnivariateFunction f = xSplineY[i].derivative(); for (int j = 0; j < yLen; j++) { dFdY[i][j] = f.value(yval[j]); } } // Cross partial derivatives final double[][] d2FdXdY = 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); d2FdXdY[i][j] = (fval[nI][nJ] - fval[nI][pJ] - fval[pI][nJ] + fval[pI][pJ]) / ((xval[nI] - xval[pI]) * (yval[nJ] - yval[pJ])); } } // Create the interpolating splines return new BicubicSplineInterpolatingFunction(xval, yval, fval, dFdX, dFdY, d2FdXdY); }
From source file:au.gov.ga.conn4d.utils.TricubicSplineInterpolator.java
/** * {@inheritDoc}//from w w w . j ava 2 s. co m */ public TricubicSplineInterpolatingFunction interpolate(final double[] zval, final double[] yval, final double[] xval, final double[][][] fval) throws NoDataException, DimensionMismatchException, NonMonotonicSequenceException { if (zval.length == 0 || yval.length == 0 || xval.length == 0 || fval.length == 0) { throw new NoDataException(); } if (zval.length != fval.length) { throw new DimensionMismatchException(zval.length, fval.length); } MathArrays.checkOrder(zval); MathArrays.checkOrder(yval); final int zLen = zval.length; final int yLen = yval.length; final int xLen = xval.length; final double[] zzval; final double[][][] ffval = new double[zLen][][]; if (zval[0] > zval[zLen - 1]) { zzval = VectorMath.selectionSort(zval); for (int i = 0; i < zLen; i++) { ffval[i] = fval[zLen - 1 - i]; } } else { zzval = zval; } // Samples, re-ordered as (z, x, y) and (y, z, x) tuplets // fvalXY[k][i][j] = f(xval[i], yval[j], zval[k]) // fvalZX[j][k][i] = f(xval[i], yval[j], zval[k]) final double[][][] fvalXY = new double[xLen][zLen][yLen]; final double[][][] fvalZX = new double[yLen][xLen][zLen]; for (int i = 0; i < zLen; i++) { if (ffval[i].length != yLen) { throw new DimensionMismatchException(ffval[i].length, yLen); } for (int j = 0; j < yLen; j++) { if (ffval[i][j].length != xLen) { throw new DimensionMismatchException(ffval[i][j].length, xLen); } for (int k = 0; k < xLen; k++) { final double v = ffval[i][j][k]; fvalXY[k][i][j] = v; fvalZX[j][k][i] = v; } } } final BicubicSplineInterpolator bsi = new BicubicSplineInterpolator(); // For each line x[i] (0 <= i < xLen), construct a 2D spline in y and z final BicubicSplineInterpolatingFunction[] xSplineYZ = new BicubicSplineInterpolatingFunction[zLen]; for (int i = 0; i < zLen; i++) { xSplineYZ[i] = bsi.interpolate(yval, xval, ffval[i]); } // For each line y[j] (0 <= j < yLen), construct a 2D spline in z and x final BicubicSplineInterpolatingFunction[] ySplineZX = new BicubicSplineInterpolatingFunction[yLen]; for (int j = 0; j < yLen; j++) { ySplineZX[j] = bsi.interpolate(xval, zzval, fvalZX[j]); } // For each line z[k] (0 <= k < zLen), construct a 2D spline in x and y final BicubicSplineInterpolatingFunction[] zSplineXY = new BicubicSplineInterpolatingFunction[xLen]; for (int k = 0; k < xLen; k++) { zSplineXY[k] = bsi.interpolate(zzval, yval, fvalXY[k]); } // Partial derivatives wrt x and wrt y final double[][][] dFdX = new double[zLen][yLen][xLen]; final double[][][] dFdY = new double[zLen][yLen][xLen]; final double[][][] d2FdXdY = new double[zLen][yLen][xLen]; for (int k = 0; k < xLen; k++) { final BicubicSplineInterpolatingFunction f = zSplineXY[k]; for (int i = 0; i < zLen; i++) { final double z = zzval[i]; for (int j = 0; j < yLen; j++) { final double y = yval[j]; dFdX[i][j][k] = f.partialDerivativeX(z, y); dFdY[i][j][k] = f.partialDerivativeY(z, y); d2FdXdY[i][j][k] = f.partialDerivativeXY(z, y); } } } // Partial derivatives wrt y and wrt z final double[][][] dFdZ = new double[zLen][yLen][xLen]; final double[][][] d2FdYdZ = new double[zLen][yLen][xLen]; for (int i = 0; i < zLen; i++) { final BicubicSplineInterpolatingFunction f = xSplineYZ[i]; for (int j = 0; j < yLen; j++) { final double y = yval[j]; for (int k = 0; k < xLen; k++) { final double x = xval[k]; dFdZ[i][j][k] = f.partialDerivativeY(y, x); d2FdYdZ[i][j][k] = f.partialDerivativeXY(y, x); } } } // Partial derivatives wrt x and wrt z final double[][][] d2FdZdX = new double[zLen][yLen][xLen]; for (int j = 0; j < yLen; j++) { final BicubicSplineInterpolatingFunction f = ySplineZX[j]; for (int k = 0; k < xLen; k++) { final double x = xval[k]; for (int i = 0; i < zLen; i++) { final double z = zzval[i]; d2FdZdX[i][j][k] = f.partialDerivativeXY(x, z); } } } // Third partial cross-derivatives final double[][][] d3FdXdYdZ = new double[zLen][yLen][xLen]; for (int i = 0; i < zLen; i++) { final int nI = nextIndex(i, zLen); final int pI = previousIndex(i); for (int j = 0; j < yLen; j++) { final int nJ = nextIndex(j, yLen); final int pJ = previousIndex(j); for (int k = 0; k < xLen; k++) { final int nK = nextIndex(k, xLen); final int pK = previousIndex(k); // XXX Not sure about this formula d3FdXdYdZ[i][j][k] = (ffval[nI][nJ][nK] - ffval[nI][pJ][nK] - ffval[pI][nJ][nK] + ffval[pI][pJ][nK] - ffval[nI][nJ][pK] + ffval[nI][pJ][pK] + ffval[pI][nJ][pK] - ffval[pI][pJ][pK]) / ((zzval[nI] - zzval[pI]) * (yval[nJ] - yval[pJ]) * (xval[nK] - xval[pK])); } } } // Create the interpolating splines return new TricubicSplineInterpolatingFunction(zzval, yval, xval, ffval, dFdX, dFdY, dFdZ, d2FdXdY, d2FdZdX, d2FdYdZ, d3FdXdYdZ); }
From source file:au.gov.ga.conn4d.utils.SplineInterpolator.java
/** * Computes an interpolating function for the data set. * /*from w w w . j ava2 s . co m*/ * @param x * the arguments for the interpolation points * @param y * the values for the interpolation points * @return a function which interpolates the data set * @throws DimensionMismatchException * if {@code x} and {@code y} have different sizes. * @throws NonMonotonicSequenceException * if {@code x} is not sorted in strict increasing order. * @throws NumberIsTooSmallException * if the size of {@code x} is smaller than 3. */ public PolynomialSplineFunction interpolate(double x[], double y[]) throws DimensionMismatchException, NumberIsTooSmallException, NonMonotonicSequenceException { if (x.length != y.length) { throw new DimensionMismatchException(x.length, y.length); } if (x.length < 3) { throw new NumberIsTooSmallException(LocalizedFormats.NUMBER_OF_POINTS, x.length, 3, true); } // Number of intervals. The number of data points is n + 1. final int n = x.length - 1; MathArrays.checkOrder(x); // Differences between knot points final double h[] = new double[n]; for (int i = 0; i < n; i++) { h[i] = x[i + 1] - x[i]; } final double mu[] = new double[n]; final double z[] = new double[n + 1]; mu[0] = 0d; z[0] = 0d; double g = 0; for (int i = 1; i < n; i++) { g = 2d * (x[i + 1] - x[i - 1]) - h[i - 1] * mu[i - 1]; mu[i] = h[i] / g; z[i] = (3d * (y[i + 1] * h[i - 1] - y[i] * (x[i + 1] - x[i - 1]) + y[i - 1] * h[i]) / (h[i - 1] * h[i]) - h[i - 1] * z[i - 1]) / g; } // cubic spline coefficients -- b is linear, c quadratic, d is cubic // (original y's are constants) final double b[] = new double[n]; final double c[] = new double[n + 1]; final double d[] = new double[n]; z[n] = 0d; c[n] = 0d; for (int j = n - 1; j >= 0; j--) { c[j] = z[j] - mu[j] * c[j + 1]; b[j] = (y[j + 1] - y[j]) / h[j] - h[j] * (c[j + 1] + 2d * c[j]) / 3d; d[j] = (c[j + 1] - c[j]) / (3d * h[j]); } final PolynomialFunction polynomials[] = new PolynomialFunction[n]; final double coefficients[] = new double[4]; for (int i = 0; i < n; i++) { coefficients[0] = y[i]; coefficients[1] = b[i]; coefficients[2] = c[i]; coefficients[3] = d[i]; polynomials[i] = new PolynomialFunction(coefficients); } return new PolynomialSplineFunction(x, polynomials); }
From source file:au.gov.ga.conn4d.utils.BicubicSplineInterpolator.java
public BicubicSplineInterpolatingFunction interpolate(final double[] xval, final double[] yval, final double[][] fval) throws NoDataException, DimensionMismatchException, NonMonotonicSequenceException, NumberIsTooSmallException { if (xval.length == 0 || yval.length == 0 || fval.length == 0) { throw new NoDataException(); }//from w w w . ja v a2s. c om if (xval.length != fval.length) { throw new DimensionMismatchException(xval.length, fval.length); } MathArrays.checkOrder(xval); MathArrays.checkOrder(yval); 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 // fX[j][i] = f(xval[i], yval[j]) final double[][] fX = new double[yLen][xLen]; for (int i = 0; i < xLen; i++) { if (fval[i].length != yLen) { throw new DimensionMismatchException(fval[i].length, yLen); } for (int j = 0; j < yLen; j++) { fX[j][i] = fval[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, fX[j]); } // For each line x[i] (0 <= i < xLen), construct a 1D spline with // respect to variable y generated by array fY_1[i] final PolynomialSplineFunction[] xSplineY = new PolynomialSplineFunction[xLen]; for (int i = 0; i < xLen; i++) { xSplineY[i] = spInterpolator.interpolate(yval, fval[i]); } // Partial derivatives with respect to x at the grid knots final double[][] dFdX = new double[xLen][yLen]; for (int j = 0; j < yLen; j++) { final UnivariateFunction f = ySplineX[j].derivative(); for (int i = 0; i < xLen; i++) { dFdX[i][j] = f.value(xval[i]); } } // Partial derivatives with respect to y at the grid knots final double[][] dFdY = new double[xLen][yLen]; for (int i = 0; i < xLen; i++) { final UnivariateFunction f = xSplineY[i].derivative(); for (int j = 0; j < yLen; j++) { dFdY[i][j] = f.value(yval[j]); } } // Cross partial derivatives final double[][] d2FdXdY = 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); d2FdXdY[i][j] = (fval[nI][nJ] - fval[nI][pJ] - fval[pI][nJ] + fval[pI][pJ]) / ((xval[nI] - xval[pI]) * (yval[nJ] - yval[pJ])); } } // Create the interpolating splines return new BicubicSplineInterpolatingFunction(xval, yval, fval, dFdX, dFdY, d2FdXdY); }
From source file:au.gov.ga.conn4d.utils.BicubicSplineInterpolatingFunction.java
/** * @param x Sample values of the x-coordinate, in increasing order. * @param y Sample values of the y-coordinate, in increasing order. * @param f Values of the function on every grid point. * @param dFdX Values of the partial derivative of function with respect * to x on every grid point.//from w w w.j av a 2 s . co m * @param dFdY Values of the partial derivative of function with respect * to y on every grid point. * @param d2FdXdY 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 NonMonotonicSequenceException if {@code x} or {@code y} are * not strictly increasing. * @throws NoDataException if any of the arrays has zero length. */ public BicubicSplineInterpolatingFunction(double[] x, double[] y, float[][] f, double[][] dFdX, double[][] dFdY, double[][] d2FdXdY) throws DimensionMismatchException, NoDataException, NonMonotonicSequenceException { final int xLen = x.length; final int yLen = y.length; if (xLen == 0 || yLen == 0 || f.length == 0 || f[0].length == 0) { throw new NoDataException(); } if (xLen != f.length) { throw new DimensionMismatchException(xLen, f.length); } if (xLen != dFdX.length) { throw new DimensionMismatchException(xLen, dFdX.length); } if (xLen != dFdY.length) { throw new DimensionMismatchException(xLen, dFdY.length); } if (xLen != d2FdXdY.length) { throw new DimensionMismatchException(xLen, d2FdXdY.length); } MathArrays.checkOrder(x); MathArrays.checkOrder(y); 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 (f[i].length != yLen) { throw new DimensionMismatchException(f[i].length, yLen); } if (dFdX[i].length != yLen) { throw new DimensionMismatchException(dFdX[i].length, yLen); } if (dFdY[i].length != yLen) { throw new DimensionMismatchException(dFdY[i].length, yLen); } if (d2FdXdY[i].length != yLen) { throw new DimensionMismatchException(d2FdXdY[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[] { f[i][j], f[ip1][j], f[i][jp1], f[ip1][jp1], dFdX[i][j], dFdX[ip1][j], dFdX[i][jp1], dFdX[ip1][jp1], dFdY[i][j], dFdY[ip1][j], dFdY[i][jp1], dFdY[ip1][jp1], d2FdXdY[i][j], d2FdXdY[ip1][j], d2FdXdY[i][jp1], d2FdXdY[ip1][jp1] }; splines[i][j] = new BicubicSplineFunction(computeSplineCoefficients(beta)); } } }
From source file:au.gov.ga.conn4d.utils.SplineInterpolator.java
public PolynomialSplineFunction interpolate(double x[], float y[]) throws DimensionMismatchException, NumberIsTooSmallException, NonMonotonicSequenceException { if (x.length != y.length) { throw new DimensionMismatchException(x.length, y.length); }//from ww w. j a v a 2 s.c om if (x.length < 3) { throw new NumberIsTooSmallException(LocalizedFormats.NUMBER_OF_POINTS, x.length, 3, true); } // Number of intervals. The number of data points is n + 1. final int n = x.length - 1; MathArrays.checkOrder(x); // Differences between knot points final double h[] = new double[n]; for (int i = 0; i < n; i++) { h[i] = x[i + 1] - x[i]; } final double mu[] = new double[n]; final double z[] = new double[n + 1]; mu[0] = 0d; z[0] = 0d; double g = 0; for (int i = 1; i < n; i++) { g = 2d * (x[i + 1] - x[i - 1]) - h[i - 1] * mu[i - 1]; mu[i] = h[i] / g; z[i] = (3d * (y[i + 1] * h[i - 1] - y[i] * (x[i + 1] - x[i - 1]) + y[i - 1] * h[i]) / (h[i - 1] * h[i]) - h[i - 1] * z[i - 1]) / g; } // cubic spline coefficients -- b is linear, c quadratic, d is cubic // (original y's are constants) final double b[] = new double[n]; final double c[] = new double[n + 1]; final double d[] = new double[n]; z[n] = 0d; c[n] = 0d; for (int j = n - 1; j >= 0; j--) { c[j] = z[j] - mu[j] * c[j + 1]; b[j] = (y[j + 1] - y[j]) / h[j] - h[j] * (c[j + 1] + 2d * c[j]) / 3d; d[j] = (c[j + 1] - c[j]) / (3d * h[j]); } final PolynomialFunction polynomials[] = new PolynomialFunction[n]; final double coefficients[] = new double[4]; for (int i = 0; i < n; i++) { coefficients[0] = y[i]; coefficients[1] = b[i]; coefficients[2] = c[i]; coefficients[3] = d[i]; polynomials[i] = new PolynomialFunction(coefficients); } return new PolynomialSplineFunction(x, polynomials); }
From source file:au.gov.ga.conn4d.utils.TricubicSplineInterpolator.java
public TricubicSplineInterpolatingFunction interpolate(final double[] zval, final double[] yval, final double[] xval, final float[][][] fval) throws NoDataException, DimensionMismatchException, NonMonotonicSequenceException { if (zval.length == 0 || yval.length == 0 || xval.length == 0 || fval.length == 0) { throw new NoDataException(); }// w w w . j a va 2 s .c o m if (zval.length != fval.length) { throw new DimensionMismatchException(zval.length, fval.length); } MathArrays.checkOrder(yval); MathArrays.checkOrder(xval); final int zLen = zval.length; final int yLen = yval.length; final int xLen = xval.length; final double[] zzval; float[][][] ffval = new float[zLen][][]; if (zval[0] > zval[zLen - 1]) { zzval = VectorMath.selectionSort(zval); for (int i = 0; i < zLen; i++) { ffval[i] = fval[zLen - 1 - i]; } } else { zzval = zval; ffval = fval; } // Samples, re-ordered as (z, x, y) and (y, z, x) tuplets // fvalXY[k][i][j] = f(xval[i], yval[j], zval[k]) // fvalZX[j][k][i] = f(xval[i], yval[j], zval[k]) final double[][][] fvalXY = new double[xLen][zLen][yLen]; final double[][][] fvalZX = new double[yLen][xLen][zLen]; for (int i = 0; i < zLen; i++) { if (ffval[i].length != yLen) { throw new DimensionMismatchException(ffval[i].length, yLen); } for (int j = 0; j < yLen; j++) { if (ffval[i][j].length != xLen) { throw new DimensionMismatchException(ffval[i][j].length, xLen); } for (int k = 0; k < xLen; k++) { final double v = ffval[i][j][k]; fvalXY[k][i][j] = v; fvalZX[j][k][i] = v; } } } final BicubicSplineInterpolator bsi = new BicubicSplineInterpolator(); // For each line x[i] (0 <= i < xLen), construct a 2D spline in y and z final BicubicSplineInterpolatingFunction[] xSplineYZ = new BicubicSplineInterpolatingFunction[zLen]; for (int i = 0; i < zLen; i++) { xSplineYZ[i] = bsi.interpolate(yval, xval, ffval[i]); } // For each line y[j] (0 <= j < yLen), construct a 2D spline in z and x final BicubicSplineInterpolatingFunction[] ySplineZX = new BicubicSplineInterpolatingFunction[yLen]; for (int j = 0; j < yLen; j++) { ySplineZX[j] = bsi.interpolate(xval, zzval, fvalZX[j]); } // For each line z[k] (0 <= k < zLen), construct a 2D spline in x and y final BicubicSplineInterpolatingFunction[] zSplineXY = new BicubicSplineInterpolatingFunction[xLen]; for (int k = 0; k < xLen; k++) { zSplineXY[k] = bsi.interpolate(zzval, yval, fvalXY[k]); } // Partial derivatives wrt x and wrt y final double[][][] dFdX = new double[zLen][yLen][xLen]; final double[][][] dFdY = new double[zLen][yLen][xLen]; final double[][][] d2FdXdY = new double[zLen][yLen][xLen]; for (int k = 0; k < xLen; k++) { final BicubicSplineInterpolatingFunction f = zSplineXY[k]; for (int i = 0; i < zLen; i++) { final double x = zzval[i]; for (int j = 0; j < yLen; j++) { final double y = yval[j]; dFdX[i][j][k] = f.partialDerivativeX(x, y); dFdY[i][j][k] = f.partialDerivativeY(x, y); d2FdXdY[i][j][k] = f.partialDerivativeXY(x, y); } } } // Partial derivatives wrt y and wrt z final double[][][] dFdZ = new double[zLen][yLen][xLen]; final double[][][] d2FdYdZ = new double[zLen][yLen][xLen]; for (int i = 0; i < zLen; i++) { final BicubicSplineInterpolatingFunction f = xSplineYZ[i]; for (int j = 0; j < yLen; j++) { final double y = yval[j]; for (int k = 0; k < xLen; k++) { final double z = xval[k]; dFdZ[i][j][k] = f.partialDerivativeY(y, z); d2FdYdZ[i][j][k] = f.partialDerivativeXY(y, z); } } } // Partial derivatives wrt x and wrt z final double[][][] d2FdZdX = new double[zLen][yLen][xLen]; for (int j = 0; j < yLen; j++) { final BicubicSplineInterpolatingFunction f = ySplineZX[j]; for (int k = 0; k < xLen; k++) { final double z = xval[k]; for (int i = 0; i < zLen; i++) { final double x = zzval[i]; d2FdZdX[i][j][k] = f.partialDerivativeXY(z, x); } } } // Third partial cross-derivatives final double[][][] d3FdXdYdZ = new double[zLen][yLen][xLen]; for (int i = 0; i < zLen; i++) { final int nI = nextIndex(i, zLen); final int pI = previousIndex(i); for (int j = 0; j < yLen; j++) { final int nJ = nextIndex(j, yLen); final int pJ = previousIndex(j); for (int k = 0; k < xLen; k++) { final int nK = nextIndex(k, xLen); final int pK = previousIndex(k); // XXX Not sure about this formula d3FdXdYdZ[i][j][k] = (ffval[nI][nJ][nK] - ffval[nI][pJ][nK] - ffval[pI][nJ][nK] + ffval[pI][pJ][nK] - ffval[nI][nJ][pK] + ffval[nI][pJ][pK] + ffval[pI][nJ][pK] - ffval[pI][pJ][pK]) / ((zzval[nI] - zzval[pI]) * (yval[nJ] - yval[pJ]) * (xval[nK] - xval[pK])); } } } // Create the interpolating splines return new TricubicSplineInterpolatingFunction(zzval, yval, xval, ffval, dFdX, dFdY, dFdZ, d2FdXdY, d2FdZdX, d2FdYdZ, d3FdXdYdZ); }