コード例 #1
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)
コード例 #2
0
ファイル: precision.py プロジェクト: HDembinski/jacobi
import numpy as np
from jacobi import jacobi
from numdifftools import Derivative


# function of one variable with auxiliary argument; returns a vector
def f(p, x):
    y = p + x
    return np.sin(y) / y


def fp(x):
    return np.cos(x) / x - np.sin(x) / x**2


x = np.linspace(-10, 10, 1000)
fpx = fp(x)
fpx1, fpxe1 = jacobi(f, 0, x)
fpx2 = Derivative(lambda p: f(p, x))(0)

plt.figure(constrained_layout=True)
plt.plot(x, np.abs(fpx1 / fpx - 1), ls="-", label="Jacobi")
plt.plot(x, np.abs(fpx2 / fpx - 1), ls="--", label="numdifftools")
plt.title("relative deviation of numerical from true derivative")
plt.legend(title="f(x) = sin(x)/x", ncol=2)
plt.semilogy()
plt.ylim(1e-16, 1e-11)
plt.axhline(np.finfo(float).resolution, color="k", ls="--")

plt.savefig("doc/_static/precision.svg")
コード例 #3
0
        iters += 1
    return incumbent, iters, acc, step


def show_results(func, incumbent, iters, acc, step, time):
    print("min f:     ", func)
    print("at x =     ", incumbent)
    print("iters:     ", iters)
    print("acc:       ", acc)
    print("step:      ", step)
    print("time (ms): ", time, "\n")


f = lambda x: 2 * x**2 - 0.5
start_time = time.time() * 1000
incumbent, iters, acc, step = backtrack(dfx=Derivative(f), x0=3., step=1e-3)
end_time = time.time() * 1000
show_results(f(incumbent),
             incumbent,
             iters,
             acc,
             step,
             time=end_time - start_time)

f = lambda x: 2 * x**4 - 4 * x**2 + x - 0.5
x0s = [-2., -0.5, 0.5, 2.]
for x0 in x0s:
    start_time = time.time() * 1000
    incumbent, iters, acc, step = backtrack(dfx=Derivative(f),
                                            x0=x0,
                                            step=1e-3)
コード例 #4
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])
コード例 #5
0
ファイル: speed.py プロジェクト: HDembinski/jacobi
for i, fi in enumerate(fn):
    t = {}
    t["jacobi"] = []
    t["numdifftools"] = []
    nmax = 5
    n = (10**np.linspace(0, nmax, nmax + 1)).astype(int)
    f = eval("lambda x: " + fi, np.__dict__)
    for ni in n:
        print(i, ni)
        x = np.linspace(0.1, 10, ni)
        number = 500 // ni + 10
        r = timeit(lambda: jacobi(lambda p: f(p + x), 0),
                   number=number) / number
        t["jacobi"].append(r)
        number = 500 // ni + 1
        r = timeit(lambda: Derivative(lambda p: f(p + x))
                   (0), number=number) / number
        t["numdifftools"].append(r)
    plt.sca(ax.flat[i])
    for k, v in t.items():
        ls = "-" if "jacobi" in k else "--"
        plt.plot(n, v, ls=ls, label=k)
    r = np.divide(t["numdifftools"], t["jacobi"])
    plt.plot(n, r, ls=":", color="k", lw=3, label="time ratio")
    for ni, ri in zip(n, r):
        plt.text(ni,
                 ri * 0.5,
                 f"{ri:.0f}" if i != 3 else f"{ri:.1f}",
                 va="top",
                 ha="center")
    plt.legend(loc="upper left", frameon=False)
    plt.title(fi)
コード例 #6
0
 def _Rdd(self, theta):
     """2nd derivative of the surface equation in spherical coordinates:
           r=r\'\'(theta)"""
     return Derivative(self._R, derOrder=2)(theta)
コード例 #7
0
 def _Rd(self, theta):
     """1st derivative of the surface equation in spherical coordinates:
           r=r\'(theta)"""
     return Derivative(self._R)(theta)
コード例 #8
0
def test_taylor_horner_deriv(x, coeffs, order):
    def f(x):
        return taylor_horner(x, coeffs)

    df = Derivative(f, n=order)
    assert_allclose(df(x), taylor_horner_deriv(x, coeffs, order), atol=1e-11)