12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667 |
- from numpy import zeros, asarray, eye, poly1d, hstack, r_
- from scipy import linalg
- __all__ = ["pade"]
- def pade(an, m, n=None):
- """
- Return Pade approximation to a polynomial as the ratio of two polynomials.
- Parameters
- ----------
- an : (N,) array_like
- Taylor series coefficients.
- m : int
- The order of the returned approximating polynomial `q`.
- n : int, optional
- The order of the returned approximating polynomial `p`. By default,
- the order is ``len(an)-1-m``.
- Returns
- -------
- p, q : Polynomial class
- The Pade approximation of the polynomial defined by `an` is
- ``p(x)/q(x)``.
- Examples
- --------
- >>> import numpy as np
- >>> from scipy.interpolate import pade
- >>> e_exp = [1.0, 1.0, 1.0/2.0, 1.0/6.0, 1.0/24.0, 1.0/120.0]
- >>> p, q = pade(e_exp, 2)
- >>> e_exp.reverse()
- >>> e_poly = np.poly1d(e_exp)
- Compare ``e_poly(x)`` and the Pade approximation ``p(x)/q(x)``
- >>> e_poly(1)
- 2.7166666666666668
- >>> p(1)/q(1)
- 2.7179487179487181
- """
- an = asarray(an)
- if n is None:
- n = len(an) - 1 - m
- if n < 0:
- raise ValueError("Order of q <m> must be smaller than len(an)-1.")
- if n < 0:
- raise ValueError("Order of p <n> must be greater than 0.")
- N = m + n
- if N > len(an)-1:
- raise ValueError("Order of q+p <m+n> must be smaller than len(an).")
- an = an[:N+1]
- Akj = eye(N+1, n+1, dtype=an.dtype)
- Bkj = zeros((N+1, m), dtype=an.dtype)
- for row in range(1, m+1):
- Bkj[row,:row] = -(an[:row])[::-1]
- for row in range(m+1, N+1):
- Bkj[row,:] = -(an[row-m:row])[::-1]
- C = hstack((Akj, Bkj))
- pq = linalg.solve(C, an)
- p = pq[:n+1]
- q = r_[1.0, pq[n+1:]]
- return poly1d(p[::-1]), poly1d(q[::-1])
|