///
        public virtual void localMonotonicityClampedTest()
        {
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final double[] xValues = new double[] {-2.0, 3.0, 4.0, 8.0, 9.1, 10.0 };
            double[] xValues = new double[] { -2.0, 3.0, 4.0, 8.0, 9.1, 10.0 };
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final double[] yValues = new double[] {0.0, 10.0, 9.5, 2.0, 1.1, -2.2, -2.6, 0.0 };
            double[] yValues = new double[] { 0.0, 10.0, 9.5, 2.0, 1.1, -2.2, -2.6, 0.0 };

            PiecewisePolynomialInterpolator interp = new CubicSplineInterpolator();
            PiecewisePolynomialResult       result = interp.interpolate(xValues, yValues);

            PiecewisePolynomialFunction1D function = new PiecewisePolynomialFunction1D();

            PiecewisePolynomialInterpolator interpPos = new MonotonicityPreservingCubicSplineInterpolator(interp);
            PiecewisePolynomialResult       resultPos = interpPos.interpolate(xValues, yValues);

            assertEquals(resultPos.Dimensions, result.Dimensions);
            assertEquals(resultPos.NumberOfIntervals, result.NumberOfIntervals);
            assertEquals(resultPos.Order, result.Order);

            const int nKeys = 121;
            double    key0  = -2.0;

            for (int i = 1; i < nKeys; ++i)
            {
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final double key = -2.0 + 12.0 / (nKeys - 1) * i;
                double key = -2.0 + 12.0 / (nKeys - 1) * i;
                assertTrue(function.evaluate(resultPos, key).get(0) - function.evaluate(resultPos, key0).get(0) <= 0.0);

                key0 = -2.0 + 11.0 / (nKeys - 1) * i;
            }
        }
        ///
        public virtual void positivityClampedMultiTest()
        {
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final double[] xValues = new double[] {1.0, 2.0, 3.0, 4.0, 5.0 };
            double[] xValues = new double[] { 1.0, 2.0, 3.0, 4.0, 5.0 };
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final double[][] yValues = new double[][] { {0.0, 0.1, 1.0, 1.0, 20.0, 5.0, 0.0 }, {-10.0, 0.1, 1.0, 1.0, 20.0, 5.0, 0.0 } };
            double[][] yValues = new double[][]
            {
                new double[] { 0.0, 0.1, 1.0, 1.0, 20.0, 5.0, 0.0 },
                new double[] { -10.0, 0.1, 1.0, 1.0, 20.0, 5.0, 0.0 }
            };

            PiecewisePolynomialInterpolator interp = new CubicSplineInterpolator();
            PiecewisePolynomialResult       result = interp.interpolate(xValues, yValues);

            PiecewisePolynomialFunction1D function = new PiecewisePolynomialFunction1D();

            PiecewisePolynomialInterpolator interpPos = new NonnegativityPreservingCubicSplineInterpolator(interp);
            PiecewisePolynomialResult       resultPos = interpPos.interpolate(xValues, yValues);

            assertEquals(resultPos.Dimensions, result.Dimensions);
            assertEquals(resultPos.NumberOfIntervals, result.NumberOfIntervals);
            assertEquals(resultPos.Order, result.Order);

            const int nPts = 101;

            for (int i = 0; i < 101; ++i)
            {
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final double key = 1.0 + 4.0 / (nPts - 1) * i;
                double key = 1.0 + 4.0 / (nPts - 1) * i;
                assertTrue(function.evaluate(resultPos, key).get(0) >= 0.0);
            }

            int dim   = yValues.Length;
            int nData = xValues.Length;

            for (int j = 0; j < dim; ++j)
            {
                for (int i = 1; i < nData - 2; ++i)
                {
                    DoubleMatrix coefMatrix = resultPos.CoefMatrix;
                    double       tau        = Math.Sign(coefMatrix.get(dim * i + j, 3));
                    assertTrue(coefMatrix.get(dim * i + j, 2) * tau >= -3.0 * yValues[j][i + 1] * tau / (xValues[i + 1] - xValues[i]));
                    assertTrue(coefMatrix.get(dim * i + j, 2) * tau <= 3.0 * yValues[j][i + 1] * tau / (xValues[i] - xValues[i - 1]));
                }
            }
        }
        /// <summary>
        /// local extrema are not necessarily at data-points
        /// </summary>
        public virtual void extremumTest()
        {
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final double[] xValues = new double[] {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8 };
            double[] xValues = new double[] { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8 };
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final double[][] yValues = new double[][] { {1.0, 1.0, 2.0, 4.0, 4.0, 2.0, 1.0, 1.0 }, {10.0, 10.0, 6.0, 4.0, 4.0, 6.0, 10.0, 10.0 } };
            double[][] yValues = new double[][]
            {
                new double[] { 1.0, 1.0, 2.0, 4.0, 4.0, 2.0, 1.0, 1.0 },
                new double[] { 10.0, 10.0, 6.0, 4.0, 4.0, 6.0, 10.0, 10.0 }
            };

            PiecewisePolynomialInterpolator interp = new CubicSplineInterpolator();
            PiecewisePolynomialResult       result = interp.interpolate(xValues, yValues);

            PiecewisePolynomialFunction1D function = new PiecewisePolynomialFunction1D();

            PiecewisePolynomialInterpolator interpPos = new MonotonicityPreservingCubicSplineInterpolator(interp);
            PiecewisePolynomialResult       resultPos = interpPos.interpolate(xValues, yValues);

            assertEquals(resultPos.Dimensions, result.Dimensions);
            assertEquals(resultPos.NumberOfIntervals, result.NumberOfIntervals);
            assertEquals(resultPos.Order, result.Order);

            assertTrue(function.evaluate(resultPos, 4.5).get(0) - function.evaluate(resultPos, 4).get(0) >= 0.0);
            assertTrue(function.evaluate(resultPos, 4.5).get(0) - function.evaluate(resultPos, 5).get(0) >= 0.0);
            assertTrue(function.evaluate(resultPos, 4.5).get(1) - function.evaluate(resultPos, 4).get(1) <= 0.0);
            assertTrue(function.evaluate(resultPos, 4.5).get(1) - function.evaluate(resultPos, 5).get(1) <= 0.0);

            const int nKeys = 41;
            double    key0  = 1.0;

            for (int i = 1; i < nKeys; ++i)
            {
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final double key = 1.0 + 3.0 / (nKeys - 1) * i;
                double key = 1.0 + 3.0 / (nKeys - 1) * i;
                assertTrue(function.evaluate(resultPos, key).get(0) - function.evaluate(resultPos, key0).get(0) >= 0.0);

                key0 = 1.0 + 3.0 / (nKeys - 1) * i;
            }
            key0 = 1.0;
            for (int i = 1; i < nKeys; ++i)
            {
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final double key = 1.0 + 3.0 / (nKeys - 1) * i;
                double key = 1.0 + 3.0 / (nKeys - 1) * i;
                assertTrue(function.evaluate(resultPos, key).get(1) - function.evaluate(resultPos, key0).get(1) <= 0.0);

                key0 = 1.0 + 3.0 / (nKeys - 1) * i;
            }
            key0 = 5.0;
            for (int i = 1; i < nKeys; ++i)
            {
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final double key = 5.0 + 3.0 / (nKeys - 1) * i;
                double key = 5.0 + 3.0 / (nKeys - 1) * i;
                assertTrue(function.evaluate(resultPos, key).get(0) - function.evaluate(resultPos, key0).get(0) <= 0.0);

                key0 = 5.0 + 3.0 / (nKeys - 1) * i;
            }
            key0 = 5.0;
            for (int i = 1; i < nKeys; ++i)
            {
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final double key = 5.0 + 3.0 / (nKeys - 1) * i;
                double key = 5.0 + 3.0 / (nKeys - 1) * i;
                assertTrue(function.evaluate(resultPos, key).get(1) - function.evaluate(resultPos, key0).get(1) >= 0.0);

                key0 = 5.0 + 3.0 / (nKeys - 1) * i;
            }
        }
        /// <summary>
        /// f(x0,x1) = ( x0 - 1.)^3 * (x1  + 14./13.)^3
        /// </summary>
        public virtual void cubicTest()
        {
            double[] x0Values = new double[] { 1.0, 2.0, 3.0, 4.0 };
            double[] x1Values = new double[] { -1.0, 0.0, 1.0, 2.0, 3.0 };
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final int n0Data = x0Values.length;
            int n0Data = x0Values.Length;
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final int n1Data = x1Values.length;
            int n1Data = x1Values.Length;

//JAVA TO C# CONVERTER NOTE: The following call to the 'RectangularArrays' helper class reproduces the rectangular array initialization that is automatic in Java:
//ORIGINAL LINE: double[][] yValues = new double[n0Data][n1Data];
            double[][] yValues = RectangularArrays.ReturnRectangularDoubleArray(n0Data, n1Data);

            for (int i = 0; i < n0Data; ++i)
            {
                for (int j = 0; j < n1Data; ++j)
                {
                    yValues[i][j] = (x0Values[i] - 1.0) * (x0Values[i] - 1.0) * (x0Values[i] - 1.0) * (x1Values[j] + 14.0 / 13.0) * (x1Values[j] + 14.0 / 13.0) * (x1Values[j] + 14.0 / 13.0);
                }
            }

            CubicSplineInterpolator           method = new CubicSplineInterpolator();
            PiecewisePolynomialInterpolator2D interp = new BicubicSplineInterpolator(method);
            PiecewisePolynomialResult2D       result = interp.interpolate(x0Values, x1Values, yValues);

//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final int n0IntExp = n0Data - 1;
            int n0IntExp = n0Data - 1;
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final int n1IntExp = n1Data - 1;
            int       n1IntExp = n1Data - 1;
            const int orderExp = 4;

            const int n0Keys = 51;
            const int n1Keys = 61;

            double[] x0Keys = new double[n0Keys];
            double[] x1Keys = new double[n1Keys];
            for (int i = 0; i < n0Keys; ++i)
            {
                x0Keys[i] = 0.0 + 5.0 * i / (n0Keys - 1);
            }
            for (int i = 0; i < n1Keys; ++i)
            {
                x1Keys[i] = -2.0 + 6.0 * i / (n1Keys - 1);
            }

            assertEquals(result.NumberOfIntervals[0], n0IntExp);
            assertEquals(result.NumberOfIntervals[1], n1IntExp);
            assertEquals(result.Order[0], orderExp);
            assertEquals(result.Order[1], orderExp);

            for (int i = 0; i < n0Data; ++i)
            {
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final double ref = Math.abs(x0Values[i]) == 0.0 ? 1.0 : Math.abs(x0Values[i]);
                double @ref = Math.Abs(x0Values[i]) == 0.0 ? 1.0 : Math.Abs(x0Values[i]);
                assertEquals(result.Knots0.get(i), x0Values[i], @ref * EPS);
                assertEquals(result.Knots2D[0].get(i), x0Values[i], @ref * EPS);
            }
            for (int i = 0; i < n1Data; ++i)
            {
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final double ref = Math.abs(x1Values[i]) == 0.0 ? 1.0 : Math.abs(x1Values[i]);
                double @ref = Math.Abs(x1Values[i]) == 0.0 ? 1.0 : Math.Abs(x1Values[i]);
                assertEquals(result.Knots1.get(i), x1Values[i], @ref * EPS);
                assertEquals(result.Knots2D[1].get(i), x1Values[i], @ref * EPS);
            }

            for (int i = 0; i < n0Data - 1; ++i)
            {
                for (int j = 0; j < n1Data - 1; ++j)
                {
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final double ref = Math.abs(yValues[i][j]) == 0.0 ? 1.0 : Math.abs(yValues[i][j]);
                    double @ref = Math.Abs(yValues[i][j]) == 0.0 ? 1.0 : Math.Abs(yValues[i][j]);
                    assertEquals(result.Coefs[i][j].get(orderExp - 1, orderExp - 1), yValues[i][j], @ref * EPS);
                }
            }

            DoubleMatrix resValues = interp.interpolate(x0Values, x1Values, yValues, x0Values, x1Values);
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final com.opengamma.strata.math.impl.function.PiecewisePolynomialFunction2D func2D = new com.opengamma.strata.math.impl.function.PiecewisePolynomialFunction2D();
            PiecewisePolynomialFunction2D func2D = new PiecewisePolynomialFunction2D();
            DoubleMatrix resDiffX0 = func2D.differentiateX0(result, x0Values, x1Values);
            DoubleMatrix resDiffX1 = func2D.differentiateX1(result, x0Values, x1Values);

//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final com.opengamma.strata.math.impl.function.PiecewisePolynomialFunction1D func1D = new com.opengamma.strata.math.impl.function.PiecewisePolynomialFunction1D();
            PiecewisePolynomialFunction1D func1D = new PiecewisePolynomialFunction1D();
            DoubleMatrix expDiffX0 = func1D.differentiate(method.interpolate(x0Values, OG_ALGEBRA.getTranspose(DoubleMatrix.copyOf(yValues)).toArray()), x0Values);
            DoubleMatrix expDiffX1 = func1D.differentiate(method.interpolate(x1Values, yValues), x1Values);

            for (int i = 0; i < n0Data; ++i)
            {
                for (int j = 0; j < n1Data; ++j)
                {
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final double expVal = expDiffX1.get(i, j);
                    double expVal = expDiffX1.get(i, j);
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final double ref = Math.abs(expVal) == 0.0 ? 1.0 : Math.abs(expVal);
                    double @ref = Math.Abs(expVal) == 0.0 ? 1.0 : Math.Abs(expVal);
                    assertEquals(resDiffX1.get(i, j), expVal, @ref * EPS);
                }
            }

            for (int i = 0; i < n0Data; ++i)
            {
                for (int j = 0; j < n1Data; ++j)
                {
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final double expVal = expDiffX0.get(j, i);
                    double expVal = expDiffX0.get(j, i);
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final double ref = Math.abs(expVal) == 0.0 ? 1.0 : Math.abs(expVal);
                    double @ref = Math.Abs(expVal) == 0.0 ? 1.0 : Math.Abs(expVal);
                    assertEquals(resDiffX0.get(i, j), expVal, @ref * EPS);
                }
            }

            for (int i = 0; i < n0Data; ++i)
            {
                for (int j = 0; j < n1Data; ++j)
                {
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final double expVal = yValues[i][j];
                    double expVal = yValues[i][j];
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final double ref = Math.abs(expVal) == 0.0 ? 1.0 : Math.abs(expVal);
                    double @ref = Math.Abs(expVal) == 0.0 ? 1.0 : Math.Abs(expVal);
                    assertEquals(resValues.get(i, j), expVal, @ref * EPS);
                }
            }
        }