def test_high_order_derivative(x): small_radius = ['sqrt', 'log', 'log2', 'log10', 'arccos', 'log1p', 'arcsin', 'arctan', 'arcsinh', 'tan', 'tanh', 'arctanh', 'arccosh'] r = 0.0061 n_max = 20 y = x for name in function_names + ['arccosh', 'arctanh']: f, true_df = get_function(name, n=1) if name == 'arccosh': y = y + 1 vals, info = derivative(f, y, r=r, n=n_max, full_output=True, step_ratio=1.6) for n in range(1, n_max): f, true_df = get_function(name, n=n) if true_df is None: continue tval = true_df(y) aerr0 = info.error_estimate[n] + 1e-15 aerr = min(aerr0, max(np.abs(tval)*1e-6, 1e-8)) print(n, name, y, vals[n], tval, info.iterations, aerr0, aerr) note("{}, {}, {}, {}, {}, {}, {}, {}".format( n, name, y, vals[n], tval, info.iterations, aerr0, aerr)) assert_allclose(np.real(vals[n]), tval, rtol=1e-6, atol=aerr)
def test_high_order_derivative(x): # small_radius = ['sqrt', 'log', 'log2', 'log10', 'arccos', 'log1p', # 'arcsin', 'arctan', 'arcsinh', 'tan', 'tanh', # 'arctanh', 'arccosh'] r = 0.0061 n_max = 20 y = x for name in function_names + ['arccosh', 'arctanh']: f, true_df = get_function(name, n=1) if name == 'arccosh': y = y + 1 vals, info = derivative(f, y, r=r, n=n_max, full_output=True, step_ratio=1.6) for n in range(1, n_max): f, true_df = get_function(name, n=n) if true_df is None: continue tval = true_df(y) aerr0 = info.error_estimate[n] + 1e-15 aerr = min(aerr0, max(np.abs(tval) * 1e-6, 1e-8)) print(n, name, y, vals[n], tval, info.iterations, aerr0, aerr) note("{}, {}, {}, {}, {}, {}, {}, {}".format( n, name, y, vals[n], tval, info.iterations, aerr0, aerr)) assert_allclose(np.real(vals[n]), tval, rtol=1e-6, atol=aerr)
def test_high_order_derivative(): x = 0.5 min_dm = dict(complex=2, forward=2, backward=2, central=4) methods = ['complex', 'central', 'backward', 'forward'] derivatives = [nd.Derivative] if nda is not None: derivatives.append(nda.Derivative) for i, derivative in enumerate(derivatives): for name in function_names: if i > 0 and name in ['arcsinh', 'exp2']: continue for n in range(1, 11): f, true_df = get_function(name, n=n) if true_df is None: continue for method in methods[3 * i:]: if i == 0 and n > 7 and method not in ['complex']: continue df = derivative(f, method=method, n=n, full_output=True) val, info = df(x) dm = max(int(-np.log10(info.error_estimate + 1e-16)) - 1, min_dm.get(method, 4)) print(i, name, method, n, dm) tval = true_df(x) assert_array_almost_equal(val, tval, decimal=dm)
def _test_first_derivative(name): x = np.linspace(0.0001, 0.98, 5) h = _default_base_step(x, scale=2) f, df = get_function(name, n=1) der = f(bicomplex(x + h * 1j, 0)).imag1 / h der_true = df(x) np.testing.assert_allclose(der, der_true, err_msg=('{0!s}'.format(name)))
def _test_second_derivative(name): x = np.linspace(0.01, 0.98, 5) h = _default_base_step(x, scale=2.5) # h = 1e-8 f, df = get_function(name, n=2) der = f(bicomplex(x + h * 1j, h)).imag12 / h**2 der_true = df(x) np.testing.assert_allclose(der, der_true, err_msg=('{0!s}'.format(name)))
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_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_first_order_derivative(self): x = 0.5 methods = ['complex', 'central', 'backward', 'forward'] for i, derivative in enumerate( [nd.Derivative, nds.Gradient, nda.Derivative]): for name in function_names: if i > 1 and name in ['arcsinh', 'exp2']: continue f, true_df = get_function(name, n=1) if true_df is None: continue for method in methods[3 * (i > 1):]: df = derivative(f, method=method) val = df(x) tval = true_df(x) dm = 7 print(i, name, method, dm, np.abs(val - tval)) assert_array_almost_equal(val, tval, decimal=dm)
def main(): x = 0.5 methods = ['complex', 'central', 'backward', 'forward'] # for i, Derivative in enumerate([nd.Derivative, nds.Gradient, # nda.Derivative]): i = 0 Derivative = nd.Derivative for name in function_names: if i > 1 and name in ['arcsinh', 'exp2']: continue f, true_df = get_function(name, n=1) if true_df is None: continue for method in methods[3 * (i > 1):]: df = Derivative(f, method=method) val = df(x) tval = true_df(x) dm = 7 print(i, name, method, dm, np.abs(val - tval))
def test_high_order_derivative(): x = 0.5 min_dm = dict(complex=2, forward=2, backward=2, central=4) methods = [ 'complex', 'central', 'backward', 'forward'] for i, derivative in enumerate([nd.Derivative, nda.Derivative]): for name in function_names: if i>0 and name in ['arcsinh', 'exp2']: continue for n in range(2, 11): f, true_df = get_function(name, n=n) if true_df is None: continue for method in methods[3*i:]: if i==0 and n > 7 and method not in ['complex']: continue df = derivative(f, method=method, n=n, full_output=True) val, info = df(x) dm = max(int(-np.log10(info.error_estimate + 1e-16))-1, min_dm.get(method, 4)) print(i, name, method, n, dm) tval = true_df(x) assert_array_almost_equal(val, tval, decimal=dm)
def run_all_benchmarks(method='forward', order=4, x_values=(0.1, 0.5, 1.0, 5), n_max=11, show_plot=True): epsilon = MinStepGenerator(num_steps=3, scale=None, step_nom=None) scales = {} for n in range(1, n_max): plt.figure(n) scale_n = scales.setdefault(n, []) # for (name, x) in itertools.product( function_names, x_values): for name in function_names: fun0, dfun = get_function(name, n) if dfun is None: continue fd = Derivative(fun0, step=epsilon, method=method, n=n, order=order) for x in x_values: r = benchmark(x=x, dfun=dfun, fd=fd, name=name, scales=None, show_plot=show_plot) print(r) scale = r['scale'] if np.isfinite(scale): scale_n.append(scale) plt.vlines(np.mean(scale_n), 1e-12, 1, 'r', linewidth=3) plt.vlines(np.median(scale_n), 1e-12, 1, 'b', linewidth=3) _print_summary(method, order, x_values, scales)
def _example3(x=0.0001, fun_name='cos', epsilon=None, method='central', scale=None, n=1, order=2): fun0, dfun = get_function(fun_name, n) if dfun is None: return dict(n=n, order=order, method=method, fun=fun_name, error=np.nan, scale=np.nan) fd = Derivative(fun0, step=epsilon, method=method, n=n, order=order) t = [] scales = np.arange(1.0, 35, 0.25) for scale in scales: fd.step.scale = scale try: val = fd(x) except Exception: val = np.nan t.append(val) t = np.array(t) tt = dfun(x) relativ_error = np.abs(t - tt) / (np.maximum(np.abs(tt), 1)) + 1e-16 # weights = np.ones((3,))/3 # relativ_error = convolve1d(relativ_error, weights) # smooth curve if np.isnan(relativ_error).all(): return dict(n=n, order=order, method=method, fun=fun_name, error=np.nan, scale=np.nan) if True: # False: # plt.semilogy(scales, relativ_error, label=fun_name) plt.vlines(default_scale(fd.method, n, order), np.nanmin(relativ_error), 1) plt.xlabel('scales') plt.ylabel('Relative error') txt = ['', "1'st", "2'nd", "3'rd", "4'th", "5'th", "6'th", "7th" ] + ["%d'th" % i for i in range(8, 25)] plt.title("The %s derivative using %s, order=%d" % (txt[n], method, order)) plt.legend(frameon=False, framealpha=0.5) plt.axis([min(scales), max(scales), np.nanmin(relativ_error), 1]) # plt.figure() # plt.show('hold') i = np.nanargmin(relativ_error) return dict(n=n, order=order, method=method, fun=fun_name, error=relativ_error[i], scale=scales[i])