// Constructor
  // Constructor with data arrays initialised to arrays x and y
  public BiCubicSplinePartialDerivative(double[] x1, double[] x2, double[][] y) {
    this.nPoints = x1.length;
    this.mPoints = x2.length;
    if (this.nPoints != y.length)
      throw new IllegalArgumentException(
          "Arrays x1 and y-row are of different length " + this.nPoints + " " + y.length);
    if (this.mPoints != y[0].length)
      throw new IllegalArgumentException(
          "Arrays x2 and y-column are of different length " + this.mPoints + " " + y[0].length);
    if (this.nPoints < 3 || this.mPoints < 3)
      throw new IllegalArgumentException("The data matrix must have a minimum size of 3 X 3");

    this.csm = new CubicSpline(this.nPoints);
    this.csn = CubicSpline.oneDarray(this.nPoints, this.mPoints);
    this.x1 = new double[this.nPoints];
    this.x2 = new double[this.mPoints];
    this.y = new double[this.nPoints][this.mPoints];
    for (int i = 0; i < this.nPoints; i++) {
      this.x1[i] = x1[i];
    }
    this.xMin[0] = Fmath.minimum(this.x1);
    this.xMax[0] = Fmath.maximum(this.x1);
    for (int j = 0; j < this.mPoints; j++) {
      this.x2[j] = x2[j];
    }
    this.xMin[1] = Fmath.minimum(this.x2);
    this.xMax[1] = Fmath.maximum(this.x2);
    for (int i = 0; i < this.nPoints; i++) {
      for (int j = 0; j < this.mPoints; j++) {
        this.y[i][j] = y[i][j];
      }
    }

    double[] yTempn = new double[mPoints];

    for (int i = 0; i < this.nPoints; i++) {
      for (int j = 0; j < mPoints; j++) yTempn[j] = y[i][j];
      this.csn[i].resetData(x2, yTempn);
      this.csn[i].calcDeriv();
    }
    this.derivCalculated = true;
  }
 // Reset potential rounding error value
 // Default option: points outside the interpolation bounds by less than the potential rounding
 // error rounded to the bounds limit
 // The default value for the potential rounding error is 5e-15*times the 10^exponent of the value
 // outside the bounds
 // This method allows the 5e-15 to be reset
 public static void potentialRoundingError(double potentialRoundingError) {
   BiCubicSplinePartialDerivative.potentialRoundingError = potentialRoundingError;
   CubicSpline.potentialRoundingError(potentialRoundingError);
 }
 // Reset rounding error check option
 // Default option: points outside the interpolation bounds by less than the potential rounding
 // error rounded to the bounds limit
 // This method causes this check to be ignored and an exception to be thrown if any point lies
 // outside the interpolation bounds
 public static void noRoundingErrorCheck() {
   BiCubicSplinePartialDerivative.roundingCheck = false;
   CubicSpline.noRoundingErrorCheck();
 }