diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index da092171c..d77627220 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -73,6 +73,10 @@ Users are encouraged to upgrade to this version as this release not
2. A few methods in the FastMath class are in fact slower that their
counterpart in either Math or StrictMath (cf. MATH-740 and MATH-901).
">
+
+ "BicubicSplineInterpolatingFunction": all fields made final and initialized in
+ the constructor.
+
Constrained EmpiricalDistribution sample/getNextValue methods to return
values within the range of the data; correctly linked RandomGenerator to
diff --git a/src/main/java/org/apache/commons/math3/analysis/interpolation/BicubicSplineInterpolatingFunction.java b/src/main/java/org/apache/commons/math3/analysis/interpolation/BicubicSplineInterpolatingFunction.java
index 1bb477671..db12cdc9d 100644
--- a/src/main/java/org/apache/commons/math3/analysis/interpolation/BicubicSplineInterpolatingFunction.java
+++ b/src/main/java/org/apache/commons/math3/analysis/interpolation/BicubicSplineInterpolatingFunction.java
@@ -66,7 +66,7 @@ public class BicubicSplineInterpolatingFunction
/** Set of cubic splines patching the whole data grid */
private final BicubicSplineFunction[][] splines;
/**
- * Partial derivatives
+ * Partial derivatives.
* The value of the first index determines the kind of derivatives:
* 0 = first partial derivatives wrt x
* 1 = first partial derivatives wrt y
@@ -74,7 +74,7 @@ public class BicubicSplineInterpolatingFunction
* 3 = second partial derivatives wrt y
* 4 = cross partial derivatives
*/
- private BivariateFunction[][][] partialDerivatives = null;
+ private final BivariateFunction[][][] partialDerivatives;
/**
* @param x Sample values of the x-coordinate, in increasing order.
@@ -156,6 +156,21 @@ public class BicubicSplineInterpolatingFunction
splines[i][j] = new BicubicSplineFunction(computeSplineCoefficients(beta));
}
}
+
+ // Compute all partial derivatives.
+
+ partialDerivatives = new BivariateFunction[5][lastI][lastJ];
+
+ for (int i = 0; i < lastI; i++) {
+ for (int j = 0; j < lastJ; j++) {
+ final BicubicSplineFunction bcs = splines[i][j];
+ partialDerivatives[0][i][j] = bcs.partialDerivativeX();
+ partialDerivatives[1][i][j] = bcs.partialDerivativeY();
+ partialDerivatives[2][i][j] = bcs.partialDerivativeXX();
+ partialDerivatives[3][i][j] = bcs.partialDerivativeYY();
+ partialDerivatives[4][i][j] = bcs.partialDerivativeXY();
+ }
+ }
}
/**
@@ -267,10 +282,6 @@ public class BicubicSplineInterpolatingFunction
*/
private double partialDerivative(int which, double x, double y)
throws OutOfRangeException {
- if (partialDerivatives == null) {
- computePartialDerivatives();
- }
-
final int i = searchIndex(x, xval);
final int j = searchIndex(y, yval);
@@ -280,26 +291,6 @@ public class BicubicSplineInterpolatingFunction
return partialDerivatives[which][i][j].value(xN, yN);
}
- /**
- * Compute all partial derivatives.
- */
- private void computePartialDerivatives() {
- final int lastI = xval.length - 1;
- final int lastJ = yval.length - 1;
- partialDerivatives = new BivariateFunction[5][lastI][lastJ];
-
- for (int i = 0; i < lastI; i++) {
- for (int j = 0; j < lastJ; j++) {
- final BicubicSplineFunction f = splines[i][j];
- partialDerivatives[0][i][j] = f.partialDerivativeX();
- partialDerivatives[1][i][j] = f.partialDerivativeY();
- partialDerivatives[2][i][j] = f.partialDerivativeXX();
- partialDerivatives[3][i][j] = f.partialDerivativeYY();
- partialDerivatives[4][i][j] = f.partialDerivativeXY();
- }
- }
- }
-
/**
* @param c Coordinate.
* @param val Coordinate samples.
@@ -382,139 +373,36 @@ public class BicubicSplineInterpolatingFunction
*
* @version $Id$
*/
-class BicubicSplineFunction
- implements BivariateFunction {
-
+class BicubicSplineFunction implements BivariateFunction {
/** Number of points. */
private static final short N = 4;
-
/** Coefficients */
private final double[][] a;
-
/** First partial derivative along x. */
- private BivariateFunction partialDerivativeX;
-
+ private final BivariateFunction partialDerivativeX;
/** First partial derivative along y. */
- private BivariateFunction partialDerivativeY;
-
+ private final BivariateFunction partialDerivativeY;
/** Second partial derivative along x. */
- private BivariateFunction partialDerivativeXX;
-
+ private final BivariateFunction partialDerivativeXX;
/** Second partial derivative along y. */
- private BivariateFunction partialDerivativeYY;
-
+ private final BivariateFunction partialDerivativeYY;
/** Second crossed partial derivative. */
- private BivariateFunction partialDerivativeXY;
+ private final BivariateFunction partialDerivativeXY;
/**
* Simple constructor.
- * @param a Spline coefficients
+ * @param coeff Spline coefficients
*/
- public BicubicSplineFunction(double[] a) {
- this.a = new double[N][N];
+ public BicubicSplineFunction(double[] coeff) {
+ a = new double[N][N];
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
- this.a[i][j] = a[i * N + j];
- }
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public double value(double x, double y) {
- if (x < 0 || x > 1) {
- throw new OutOfRangeException(x, 0, 1);
- }
- if (y < 0 || y > 1) {
- throw new OutOfRangeException(y, 0, 1);
- }
-
- final double x2 = x * x;
- final double x3 = x2 * x;
- final double[] pX = {1, x, x2, x3};
-
- final double y2 = y * y;
- final double y3 = y2 * y;
- final double[] pY = {1, y, y2, y3};
-
- return apply(pX, pY, a);
- }
-
- /**
- * Compute the value of the bicubic polynomial.
- *
- * @param pX Powers of the x-coordinate.
- * @param pY Powers of the y-coordinate.
- * @param coeff Spline coefficients.
- * @return the interpolated value.
- */
- private double apply(double[] pX, double[] pY, double[][] coeff) {
- double result = 0;
- for (int i = 0; i < N; i++) {
- for (int j = 0; j < N; j++) {
- result += coeff[i][j] * pX[i] * pY[j];
+ a[i][j] = coeff[i * N + j];
}
}
- return result;
- }
+ // Compute all partial derivatives functions.
- /**
- * @return the partial derivative wrt {@code x}.
- */
- public BivariateFunction partialDerivativeX() {
- if (partialDerivativeX == null) {
- computePartialDerivatives();
- }
-
- return partialDerivativeX;
- }
- /**
- * @return the partial derivative wrt {@code y}.
- */
- public BivariateFunction partialDerivativeY() {
- if (partialDerivativeY == null) {
- computePartialDerivatives();
- }
-
- return partialDerivativeY;
- }
- /**
- * @return the second partial derivative wrt {@code x}.
- */
- public BivariateFunction partialDerivativeXX() {
- if (partialDerivativeXX == null) {
- computePartialDerivatives();
- }
-
- return partialDerivativeXX;
- }
- /**
- * @return the second partial derivative wrt {@code y}.
- */
- public BivariateFunction partialDerivativeYY() {
- if (partialDerivativeYY == null) {
- computePartialDerivatives();
- }
-
- return partialDerivativeYY;
- }
- /**
- * @return the second partial cross-derivative.
- */
- public BivariateFunction partialDerivativeXY() {
- if (partialDerivativeXY == null) {
- computePartialDerivatives();
- }
-
- return partialDerivativeXY;
- }
-
- /**
- * Compute all partial derivatives functions.
- */
- private void computePartialDerivatives() {
final double[][] aX = new double[N][N];
final double[][] aY = new double[N][N];
final double[][] aXX = new double[N][N];
@@ -590,4 +478,76 @@ class BicubicSplineFunction
}
};
}
+
+ /**
+ * {@inheritDoc}
+ */
+ public double value(double x, double y) {
+ if (x < 0 || x > 1) {
+ throw new OutOfRangeException(x, 0, 1);
+ }
+ if (y < 0 || y > 1) {
+ throw new OutOfRangeException(y, 0, 1);
+ }
+
+ final double x2 = x * x;
+ final double x3 = x2 * x;
+ final double[] pX = {1, x, x2, x3};
+
+ final double y2 = y * y;
+ final double y3 = y2 * y;
+ final double[] pY = {1, y, y2, y3};
+
+ return apply(pX, pY, a);
+ }
+
+ /**
+ * Compute the value of the bicubic polynomial.
+ *
+ * @param pX Powers of the x-coordinate.
+ * @param pY Powers of the y-coordinate.
+ * @param coeff Spline coefficients.
+ * @return the interpolated value.
+ */
+ private double apply(double[] pX, double[] pY, double[][] coeff) {
+ double result = 0;
+ for (int i = 0; i < N; i++) {
+ for (int j = 0; j < N; j++) {
+ result += coeff[i][j] * pX[i] * pY[j];
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * @return the partial derivative wrt {@code x}.
+ */
+ public BivariateFunction partialDerivativeX() {
+ return partialDerivativeX;
+ }
+ /**
+ * @return the partial derivative wrt {@code y}.
+ */
+ public BivariateFunction partialDerivativeY() {
+ return partialDerivativeY;
+ }
+ /**
+ * @return the second partial derivative wrt {@code x}.
+ */
+ public BivariateFunction partialDerivativeXX() {
+ return partialDerivativeXX;
+ }
+ /**
+ * @return the second partial derivative wrt {@code y}.
+ */
+ public BivariateFunction partialDerivativeYY() {
+ return partialDerivativeYY;
+ }
+ /**
+ * @return the second partial cross-derivative.
+ */
+ public BivariateFunction partialDerivativeXY() {
+ return partialDerivativeXY;
+ }
}