def test_pade_complex(): # Test sequence with known solutions - see page 6 of 10.1109/PESGM.2012.6344759. # Variable x is parameter - these tests will work with any complex number. x = 0.2 + 0.6j an = [ 1.0, x, -x * x.conjugate(), x.conjugate() * (x**2) + x * (x.conjugate()**2), -(x**3) * x.conjugate() - 3 * (x * x.conjugate())**2 - x * (x.conjugate()**3) ] nump, denomp = pade(an, 1, 1) assert_array_almost_equal(nump.c, [x + x.conjugate(), 1.0]) assert_array_almost_equal(denomp.c, [x.conjugate(), 1.0]) nump, denomp = pade(an, 1, 2) assert_array_almost_equal(nump.c, [x**2, 2 * x + x.conjugate(), 1.0]) assert_array_almost_equal(denomp.c, [x + x.conjugate(), 1.0]) nump, denomp = pade(an, 2, 2) assert_array_almost_equal(nump.c, [ x**2 + x * x.conjugate() + x.conjugate()**2, 2 * (x + x.conjugate()), 1.0 ]) assert_array_almost_equal(denomp.c, [x.conjugate()**2, x + 2 * x.conjugate(), 1.0])
def test_pade_trivial(): nump, denomp = pade([1.0], 0) assert_array_equal(nump.c, [1.0]) assert_array_equal(denomp.c, [1.0]) nump, denomp = pade([1.0], 0, 0) assert_array_equal(nump.c, [1.0]) assert_array_equal(denomp.c, [1.0])
def test_pade_ints(): # Simple test sequences (one of ints, one of floats). an_int = [1, 2, 3, 4] an_flt = [1.0, 2.0, 3.0, 4.0] # Make sure integer arrays give the same result as float arrays with same values. for i in range(0, len(an_int)): for j in range(0, len(an_int) - i): # Create float and int pade approximation for given order. nump_int, denomp_int = pade(an_int, i, j) nump_flt, denomp_flt = pade(an_flt, i, j) # Check that they are the same. assert_array_equal(nump_int.c, nump_flt.c) assert_array_equal(denomp_int.c, denomp_flt.c)
def se_pade(m, n, s, ell): order = m + n #power p = np.arange(order + 1) #intermediate variable c = np.power((-np.square(ell) / 2), p) / factorial(p) #simo's implementation of pade seems different to the scipy one #it seems that simo take account negativity of c in his pade_approx.m #I dont know which is one correct pade_res = pade(c, n, m) a = pade_res[0].coefficients b = pade_res[1].coefficients A = np.zeros(2 * a.shape[0] - 1) B = np.zeros(2 * b.shape[0] - 1) A[::2] = a B[::2] = b A = A * np.square(s) * np.sqrt(2 * np.pi) * ell return np.poly1d(A), np.poly1d(B)
def _pade_delay(p, q, c): """Numerically evaluated state-space using Pade approximants. This may have numerical issues for large values of p or q. """ i = np.arange(1, p + q + 1, dtype=np.float64) taylor = np.append([1.0], (-c)**i / factorial(i)) num, den = pade(taylor, q) return LinearSystem((num, den), analog=True)
def fit(zs,us,m=10,n=10): """Fit to a Pade approximant""" us = 1./us e_exp = np.polyfit(zs,us,(m+n)*2) p, q = pade(np.flip(e_exp), m,n) # e_exp = np.flip(e_exp) print(e_exp) e_poly = np.poly1d(e_exp) def f(z): return 1/(p(z)/q(z)) return f
def test_pade_4term_exp(): # First four Taylor coefficients of exp(x). # Unlike poly1d, the first array element is the zero-order term. an = [1.0, 1.0, 0.5, 1.0 / 6] nump, denomp = pade(an, 0) assert_array_almost_equal(nump.c, [1.0 / 6, 0.5, 1.0, 1.0]) assert_array_almost_equal(denomp.c, [1.0]) nump, denomp = pade(an, 1) assert_array_almost_equal(nump.c, [1.0 / 6, 2.0 / 3, 1.0]) assert_array_almost_equal(denomp.c, [-1.0 / 3, 1.0]) nump, denomp = pade(an, 2) assert_array_almost_equal(nump.c, [1.0 / 3, 1.0]) assert_array_almost_equal(denomp.c, [1.0 / 6, -2.0 / 3, 1.0]) nump, denomp = pade(an, 3) assert_array_almost_equal(nump.c, [1.0]) assert_array_almost_equal(denomp.c, [-1.0 / 6, 0.5, -1.0, 1.0])
def test_pade_4term_exp(): # First four Taylor coefficients of exp(x). # Unlike poly1d, the first array element is the zero-order term. an = [1.0, 1.0, 0.5, 1.0/6] nump, denomp = pade(an, 0) assert_array_almost_equal(nump.c, [1.0/6, 0.5, 1.0, 1.0]) assert_array_almost_equal(denomp.c, [1.0]) nump, denomp = pade(an, 1) assert_array_almost_equal(nump.c, [1.0/6, 2.0/3, 1.0]) assert_array_almost_equal(denomp.c, [-1.0/3, 1.0]) nump, denomp = pade(an, 2) assert_array_almost_equal(nump.c, [1.0/3, 1.0]) assert_array_almost_equal(denomp.c, [1.0/6, -2.0/3, 1.0]) nump, denomp = pade(an, 3) assert_array_almost_equal(nump.c, [1.0]) assert_array_almost_equal(denomp.c, [-1.0/6, 0.5, -1.0, 1.0])
def pade_vector_rational_function(taylor_polynomial, pade_power, **kwargs): taylor_polynomial = VectorPolynomial( taylor_polynomial) # shape = (N, taylor_order) pp = list() qq = list() for ii in range(taylor_polynomial.N): pii, qii = pade(taylor_polynomial.coeffs[ii, :], pade_power, **kwargs) pp.append(pii.coeffs[::-1]) qq.append(qii.coeffs[::-1]) numerator = VectorPolynomial(np.array(pp)) denominator = VectorPolynomial(np.array(qq)) return numerator / denominator
def exp_coeff(Y, L, nu, n_stop): """ Computes the coefficient for the exponential approximation of the convolution coefficients. """ print "*** Starting Pade approximation" # defining the formal serie # with the real part of the coefficients f = [[Y[i,n].real for n in range(nu, n_stop)] for i in range(8)] # matrix to store q_{i,l} and b_{i,l} q = np.zeros((8, L), dtype=complex) b = np.zeros((8, L), dtype=complex) for i in range(8): P, Q = pade(f[i], L) assert(P.o == L-1 and Q.o == L) root = Q.roots for l in range(L): q[i,l] = root[l] # assert(abs(q[i,l]) > 1) b[i,l] = -(P(q[i,l])/Q.deriv()(q[i,l]))*(q[i,l]**(nu-1)) print " * max(b) = {}, max(q) = {}".format(np.amax(abs(b)), np.amax(abs(q))) print "*** Pade approximation --> done\n" print "*** Checking Pade approximation" Y_appr = np.zeros((8, n_stop), dtype=complex) for i in range(8): for n in range(nu): Y_appr[i,n] = Y[i,n] for n in range(nu, n_stop): Y_appr[i,n] = np.sum([b[i,l]*(q[i,l]**(-n)) for l in range(L)]) # testing the approximation test = True for i in range(8): error = np.linalg.norm(abs(Y[i,:] - Y_appr[i,:])) print " * i = {} --> |Y-Y_appr| = {}".format(i, error) if error > 10**(-3): test = False assert(test == True) print "*** Pade approximation --> checked\n" return q, b
def pade_propagator_coefs_m(*, pade_order, diff2, k0, dx, spe=False, alpha=0): if spe: def sqrt_1plus(x): return 1 + x / 2 elif alpha == 0: def sqrt_1plus(x): return np.sqrt(1 + x) else: raise Exception('alpha not supported') def propagator_func(s): return np.exp(1j * k0 * dx * (sqrt_1plus(diff2(s)) - 1)) taylor_coefs = approximate_taylor_polynomial( propagator_func, 0, pade_order[0] + pade_order[1] + 5, 0.01) p, q = pade(taylor_coefs, pade_order[0], pade_order[1]) pade_coefs = list( zip_longest([-1 / complex(v) for v in np.roots(p)], [-1 / complex(v) for v in np.roots(q)], fillvalue=0.0j)) return pade_coefs
def se_pade(m, n, s, ell): order = m + n #power p = np.arange(order, -1, -1) #intermediate variable c = np.power((np.square(ell) / 2), p) / factorial(p) pade_res = pade(c, m, n) b = pade_res[0].coefficients a = pade_res[1].coefficients A = np.zeros(2 * a.shape[0] - 1) B = np.zeros(2 * b.shape[0] - 1) A[::2] = a B[::2] = b B = B * np.square(s) * np.sqrt(np.pi) * ell return A, B
y = asymptote_nan(f(x), x, x0list=[0]) fig = plt.figure(figsize=(8, 6)) ax = fig.add_subplot(1, 1, 1) #ax.plot(x,y) ax.set_ylim(-4, 4) ax.grid('on') # ax.plot(x,tay(x),markersize=8) # ax.plot(x,np.sin(x),markersize=8) x0 = 1.0 #1.0 T10poly = scipy.interpolate.approximate_taylor_polynomial(f, x=x0, degree=10, scale=0.05) P5poly, Q5poly = pade(T10poly.coeffs[::-1], 5) T10 = lambda x: T10poly(x - x0) R5_5 = lambda x: P5poly(x - x0) / Q5poly(x - x0) print(T10poly) print("P5 poly {}".format(P5poly)) print(Q5poly) #fig = plt.figure(figsize=(8,6)) #ax = fig.add_subplot(1,1,1) ax.plot(x, y, label='f(x)') ax.plot(x0, f(x0), '.k', markersize=8) yR5 = R5_5(x) # use real roots of Q5(x-x0) for finding asymptotes yR5 = asymptote_nan( yR5, x, [r + x0 for r in np.roots(Q5poly) if np.abs(np.imag(r)) < 1e-8]) ax.plot(x, T10(x), label='T10(x)')
def test_pade_4term_exp(): # First four Taylor coefficients of exp(x). # Unlike poly1d, the first array element is the zero-order term. an = [1.0, 1.0, 0.5, 1.0 / 6] nump, denomp = pade(an, 0) assert_array_almost_equal(nump.c, [1.0 / 6, 0.5, 1.0, 1.0]) assert_array_almost_equal(denomp.c, [1.0]) nump, denomp = pade(an, 1) assert_array_almost_equal(nump.c, [1.0 / 6, 2.0 / 3, 1.0]) assert_array_almost_equal(denomp.c, [-1.0 / 3, 1.0]) nump, denomp = pade(an, 2) assert_array_almost_equal(nump.c, [1.0 / 3, 1.0]) assert_array_almost_equal(denomp.c, [1.0 / 6, -2.0 / 3, 1.0]) nump, denomp = pade(an, 3) assert_array_almost_equal(nump.c, [1.0]) assert_array_almost_equal(denomp.c, [-1.0 / 6, 0.5, -1.0, 1.0]) # Testing inclusion of optional parameter nump, denomp = pade(an, 0, 3) assert_array_almost_equal(nump.c, [1.0 / 6, 0.5, 1.0, 1.0]) assert_array_almost_equal(denomp.c, [1.0]) nump, denomp = pade(an, 1, 2) assert_array_almost_equal(nump.c, [1.0 / 6, 2.0 / 3, 1.0]) assert_array_almost_equal(denomp.c, [-1.0 / 3, 1.0]) nump, denomp = pade(an, 2, 1) assert_array_almost_equal(nump.c, [1.0 / 3, 1.0]) assert_array_almost_equal(denomp.c, [1.0 / 6, -2.0 / 3, 1.0]) nump, denomp = pade(an, 3, 0) assert_array_almost_equal(nump.c, [1.0]) assert_array_almost_equal(denomp.c, [-1.0 / 6, 0.5, -1.0, 1.0]) # Testing reducing array. nump, denomp = pade(an, 0, 2) assert_array_almost_equal(nump.c, [0.5, 1.0, 1.0]) assert_array_almost_equal(denomp.c, [1.0]) nump, denomp = pade(an, 1, 1) assert_array_almost_equal(nump.c, [1.0 / 2, 1.0]) assert_array_almost_equal(denomp.c, [-1.0 / 2, 1.0]) nump, denomp = pade(an, 2, 0) assert_array_almost_equal(nump.c, [1.0]) assert_array_almost_equal(denomp.c, [1.0 / 2, -1.0, 1.0])
def test_pade_trivial(): nump, denomp = pade([1.0], 0) assert_array_equal(nump.c, [1.0]) assert_array_equal(denomp.c, [1.0])