Exemple #1
0
    def test_NaN_exception(self):
        np.random.seed(1234)
        x = np.linspace(0, 2, 5)
        y = np.linspace(0, 1, 7)
        values = np.random.rand(5, 7)
        interp = InterpND((x, y), values)

        with self.assertRaises(OutOfBoundsError) as cm:
            interp.interpolate(np.array([1, np.nan]))

        err = cm.exception

        self.assertEqual(str(err), 'One of the requested xi contains a NaN')
        self.assertEqual(err.idx, 1)
        self.assertTrue(np.isnan(err.value))
        self.assertEqual(err.lower, 0)
        self.assertEqual(err.upper, 1)
Exemple #2
0
    def test_error_messages(self):
        # For coverage. Most of these errors are probably not reachable in openmdao, but
        # proper unit testing requires them for standalone usage of the Interpolation.
        points, values = self._get_sample_4d_large()

        with self.assertRaises(ValueError) as cm:
            interp = InterpND(points, values.tolist(), interp_method='junk')

        msg = ('Interpolation method "junk" is not defined. Valid methods are')
        self.assertTrue(str(cm.exception).startswith(msg))

        with self.assertRaises(ValueError) as cm:
            interp = InterpND(points, values.tolist()[1])

        msg = ('There are 4 point arrays, but values has 3 dimensions')
        self.assertEqual(str(cm.exception), msg)

        badpoints = deepcopy(points)
        badpoints[0][0] = 55.0
        with self.assertRaises(ValueError) as cm:
            interp = InterpND(badpoints, values.tolist())

        msg = ('The points in dimension 0 must be strictly ascending')
        self.assertEqual(str(cm.exception), msg)

        badpoints[0] = np.vstack((np.arange(6), np.arange(6)))
        with self.assertRaises(ValueError) as cm:
            interp = InterpND(badpoints, values.tolist())

        msg = ('The points in dimension 0 must be 1-dimensional')
        self.assertEqual(str(cm.exception), msg)

        badpoints[0] = (np.arange(4))
        with self.assertRaises(ValueError) as cm:
            interp = InterpND(badpoints, values.tolist())

        msg = ('There are 4 points and 6 values in dimension 0')
        self.assertEqual(str(cm.exception), msg)

        badvalues = np.array(values, dtype=np.complex)
        with self.assertRaises(ValueError) as cm:
            interp = InterpND(badpoints, badvalues.tolist())

        msg = ("Interpolation method 'slinear' does not support complex values.")
        self.assertEqual(str(cm.exception), msg)

        interp = InterpND(points, values.tolist())
        x = [0.5, 0, 0.5, 0.9]

        with self.assertRaises(KeyError) as cm:
            interp = InterpND(points, values.tolist(), interp_method="slinear",
                              bad_arg=1)

        msg = ("\"InterpLinear: Option 'bad_arg' cannot be set because it has not been declared.")
        self.assertTrue(str(cm.exception).startswith(msg))
    def test_derivative_hysteresis_bug(self):
        alt = np.array([-1000, 0, 1000], dtype=float)
        rho = np.array([0.00244752, 0.00237717, 0.00230839])

        rho_interp = InterpND(method='slinear',
                              points=alt,
                              values=rho,
                              extrapolate=True)

        x = 0.0
        _, dval1 = rho_interp.interpolate([x], compute_derivative=True)

        x = 0.5
        _, dval2 = rho_interp.interpolate([x], compute_derivative=True)

        x = 0.0
        _, dval3 = rho_interp.interpolate([x], compute_derivative=True)

        x = -0.5
        _, dval4 = rho_interp.interpolate([x], compute_derivative=True)

        x = 0.0
        _, dval5 = rho_interp.interpolate([x], compute_derivative=True)

        assert_near_equal(dval3 - dval1, np.array([[0.0]]))
        assert_near_equal(dval5 - dval1, np.array([[0.0]]))
    def test_interpolating_spline_derivs(self):
        n_cp = 12
        n_point = 21

        t = np.linspace(0, 3.0*np.pi, n_cp)
        tt = np.linspace(0, 3.0*np.pi, n_point)

        x = np.sin(t)

        for method in self.spline_methods:
            interp = InterpND(method=method, points=t, x_interp=tt)
            computed, deriv = interp.evaluate_spline(x, compute_derivative=True)

            x_expected = np.sin(tt)
            delta = computed.flatten() - x_expected

            # Here we test that we don't have crazy interpolation error.
            self.assertLess(max(delta), .25)
    def test_trilinear(self):
        # Test trilinear vs 3d slinear.

        p1 = np.linspace(0, 100, 25)
        p2 = np.linspace(-10, 10, 15)
        p3 = np.linspace(0, 1, 12)

        # can use meshgrid to create a 3D array of test data
        P1, P2, P3 = np.meshgrid(p1, p2, p3, indexing='ij')
        f_p = np.sqrt(P1) + P2 * P3

        x1 = np.linspace(-2, 101, 5)
        x2 = np.linspace(-10.5, 11, 5)
        x3 = np.linspace(-0.2, 1.1, 5)
        X1, X2, X3 = np.meshgrid(x1, x2, x3, indexing='ij')
        x = np.zeros((125, 3))
        x[:, 0] = X1.ravel()
        x[:, 1] = X2.ravel()
        x[:, 2] = X3.ravel()

        interp = InterpND(points=(p1, p2, p3),
                          values=f_p,
                          method='trilinear',
                          extrapolate=True)
        f, df_dx = interp.interpolate(x, compute_derivative=True)

        interp_base = InterpND(points=(p1, p2, p3),
                               values=f_p,
                               method='slinear',
                               extrapolate=True)
        f_base, df_dx_base = interp_base.interpolate(x,
                                                     compute_derivative=True)

        assert_near_equal(f, f_base, 1e-11)
        assert_near_equal(df_dx, df_dx_base, 1e-11)

        # Test non-vectorized.
        for j, x_i in enumerate(x):
            interp = InterpND(points=(p1, p2, p3),
                              values=f_p,
                              method='trilinear',
                              extrapolate=True)
            f, df_dx = interp.interpolate(x_i, compute_derivative=True)

            assert_near_equal(f, f_base[j], 1e-11)
            assert_near_equal(df_dx[0], df_dx_base[j, :], 1e-11)
    def test_bsplines_interpolating_spline(self):
        n_cp = 80
        n_point = 160

        t = np.linspace(0, 3.0 * np.pi, n_cp)
        tt = np.linspace(0, 3.0 * np.pi, n_point)

        x = np.sin(t)

        # Now, test newer interface for order_reducing spline.

        interp = InterpND(method='bsplines', points=t, x_interp=tt)
        computed = interp.evaluate_spline(x)

        x_expected = np.sin(tt)
        delta = computed.flatten() - x_expected

        # Here we test that we don't have crazy interpolation error.
        self.assertLess(max(delta), .15)
        # And that it gets middle points a little better.
        self.assertLess(max(delta[15:-15]), .06)
    def test_table_interp(self):

        # create input param training data, of sizes 25, 5, and 10 points resp.
        p1 = np.linspace(0, 100, 25)
        p2 = np.linspace(-10, 10, 5)
        p3 = np.linspace(0, 1, 10)

        # can use meshgrid to create a 3D array of test data
        P1, P2, P3 = np.meshgrid(p1, p2, p3, indexing='ij')
        f = np.sqrt(P1) + P2 * P3

        interp = InterpND(method='lagrange3', points=(p1, p2, p3), values=f)

        x = np.array([55.12, -2.14, 0.323])
        f, df_dx = interp.interpolate(x, compute_derivative=True)

        actual = np.array([6.73306794])
        deriv_actual = np.array([[0.06734927, 0.323, -2.14]])

        assert_near_equal(f, actual, tolerance=1e-7)
        assert_near_equal(df_dx, deriv_actual, tolerance=1e-7)
    def test_spline_out_of_bounds_extrap(self):
        points, values, func, df = self. _get_sample_2d()
        np.random.seed(5)
        test_pt = np.random.uniform(3, 3.1, 2)
        actual = func(*test_pt)
        gradient = np.array(df(*test_pt))
        tol = 1e-1
        for method in self.interp_methods:
            k = self.interp_configs[method]
            if method == 'slinear':
                tol = 2
            interp = InterpND(method=method, points=points, values=values,
                              extrapolate=True)
            computed, computed_grad = interp.interpolate(test_pt, compute_derivative=True)
            computed_grad = interp.gradient(test_pt)
            r_err = rel_error(actual, computed)
            assert r_err < tol

            r_err = rel_error(gradient, computed_grad)
            # extrapolated gradients are even trickier, but usable still
            assert r_err < 2 * tol
Exemple #9
0
    def test_interp_spline_akima(self):

        xcp = np.array([1.0, 2.0, 4.0, 6.0, 10.0, 12.0])
        ycp = np.array([5.0, 12.0, 14.0, 16.0, 21.0, 29.0])
        n = 50
        x = np.linspace(1.0, 12.0, n)

        interp = InterpND(method='akima', points=xcp, x_interp=x, delta_x=0.1)
        y = interp.evaluate_spline(ycp)

        assert_near_equal(y,
                          np.array([ 5.       ,  7.20902005,  9.21276849, 10.81097162, 11.80335574,
                                     12.1278001 , 12.35869145, 12.58588536, 12.81022332, 13.03254681,
                                     13.25369732, 13.47451633, 13.69584534, 13.91852582, 14.14281484,
                                     14.36710105, 14.59128625, 14.81544619, 15.03965664, 15.26399335,
                                     15.48853209, 15.7133486 , 15.93851866, 16.16573502, 16.39927111,
                                     16.63928669, 16.8857123 , 17.1384785 , 17.39751585, 17.66275489,
                                     17.93412619, 18.21156029, 18.49498776, 18.78433915, 19.07954501,
                                     19.38053589, 19.68724235, 19.99959495, 20.31752423, 20.64096076,
                                     20.96983509, 21.37579297, 21.94811407, 22.66809748, 23.51629844,
                                     24.47327219, 25.51957398, 26.63575905, 27.80238264, 29.        ]),
                          tolerance=1e-6)
Exemple #10
0
    def test_interp_spline_akima_derivs(self):

        xcp = np.array([1.0, 2.0, 4.0, 6.0, 10.0, 12.0])
        ycp = np.array([5.0, 12.0, 14.0, 16.0, 21.0, 29.0])
        n = 5
        x = np.linspace(1.0, 12.0, n)

        interp = InterpND(method='akima', points=xcp, x_interp=x, delta_x=0.1)
        y, dy_dycp = interp.evaluate_spline(ycp, compute_derivative=True)

        assert_near_equal(dy_dycp,
                          np.array([[ 1.00000000e+00,  0.00000000e+00,  0.00000000e+00,
                                      0.00000000e+00,  0.00000000e+00,  0.00000000e+00],
                                    [-1.86761492e-06,  3.31278014e-02,  1.05874907e+00,
                                     -9.18750000e-02,  0.00000000e+00,  0.00000000e+00],
                                    [ 0.00000000e+00,  0.00000000e+00, -2.10964627e-01,
                                      1.19119941e+00,  2.02602810e-02, -4.95062934e-04],
                                    [ 0.00000000e+00,  0.00000000e+00, -2.64126732e-01,
                                      5.82784977e-01,  6.83151998e-01, -1.81024253e-03],
                                    [ 0.00000000e+00,  0.00000000e+00,  0.00000000e+00,
                                      0.00000000e+00,  0.00000000e+00,  1.00000000e+00]]),
                          tolerance=1e-6)
Exemple #11
0
    def test_interp_spline_bsplines(self):

        xcp = np.array([1.0, 2.0, 4.0, 6.0, 10.0, 12.0])
        ycp = np.array([5.0, 12.0, 14.0, 16.0, 21.0, 29.0])
        n = 50
        x = np.linspace(1.0, 12.0, n)

        interp = InterpND(method='bsplines', num_cp=6, x_interp=x)

        y = interp.evaluate_spline(ycp)

        assert_near_equal(y,
                          np.array([ 9.21614583,  9.90911525, 10.52244151, 11.06231159, 11.53491244,
                                     11.94643105, 12.30305438, 12.61096939, 12.87636305, 13.10542234,
                                     13.30433422, 13.47928566, 13.63646363, 13.7820551 , 13.92203064,
                                     14.05954727, 14.19579437, 14.33192094, 14.46907599, 14.60840854,
                                     14.75106758, 14.89820214, 15.05096121, 15.2104938 , 15.37794893,
                                     15.5544756 , 15.74122282, 15.9393396 , 16.14997495, 16.37427787,
                                     16.61339737, 16.86848247, 17.14102103, 17.43486416, 17.75486932,
                                     18.10589772, 18.49281052, 18.92046894, 19.39373414, 19.91746734,
                                     20.4965297 , 21.13578243, 21.8400867 , 22.61430372, 23.46329467,
                                     24.39192074, 25.40504312, 26.507523  , 27.70422156, 29.        ]),
                          tolerance=1e-6)
Exemple #12
0
    def test_cs_across_interp(self):
        # The standalone interpolator is used inside of components, so the imaginary part must
        # be carried through all operations to the outputs.
        xcp = np.array([1.0, 2.0, 4.0, 6.0, 10.0, 12.0])
        ycp = np.array([5.0, 12.0, 14.0, 16.0, 21.0, 29.0])
        n = 50
        x = np.linspace(1.0, 12.0, n)

        ycp = np.array([[5.0 + 1j, 12.0, 14.0, 16.0, 21.0, 29.0],
                        [5.0, 12.0 + 1j, 14.0, 16.0, 21.0, 29.0]])

        for method in SPLINE_METHODS:

            # complex step not supported on scipy methods
            if method.startswith('scipy'):
                continue

            interp = InterpND(method=method, points=xcp, x_interp=x)
            y, dy = interp.evaluate_spline(ycp, compute_derivative=True)

            self.assertTrue(y.dtype == complex)

            if method in ['akima']:
                # Derivs depend on values only for akima.
                self.assertTrue(dy.dtype == complex)

        p1 = np.linspace(0, 100, 25)
        p2 = np.linspace(-10, 10, 5)
        p3 = np.linspace(0, 1, 10)

        # can use meshgrid to create a 3D array of test data
        P1, P2, P3 = np.meshgrid(p1, p2, p3, indexing='ij')
        f = np.sqrt(P1) + P2 * P3

        x = np.array([[55.12 + 1j, -2.14, 0.323],
                      [55.12, -2.14 + 1j, 0.323],
                      [55.12, -2.14, 0.323 + 1j]])

        for method in TABLE_METHODS:

            # complex step not supported on scipy methods
            if method.startswith('scipy'):
                continue

            if method in ['1D-akima', 'akima1D']:
                # These methods are for fixed grids other than 3d.
                continue

            interp = InterpND(method=method, points=(p1, p2, p3), values=f)
            y, dy = interp.interpolate(x, compute_derivative=True)

            self.assertTrue(y.dtype == complex)
            self.assertTrue(dy.dtype == complex)
Exemple #13
0
    def _setup_var_data(self):
        """
        Instantiate surrogates for the output variables that use the default surrogate.
        """
        interp_method = self.options['method']

        opts = {}
        if 'interp_options' in self.options:
            opts = self.options['interp_options']
        for name, train_data in self.training_outputs.items():
            self.interps[name] = InterpND(method=interp_method,
                                          points=self.params, values=train_data,
                                          extrapolate=self.options['extrapolate'])

        if self.options['training_data_gradients']:
            self.grad_shape = tuple([self.options['vec_size']] + [i.size for i in self.params])

        super(MetaModelStructuredComp, self)._setup_var_data()
    def test_akima1D(self):
        # Test akima1D vs 1D akima.

        p = np.linspace(0, 100, 25)
        f_p = np.cos(p * np.pi * 0.5)
        x = np.linspace(-1, 101, 33)

        interp = InterpND(points=p,
                          values=f_p,
                          method='akima1D',
                          extrapolate=True)
        f, df_dx = interp.interpolate(x, compute_derivative=True)

        interp_base = InterpND(points=p,
                               values=f_p,
                               method='akima',
                               extrapolate=True)
        f_base, df_dx_base = interp_base.interpolate(x,
                                                     compute_derivative=True)

        assert_near_equal(f, f_base, 1e-13)
        assert_near_equal(df_dx, df_dx_base.ravel(), 1e-13)

        # Test non-vectorized.
        for j, x_i in enumerate(x):
            interp = InterpND(points=p,
                              values=f_p,
                              method='akima1D',
                              extrapolate=True)
            f, df_dx = interp.interpolate(x_i, compute_derivative=True)

            assert_near_equal(f, f_base[j], 1e-13)

            # Compare abs error since deriv is near zero in some spots.
            abs_err = np.abs(df_dx[0] - df_dx_base[j])
            assert_near_equal(abs_err, 0.0, 1e-13)
    def test_minimum_required_gridsize(self):
        for method in self.interp_methods:

            # Scipy does order reduction as needed.
            if method.startswith('scipy'):
                continue

            k = self.interp_configs[method] - 1
            x = np.linspace(0, 1, k)
            y = np.linspace(0, 1, k)
            points = [x, y]
            X, Y = np.meshgrid(*points, indexing='ij')
            values = X + Y
            #self.assertRaises(ValueError, InterpND, points, values, method)
            with self.assertRaises(ValueError) as cm:
                interp = InterpND(method=method, points=points, values=values)

            msg = 'There are {} points in a data dimension, but method'.format(k)
            self.assertTrue(str(cm.exception).startswith(msg))
Exemple #16
0
    def _setup_var_data(self, recurse=True):
        """
        Instantiate surrogates for the output variables that use the default surrogate.

        Parameters
        ----------
        recurse : bool
            Whether to call this method in subsystems.
        """
        interp_method = self.options['method']

        for name, train_data in iteritems(self.training_outputs):
            self.interps[name] = InterpND(self.params, train_data,
                                          interp_method=interp_method,
                                          bounds_error=not self.options['extrapolate'])

        if self.options['training_data_gradients']:
            self.grad_shape = tuple([self.options['vec_size']] + [i.size for i in self.params])

        super(MetaModelStructuredComp, self)._setup_var_data(recurse=recurse)
Exemple #17
0
    def setup(self):
        """
        Perform some final setup and checks.
        """
        interp_method = self.options['method']

        x_cp_val = self.options['x_cp_val']
        n_cp = self.options['num_cp']

        if x_cp_val is not None:

            if interp_method == 'bsplines':
                msg = "{}: 'x_cp_val' is not a valid option when using method 'bsplines'. "
                msg += "Set 'num_cp' instead."
                raise ValueError(msg.format(self.msginfo))

            if n_cp is not None:
                msg = "{}: It is not valid to set both options 'x_cp_val' and 'num_cp'."
                raise ValueError(msg.format(self.msginfo))

            grid = np.asarray(x_cp_val)
            n_cp = len(grid)

        elif n_cp is not None:
            grid = np.linspace(0, 1.0, n_cp)

        else:
            msg = "{}: Either option 'x_cp_val' or 'num_cp' must be set."
            raise ValueError(msg.format(self.msginfo))

        self._n_cp = n_cp
        opts = {}
        if 'interp_options' in self.options:
            opts = self.options['interp_options']

        vec_size = self.options['vec_size']
        n_interp = len(self.options['x_interp_val'])

        for y_cp_name, y_interp_name, y_cp_val, y_units in self._spline_cache:

            self.add_output(y_interp_name, np.ones((vec_size, n_interp)), units=y_units)

            if y_cp_val is None:
                y_cp_val = np.ones((vec_size, n_cp))

            elif len(y_cp_val.shape) < 2:
                y_cp_val = y_cp_val.reshape((vec_size, n_cp))

            self.add_input(name=y_cp_name, val=y_cp_val, units=y_units)

            self.interp_to_cp[y_interp_name] = y_cp_name

            row = np.repeat(np.arange(n_interp), n_cp)
            col = np.tile(np.arange(n_cp), n_interp)
            rows = np.tile(row, vec_size) + \
                np.repeat(n_interp * np.arange(vec_size), n_interp * n_cp)
            cols = np.tile(col, vec_size) + np.repeat(n_cp * np.arange(vec_size), n_interp * n_cp)

            self.declare_partials(y_interp_name, y_cp_name, rows=rows, cols=cols)

            # Separate data for each vec_size, but we only need to do sizing, so just pass
            # in the first.  Most interps aren't vectorized.
            cp_val = y_cp_val[0, :]
            self.interps[y_interp_name] = InterpND(points=(grid, ), values=cp_val,
                                                   method=interp_method,
                                                   x_interp=self.options['x_interp_val'],
                                                   extrapolate=True, **opts)

        # The scipy methods do not support complex step.
        if self.options['method'].startswith('scipy'):
            self.set_check_partial_options('*', method='fd')
Exemple #18
0
    def test_auto_reduce_spline_order(self):
        # if a spline method is used and spline_dim_error=False and a dimension
        # does not have enough points, the spline order for that dimension
        # should be automatically reduced
        np.random.seed(314)

        # x dimension is too small for cubic, should fall back to linear
        x = [0, 1]
        y = np.linspace(-10, 4, 10)
        z = np.linspace(1000, 2000, 20)

        points = [x, y, z]
        values = np.random.randn(2, 10, 20)

        interp = InterpND(points, values, interp_method='scipy_cubic')

        # first dimension (x) should be reduced to k=1 (linear)
        self.assertEqual(interp.table._ki[0], 1)

        # should operate as normal
        x = np.array([0.5, 0, 1001])
        result = interp.interpolate(x)
        assert_almost_equal(result, -0.046325695741704434, decimal=5)

        interp = InterpND(points, values, interp_method='scipy_slinear')
        value1 = interp.interpolate(x)

        # cycle through different methods that require order reduction
        # in the first dimension
        interp = InterpND(points, values, interp_method='scipy_quintic')
        value2 = interp.interpolate(x)
        interp.gradient(x)
        interp = InterpND(points, values, interp_method='scipy_cubic')
        value3 = interp.interpolate(x)
        interp.gradient(x)

        # values from different methods should be different
        self.assertTrue(value1[0] != value2[0])
        self.assertTrue(value2[0] != value3[0])
    def test_interp_akima_derivs(self):

        xcp = np.array([1.0, 2.0, 4.0, 6.0, 10.0, 12.0])
        ycp = np.array([5.0, 12.0, 14.0, 16.0, 21.0, 29.0])
        n = 23
        x = np.linspace(1.0, 12.0, n)

        interp = InterpND(method='akima', points=xcp, x_interp=x, delta_x=0.1)
        y, dy_dycp = interp.evaluate_spline(ycp, compute_derivative=True)

        deriv = np.array([[
            1.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
            0.00000000e+00, 0.00000000e+00
        ],
                          [
                              3.12508538e-01, 7.81237193e-01, -9.37457312e-02,
                              0.00000000e+00, 0.00000000e+00, 0.00000000e+00
                          ],
                          [
                              0.00000000e+00, 1.00000000e+00, 0.00000000e+00,
                              0.00000000e+00, 0.00000000e+00, 0.00000000e+00
                          ],
                          [
                              -1.92097534e-05, 7.05028815e-01, 3.39990395e-01,
                              -4.50000000e-02, 0.00000000e+00, 0.00000000e+00
                          ],
                          [
                              -1.70753364e-05, 3.80025613e-01, 7.39991462e-01,
                              -1.20000000e-01, 0.00000000e+00, 0.00000000e+00
                          ],
                          [
                              -6.40325114e-06, 1.15009605e-01, 1.01999680e+00,
                              -1.35000000e-01, 0.00000000e+00, 0.00000000e+00
                          ],
                          [
                              0.00000000e+00, 1.11022302e-16, 1.00000000e+00,
                              0.00000000e+00, 0.00000000e+00, 0.00000000e+00
                          ],
                          [
                              0.00000000e+00, -5.62500000e-03, 7.60412946e-01,
                              2.45667949e-01, -5.30632175e-04, 7.47369260e-05
                          ],
                          [
                              0.00000000e+00, -5.00000000e-03, 5.07767857e-01,
                              4.98447864e-01, -1.41501913e-03, 1.99298469e-04
                          ],
                          [
                              0.00000000e+00, -1.87500000e-03, 2.51238839e-01,
                              7.52003846e-01, -1.59189652e-03, 2.24210778e-04
                          ],
                          [
                              0.00000000e+00, 0.00000000e+00, 1.11022302e-16,
                              1.00000000e+00, 0.00000000e+00, 0.00000000e+00
                          ],
                          [
                              0.00000000e+00, 0.00000000e+00, -2.10964627e-01,
                              1.19119941e+00, 2.02602810e-02, -4.95062934e-04
                          ],
                          [
                              0.00000000e+00, 0.00000000e+00, -3.55003720e-01,
                              1.28195585e+00, 7.41473347e-02, -1.09946322e-03
                          ],
                          [
                              0.00000000e+00, 0.00000000e+00, -4.35442243e-01,
                              1.27731946e+00, 1.59810592e-01, -1.68780891e-03
                          ],
                          [
                              0.00000000e+00, 0.00000000e+00, -4.55605159e-01,
                              1.18234038e+00, 2.75399483e-01, -2.13470805e-03
                          ],
                          [
                              0.00000000e+00, 0.00000000e+00, -4.18817429e-01,
                              1.00206876e+00, 4.19063438e-01, -2.31476868e-03
                          ],
                          [
                              0.00000000e+00, 0.00000000e+00, -3.28404018e-01,
                              7.41554727e-01, 5.88951889e-01, -2.10259885e-03
                          ],
                          [
                              0.00000000e+00, 0.00000000e+00, -1.87689887e-01,
                              4.05848427e-01, 7.83214266e-01, -1.37280661e-03
                          ],
                          [
                              0.00000000e+00, 0.00000000e+00, 2.22044605e-16,
                              0.00000000e+00, 1.00000000e+00, 4.33680869e-19
                          ],
                          [
                              0.00000000e+00, 0.00000000e+00, 1.18164062e-01,
                              -2.58789062e-01, 1.05371094e+00, 8.69140625e-02
                          ],
                          [
                              0.00000000e+00, 0.00000000e+00, 1.05034722e-01,
                              -2.50868056e-01, 8.32465278e-01, 3.13368056e-01
                          ],
                          [
                              0.00000000e+00, 0.00000000e+00, 3.93880208e-02,
                              -1.17513021e-01, 4.44986979e-01, 6.33138021e-01
                          ],
                          [
                              0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
                              0.00000000e+00, 0.00000000e+00, 1.00000000e+00
                          ]])

        assert_near_equal(deriv, dy_dycp, tolerance=1e-6)
    def test_error_messages(self):
        points, values = self._get_sample_4d_large()

        with self.assertRaises(ValueError) as cm:
            interp = InterpND(method='junk',
                              points=points,
                              values=values.tolist())

        msg = ('Interpolation method "junk" is not defined. Valid methods are')
        self.assertTrue(str(cm.exception).startswith(msg))

        with self.assertRaises(ValueError) as cm:
            interp = InterpND(method=points,
                              points=points,
                              values=values.tolist())

        msg = ("Argument 'method' should be a string.")
        self.assertTrue(str(cm.exception).startswith(msg))

        with self.assertRaises(ValueError) as cm:
            interp = InterpND(method='slinear',
                              points=points,
                              values=values.tolist()[1])

        msg = ('There are 4 point arrays, but values has 3 dimensions')
        self.assertEqual(str(cm.exception), msg)

        badpoints = deepcopy(points)
        badpoints[0][0] = 55.0
        with self.assertRaises(ValueError) as cm:
            interp = InterpND(method='slinear',
                              points=badpoints,
                              values=values.tolist())

        msg = ('The points in dimension 0 must be strictly ascending')
        self.assertEqual(str(cm.exception), msg)

        badpoints[0] = np.vstack((np.arange(6), np.arange(6)))
        with self.assertRaises(ValueError) as cm:
            interp = InterpND(method='slinear',
                              points=badpoints,
                              values=values.tolist())

        msg = ('The points in dimension 0 must be 1-dimensional')
        self.assertEqual(str(cm.exception), msg)

        badpoints[0] = (np.arange(4))
        with self.assertRaises(ValueError) as cm:
            interp = InterpND(method='slinear',
                              points=badpoints,
                              values=values.tolist())

        msg = ('There are 4 points and 6 values in dimension 0')
        self.assertEqual(str(cm.exception), msg)

        badvalues = np.array(values, dtype=complex)
        with self.assertRaises(ValueError) as cm:
            interp = InterpND(method='slinear',
                              points=badpoints,
                              values=badvalues.tolist())

        msg = (
            "Interpolation method 'slinear' does not support complex values.")
        self.assertEqual(str(cm.exception), msg)

        interp = InterpND(method='slinear',
                          points=points,
                          values=values.tolist())
        x = [0.5, 0, 0.5, 0.9]

        with self.assertRaises(KeyError) as cm:
            interp = InterpND(method='slinear',
                              points=points,
                              values=values.tolist(),
                              bad_arg=1)

        msg = (
            "\"InterpLinear: Option 'bad_arg' cannot be set because it has not been declared."
        )
        self.assertTrue(str(cm.exception).startswith(msg))

        # Bspline not supported for tables.
        points, values, func, df = self._get_sample_2d()
        with self.assertRaises(ValueError) as cm:
            interp = InterpND(method='bsplines', points=points, values=values)

        msg = "Method 'bsplines' is not supported for table interpolation."
        self.assertTrue(str(cm.exception).startswith(msg))

        with self.assertRaises(ValueError) as cm:
            interp = InterpND(method='bsplines', points=points)

        msg = "Either 'values' or 'x_interp' must be specified."
        self.assertTrue(str(cm.exception).startswith(msg))