def test_central_and_forward_derivative_on_log(self): # Although a central rule may put some samples in the wrong places, it # may still succeed epsilon = nd.MinStepGenerator(num_steps=15, offset=0, step_ratio=2) dlog = nd.Derivative(np.log, method='central', step=epsilon) x = 0.001 assert_allclose(dlog(x), 1.0 / x) # But forcing the use of a one-sided rule may be smart anyway dlog = nd.Derivative(np.log, method='forward', step=epsilon) assert_allclose(dlog(x), 1 / x)
def test_derivative_of_cos_x(x): note('x = {}'.format(x)) msg = 'order = {}, error = {}, err_est = {}' true_vals = (-np.sin(x), -np.cos(x), np.sin(x), np.cos(x)) * 2 for method in ['complex', 'central', 'forward', 'backward']: note('method = {}'.format(method)) n_max = dict(complex=7, central=6).get(method, 4) for n in range(1, n_max + 1): true_val = true_vals[n - 1] start, stop, step = dict(central=(2, 7, 2), complex=(2, 3, 1)).get(method, (1, 5, 1)) note('n = {}, true_val = {}'.format(n, true_val)) for order in range(start, stop, step): d3cos = nd.Derivative(np.cos, n=n, order=order, method=method, full_output=True) y, _info = d3cos(x) _error = np.abs(y - true_val) aerr = 100 * _info.error_estimate + 1e-14 # if aerr < 1e-14 and np.abs(true_val) < 1e-3: # aerr = 1e-8 note(msg.format(order, _error, _info.error_estimate)) assert_allclose(y, true_val, rtol=1e-6, atol=aerr)
def test_derivative_sin(): # Evaluate the indicated (default = first) # derivative at multiple points dsin = nd.Derivative(np.sin) x = np.linspace(0, 2. * np.pi, 13) y = dsin(x) assert_allclose(y, np.cos(x), atol=1e-8)
def test_derivative_sin(): # Evaluate the indicated (default = first) # derivative at multiple points dsin = nd.Derivative(np.sin) x = np.linspace(0, 2. * np.pi, 13) y = dsin(x) np.testing.assert_almost_equal(y, np.cos(x), decimal=8)
def test_derivative_of_cos_x(): x = np.r_[0, np.pi / 6.0, np.pi / 2.0] true_vals = (-np.sin(x), -np.cos(x), np.sin(x), np.cos(x), -np.sin(x), -np.cos(x)) for method in ['complex', 'central', 'forward', 'backward']: n_max = dict(complex=2, central=6).get(method, 5) for n in range(1, n_max + 1): true_val = true_vals[n - 1] start, stop, step = dict(central=(2, 7, 2), complex=(2, 3, 1)).get(method, (1, 5, 1)) for order in range(start, stop, step): d3cos = nd.Derivative(np.cos, n=n, order=order, method=method, full_output=True) y, _info = d3cos(x) _error = np.abs(y - true_val) # small = error <= info.error_estimate # if not small.all(): # small = np.where(small, small, error <= 10**(-11 + n)) # if not small.all(): # print('method=%s, n=%d, order=%d' % (method, n, order)) # print(error, info.error_estimate) assert_array_almost_equal(y, true_val, decimal=4)
def test_infinite_functions(self): def finf(x): return np.inf * np.ones_like(x) df = nd.Derivative(finf) val = df(0) assert np.isnan(val) df.n = 0 assert df(0) == np.inf
def test_infinite_functions(self): def finf(x): return np.inf * np.ones_like(x) df = nd.Derivative(finf) val = df(0) self.assert_(np.isnan(val)) df.n = 0 self.assertEqual(df(0), np.inf)
def test_derivative_cube(): """Test for Issue 7""" def cube(x): return x * x * x dcube = nd.Derivative(cube) shape = (3, 2) x = np.ones(shape) * 2 dx = dcube(x) assert_allclose(list(dx.shape), list(shape), err_msg='Shape mismatch') txt = 'First differing element %d\n value = %g,\n true value = %g' for i, (val, tval) in enumerate(zip(dx.ravel(), (3 * x**2).ravel())): assert_allclose(val, tval, rtol=1e-8, err_msg=txt % (i, val, tval))
def test_high_order_derivative(self): x = 0.5 methods = ['complex', 'central', 'forward', 'backward'] for name in function_names: for n in range(2, 11): f, true_df = get_function(name, n=n) if true_df is None: continue for method in methods: if n > 7 and method not in ['complex']: continue val = nd.Derivative(f, method=method, n=n)(x) print(name, method, n) assert_array_almost_equal(val, true_df(x), decimal=2)
def test_central_forward_backward(): central = { (1, 1): [-0.33333333, 1.33333333], (1, 2): [-0.33333333, 1.33333333], (1, 3): [-0.33333333, 1.33333333], (1, 4): [-0.06666667, 1.06666667], (1, 5): [-0.06666667, 1.06666667], (1, 6): [-0.01587302, 1.01587302], (2, 1): [0.02222222, -0.44444444, 1.42222222], (2, 2): [0.02222222, -0.44444444, 1.42222222], (2, 3): [0.02222222, -0.44444444, 1.42222222], (2, 4): [1.05820106e-03, -8.46560847e-02, 1.08359788e+00], (2, 5): [1.05820106e-03, -8.46560847e-02, 1.08359788e+00], (2, 6): [6.22471211e-05, -1.99190787e-02, 1.01985683e+00] } forward = { (1, 1): [-1., 2.], (1, 2): [-0.33333333, 1.33333333], (1, 3): [-0.14285714, 1.14285714], (1, 4): [-0.06666667, 1.06666667], (1, 5): [-0.03225806, 1.03225806], (1, 6): [-0.01587302, 1.01587302], (2, 1): [0.33333333, -2., 2.66666667], (2, 2): [0.04761905, -0.57142857, 1.52380952], (2, 3): [0.00952381, -0.22857143, 1.21904762], (2, 4): [0.00215054, -0.10322581, 1.10107527], (2, 5): [5.12032770e-04, -4.91551459e-02, 1.04864311e+00], (2, 6): [1.24984377e-04, -2.39970004e-02, 1.02387202e+00] } true_vals = { 'central': central, 'forward': forward, 'backward': forward } for method in true_vals: truth = true_vals[method] for num_terms in [1, 2]: for order in range(1, 7): d = nd.Derivative(np.exp, method=method, order=order) d.set_richardson_rule(step_ratio=2.0, num_terms=num_terms) rule = d.richardson.rule() assert_allclose(rule, truth[(num_terms, order)], atol=1e-8)
def test_high_order_derivative_cos(): true_vals = (0.0, -1.0, 0.0, 1.0, 0.0, -1.0, 0.0) methods = ['complex', 'multicomplex', 'central', 'forward', 'backward'] for method in methods: n_max = dict(multicomplex=2, central=6).get(method, 5) for n in range(0, n_max + 1): true_val = true_vals[n] for order in range(2, 9, 2): d3cos = nd.Derivative(np.cos, n=n, order=order, method=method, full_output=True) y, _info = d3cos(np.pi / 2.0) # _error = np.abs(y - true_val) # small = error <= info.error_estimate # if not small: # small = error < 10**(-12 + n) # if not small: # print('method=%s, n=%d, order=%d' % (method, n, order)) # print(error, info.error_estimate) # self.assertTrue(small) assert_allclose(y, true_val, atol=1e-4)
def test_complex(): truth = { (1, 2, 8): [9.576480164718605e-07, -0.004167684167715291, 1.004166726519699], (4, 2, 2): [0.0002614379084968331, -0.07111111111111235, 1.070849673202616], (1, 2, 4): [0.0002614379084968331, -0.07111111111111235, 1.070849673202616], (4, 1, 8): [-0.0039215686274510775, 1.0039215686274505], (2, 2, 4): [0.0002614379084968331, -0.07111111111111235, 1.070849673202616], (4, 2, 8): [9.576480164718605e-07, -0.004167684167715291, 1.004166726519699], (3, 1, 8): [-0.0039215686274510775, 1.0039215686274505], (4, 1, 2): [-0.06666666666666654, 1.0666666666666664], (3, 1, 6): [-0.06666666666666654, 1.0666666666666664], (1, 1, 8): [-0.0039215686274510775, 1.0039215686274505], (2, 1, 8): [-0.0039215686274510775, 1.0039215686274505], (4, 1, 4): [-0.06666666666666654, 1.0666666666666664], (3, 1, 4): [-0.06666666666666654, 1.0666666666666664], (2, 1, 4): [-0.06666666666666654, 1.0666666666666664], (3, 2, 2): [0.0002614379084968331, -0.07111111111111235, 1.070849673202616], (2, 2, 8): [9.576480164718605e-07, -0.004167684167715291, 1.004166726519699], (2, 1, 6): [-0.06666666666666654, 1.0666666666666664], (3, 1, 2): [-0.06666666666666654, 1.0666666666666664], (4, 1, 6): [-0.06666666666666654, 1.0666666666666664], (1, 1, 6): [-0.06666666666666654, 1.0666666666666664], (1, 2, 2): [0.022222222222222185, -0.444444444444444, 1.4222222222222216], (3, 2, 6): [0.0002614379084968331, -0.07111111111111235, 1.070849673202616], (1, 1, 4): [-0.06666666666666654, 1.0666666666666664], (2, 1, 2): [-0.06666666666666654, 1.0666666666666664], (4, 2, 4): [0.0002614379084968331, -0.07111111111111235, 1.070849673202616], (3, 2, 4): [0.0002614379084968331, -0.07111111111111235, 1.070849673202616], (2, 2, 2): [0.0002614379084968331, -0.07111111111111235, 1.070849673202616], (1, 2, 6): [ 0.0002614379084968331, -0.07111111111111235, 1.070849673202616 ], (4, 2, 6): [ 0.0002614379084968331, -0.07111111111111235, 1.070849673202616 ], (1, 1, 2): [-0.33333333333333304, 1.333333333333333], (3, 2, 8): [ 9.576480164718605e-07, -0.004167684167715291, 1.004166726519699 ], (2, 2, 6): [ 0.0002614379084968331, -0.07111111111111235, 1.070849673202616 ] } for n in [1, 2, 3, 4]: for num_terms in [1, 2]: for order in range(2, 9, 2): d = nd.Derivative(np.exp, n=n, method='complex', order=order) d.set_richardson_rule(step_ratio=2.0, num_terms=num_terms) rule = d.richardson.rule() msg = "n={0}, num_terms={1}, order={2}".format( n, num_terms, order) assert_allclose(rule, truth[(n, num_terms, order)], err_msg=msg)
def test_backward_derivative_on_sinh(self): # Compute the derivative of a function using a backward difference # scheme. A backward scheme will only look below x0. dsinh = nd.Derivative(np.sinh, method='backward') assert_allclose(dsinh(0.0), np.cosh(0.0))
def test_derivative_exp(): # derivative of exp(x), at x == 0 dexp = nd.Derivative(np.exp) assert_allclose(dexp(0), np.exp(0), rtol=1e-8)
def test_derivative_exp(): # derivative of exp(x), at x == 0 dexp = nd.Derivative(np.exp) assert_array_almost_equal(dexp(0), np.exp(0), decimal=8)