Exemplo n.º 1
0
def inverse_pade(f, x0, m, n):
    """
    Padé approximant coefficients of the inverse of f.

    Given a callable f, and a point x0, find the Padé approximant of degree
    (m, n) of the inverse of f at x0.

    If y0 = f(x0), and if the inverse of f is g, this function returns
    the Padé approximant coefficients of g(y) at y0.

    f'(x0) must be nonzero.

    Examples
    --------
    >>> import mpmath
    >>> mpmath.mp.dps = 40

    Compute the Padé approximant to the inverse of sin(x) at x=1.

    >>> inverse_pade(mpmath.sin, 1, 5, 4)
    ([mpf('1.0'),
      mpf('-5.428836087225345782152614868037223199487785'),
      mpf('-14.59025586448337482707922792297134121701713'),
      mpf('76.66727054306441691994858675947043862200347'),
      mpf('20.92630843471146736348587129663693571301545'),
      mpf('-91.95538065543221755259217919809770565490541')],
     [mpf('1.0'),
      mpf('-7.279651804906271400064368109435873392958164'),
      mpf('-3.784426620962357975179374311522526358975659'),
      mpf('94.34419434777145262733458338059694153109452'),
      mpf('-114.4848137234397209897780633142520390436954')])

    Compare that to computing the Padé approximant of the arcsine
    function directly.

    >>> c = mpmath.taylor(mpmath.asin, mpmath.sin(1), 10)
    >>> mpmath.pade(c, 5, 4)
    ([mpf('1.0'),
      mpf('-5.428836087225345782152614868037223199022362'),
      mpf('-14.59025586448337482707922792297134122127003'),
      mpf('76.66727054306441691994858675947043863057723'),
      mpf('20.92630843471146736348587129663693571903839'),
      mpf('-91.95538065543221755259217919809770566742443')],
     [mpf('1.0'),
      mpf('-7.279651804906271400064368109435873392492793'),
      mpf('-3.784426620962357975179374311522526364090111'),
      mpf('94.34419434777145262733458338059694154789217'),
      mpf('-114.4848137234397209897780633142520390591904')])

    """
    d = m + n + 1
    c = inverse_taylor(f, x0, d)
    pc, qc = mpmath.pade(c, m, n)
    return pc, qc
Exemplo n.º 2
0
def pade(t, n):
    """ pade approximation of a time delay, as per mathworks' controls toolkit.
    supports arbitrary precision mathematics via mpmath and sympy"
    for more information, see:
        * http://home.hit.no/~hansha/documents/control/theory/pade_approximation.pdf 
        * http://www.mathworks.com/help/control/ref/pade.html
    """
    # e**(s*t) -> laplace transform of a time delay with 't' duration
    # e**x -> taylor series
    taylor = mpmath.taylor(sympy.exp, 0, n * 2)
    (num, den) = mpmath.pade(taylor, n, n)
    num = sum([x * (-t * s)**y for y, x in enumerate(num[::-1])])
    den = sum([x * (-t * s)**y for y, x in enumerate(den[::-1])])
    return num / den
Exemplo n.º 3
0
def pade_coefs(*, pade_order, k0, dx, alpha=0):
    mpmath.mp.dps = 63

    if alpha == 0:

        def sqrt_1plus(x):
            return mpmath.mp.sqrt(1 + x)
    else:
        a_n, b_n = pade_sqrt_coefs(pade_order[1])

        def sqrt_1plus(x):
            return pade_sqrt(x, a_n, b_n, alpha)

    def propagator_func(s):
        return mpmath.mp.exp(1j * k0 * dx * (sqrt_1plus(s) - 1))

    t = mpmath.taylor(propagator_func, 0, pade_order[0] + pade_order[1] + 20)
    p, q = mpmath.pade(t, pade_order[0], pade_order[1])
    num_coefs = np.array([complex(v) for v in p])
    den_coefs = np.array([complex(v) for v in q])
    return num_coefs[::-1], den_coefs[::-1]
Exemplo n.º 4
0
    def __init__(self, n):
        self.n = n
        mpmath.mp.dps = 100

        def func(x):
            return mpmath.exp(-x) * mpmath.besseli(0, x)

        t = mpmath.taylor(func, 0, 2 * n + 1)
        self.p, self.q = mpmath.pade(t, n, n)
        # self.pade_coefs = list(zip_longest([-1 / complex(v) for v in mpmath.polyroots(p[::-1], maxsteps=2000)],
        #                               [-1 / complex(v) for v in mpmath.polyroots(q[::-1], maxsteps=2000)],
        #                               fillvalue=0.0j))
        #self.pade_roots_num = [complex(v) for v in mpmath.polyroots(self.p[::-1], maxsteps=5000)]
        #self.pade_roots_den = [complex(v) for v in mpmath.polyroots(self.q[::-1], maxsteps=5000)]
        self.pade_coefs_num = [complex(v) for v in self.p]
        self.pade_coefs_den = [complex(v) for v in self.q]
        self.taylor_coefs = [complex(v) for v in t]

        a = [self.q[-1]] + [b + c for b, c in zip(self.q[:-1:], self.p)]
        self.a_roots = [
            complex(v) for v in mpmath.polyroots(a[::-1], maxsteps=5000)
        ]
Exemplo n.º 5
0
def pade_propagator_coefs(*, pade_order, diff2, k0, dx, spe=False, alpha=0):
    """

    :param pade_order: order of Pade approximation, tuple, for ex (7, 8)
    :param diff2:
    :param k0:
    :param dx:
    :param spe:
    :param alpha: rotation angle, see F. A. Milinazzo et. al. Rational square-root approximations for parabolic equation algorithms. 1997. Acoustical Society of America.
    :return:
    """

    mpmath.mp.dps = 63
    if spe:

        def sqrt_1plus(x):
            return 1 + x / 2
    elif alpha == 0:

        def sqrt_1plus(x):
            return mpmath.mp.sqrt(1 + x)
    else:
        a_n, b_n = pade_sqrt_coefs(pade_order[1])

        def sqrt_1plus(x):
            return pade_sqrt(x, a_n, b_n, alpha)

    def propagator_func(s):
        return mpmath.mp.exp(1j * k0 * dx * (sqrt_1plus(diff2(s)) - 1))

    t = mpmath.taylor(propagator_func, 0, pade_order[0] + pade_order[1] + 2)
    p, q = mpmath.pade(t, pade_order[0], pade_order[1])
    pade_coefs = list(
        zip_longest([
            -1 / complex(v) for v in mpmath.polyroots(p[::-1], maxsteps=2000)
        ], [-1 / complex(v) for v in mpmath.polyroots(q[::-1], maxsteps=2000)],
                    fillvalue=0.0j))
    return pade_coefs
Exemplo n.º 6
0
def lambertw_pade():
    derivs = [mpmath.diff(mpmath.lambertw, 0, n=n) for n in range(6)]
    p, q = mpmath.pade(derivs, 3, 2)
    return p, q
Exemplo n.º 7
0
def lambertw_pade():
    derivs = []
    for n in range(6):
        derivs.append(mpmath.diff(mpmath.lambertw, 0, n=n))
    p, q = mpmath.pade(derivs, 3, 2)
    return p, q
Exemplo n.º 8
0
def lambertw_pade():
    derivs = []
    for n in range(6):
        derivs.append(mpmath.diff(mpmath.lambertw, 0, n=n))
    p, q = mpmath.pade(derivs, 3, 2)
    return p, q
Exemplo n.º 9
0
def lambertw_pade():
    derivs = [mpmath.diff(mpmath.lambertw, 0, n=n) for n in range(6)]
    p, q = mpmath.pade(derivs, 3, 2)
    return p, q
Exemplo n.º 10
0
import mpmath


def f(x):
    return (mpmath.pi + x + mpmath.sin(x)) / (2*mpmath.pi)


# Note: 40 digits might be overkill; a few more digits than the default
# might be sufficient.
mpmath.mp.dps = 40
ts = mpmath.taylor(f, -mpmath.pi, 20)
p, q = mpmath.pade(ts, 9, 10)

p = [float(c) for c in p]
q = [float(c) for c in q]
print('p =', p)
print('q =', q)