コード例 #1
0
ファイル: test_fornberg.py プロジェクト: pbrod/numdifftools
    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)
コード例 #2
0
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)
コード例 #3
0
 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)
コード例 #4
0
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)))
コード例 #5
0
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)))
コード例 #6
0
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)))
コード例 #7
0
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)))
コード例 #8
0
 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)
コード例 #9
0
 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)
コード例 #10
0
    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)
コード例 #11
0
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))
コード例 #12
0
    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)
コード例 #13
0
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)
コード例 #14
0
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])