In [1]:
%pylab inline

from sympy.utilities.lambdify import lambdify
from sympy import init_session
init_session()

from numpy import arange, abs

from pandas import DataFrame

from pylab import plot


Populating the interactive namespace from numpy and matplotlib
IPython console for SymPy 0.7.3 (Python 3.3.2-64-bit) (ground types: python)

These commands were executed:
>>> from __future__ import division
>>> from sympy import *
>>> x, y, z, t = symbols('x y z t')
>>> k, m, n = symbols('k m n', integer=True)
>>> f, g, h = symbols('f g h', cls=Function)

Documentation can be found at http://www.sympy.org

In [2]:
p1 = (1/2)*((x + sqrt(x**2 - 1))**m + (x - sqrt(x**2 - 1))**m)
p2 = cos(m*acos(x))
Eq(p1, p2)


Out[2]:
$$0.5 \left(x - \sqrt{x^{2} - 1}\right)^{m} + 0.5 \left(x + \sqrt{x^{2} - 1}\right)^{m} = \cos{\left (m \operatorname{acos}{\left (x \right )} \right )}$$

In [3]:
result = []
powers = range(1,10)
points = arange(-2, 2, 0.25)
def cleverLog(x): 
    if x == 0: return '-∞'
    else: return log(x)
for xv in points:
    poly1 = p1.subs(x, xv)
    poly2 = p2.subs(x, xv)
    result.append([cleverLog(abs(N(poly1.subs(m, mv) - poly2.subs(m, mv), 3))) for mv in powers])
DataFrame(data=result, index=points, columns=powers)


Out[3]:
1 2 3 4 5 6 7 8 9
-2.00 -36.1 -33.9 -31.5 -30.4 -29.0 -27.0 -26.1 -24.4 -22.7
-1.75 -35.8 -34.1 -32.8 -31.0 -29.5 -28.6 -26.7 -25.8 -24.7
-1.50 -36.5 -34.6 -33.0 -32.1 -30.9 -29.6 -28.5 -27.5 -26.2
-1.25 -36.9 -35.3 -34.0 -33.2 -32.3 -31.2 -30.5 -29.7 -28.9
-1.00 -∞ -∞ -∞ -∞ -∞ -∞ -∞ -∞ -∞
-0.75 -∞ -37.0 -35.3 -39.5 -37.8 -34.5 -34.5 -38.8 -35.1
-0.50 -36.0 -35.7 -36.6 -34.8 -34.1 -35.9 -35.1 -34.4 -35.5
-0.25 -36.7 -36.3 -36.3 -35.4 -35.7 -35.0 -36.0 -34.9 -34.2
0.00 -37.3 -∞ -36.2 -∞ -35.7 -∞ -35.4 -∞ -35.1
0.25 -∞ -37.3 -35.8 -36.9 -37.9 -35.5 -35.6 -37.5 -36.3
0.50 -36.7 -35.7 -36.6 -35.5 -34.4 -35.9 -35.8 -34.4 -35.5
0.75 -∞ -36.4 -36.1 -36.8 -37.2 -35.4 -36.4 -35.3 -37.0
1.00 -∞ -∞ -∞ -∞ -∞ -∞ -∞ -∞ -∞
1.25 -∞ -∞ -34.7 -∞ -∞ -31.9 -31.9 -31.2 -∞
1.50 -∞ -35.4 -33.3 -∞ -32.6 -30.1 -29.4 -29.1 -26.6
1.75 -36.0 -34.7 -∞ -31.5 -29.8 -∞ -26.9 -26.3 -∞

In [4]:
def drawChebyshev():
    xs = pylab.linspace(-1, 1, 1000)
    for i in range(3,10,2):
        cheb = lambdify(x, p2.subs(m, i), "numpy")
        plot(xs, cheb(xs))
        title(p2.subs(m, i))
        show()

drawChebyshev()



In [9]:
def interpolate(f, points):
    values = f(points)
    M = pylab.ma.vander(points)
    invM = pylab.linalg.inv(M)
    a = dot(invM, values)
    return Poly(a, x).as_expr()

def absOmega(points):
    pcopy = points
    return pylab.vectorize(lambda x: abs(pylab.prod([x - p for p in pcopy])))

def chebspace(start, end, n):
    cos = pylab.cos
    pi = pylab.pi
    return [(start+end)/2 + ((end-start)/2)*cos(pi*(2*k+1)/(2*n)) for k in range(0,n)]

def maximum(f, start, end):
    from scipy.optimize import minimize_scalar
    return f(minimize_scalar(lambda x: -f(x), bounds=(start, end), method='bounded').x)

fun = lambdify(x, tanh(x), 'numpy')
dfun = lambdify(x, tanh(x).diff(x), 'numpy')
Ifun = lambdify(x, log(cosh(x)), 'numpy')

In [6]:
def graphics():
    n = 20
    
    points = pylab.linspace(-2, 2, n)
    chebPoints = chebspace(-2, 2, n)
    L1 = interpolate(fun, points)
    L1_f = lambdify(x, L1, 'numpy')
    L2 = interpolate(fun, chebPoints)
    L2_f = lambdify(x, L2, 'numpy')
    
    dL1_f = lambdify(x, L1.diff(x), 'numpy')
    dL2_f = lambdify(x, L2.diff(x), 'numpy')
    
    IL1_f = lambdify(x, L1.integrate(x), 'numpy')
    IL2_f = lambdify(x, L2.integrate(x), 'numpy')
    
    t = pylab.linspace(-2, 2, 1000)
    
    plot(t, fun(t))
    title(r'$\tanh(x)$')
    show()
    
    plot(t, L1_f(t))
    title(r'$L_1(x)$')
    show()
    
    plot(t, L2_f(t))
    title(r'$L_2(x)$')
    show()
    
    plot(t, pylab.vectorize(lambda x: abs(fun(x) - L1_f(x)))(t))
    title(r'$|\Delta_1|$')
    show()
    
    plot(t, pylab.vectorize(lambda x: abs(fun(x) - L2_f(x)))(t))
    title(r'$|\Delta_2|$')
    show()
    
    plot(t, dfun(t))
    title(r"$\tanh'(x)$")
    show()
    
    plot(t, dL1_f(t))
    title(r'$dL_1$')
    show()
    
    plot(t, dL2_f(t))
    title(r'$dL_2$')
    show()
    
    plot(t, pylab.vectorize(lambda x: abs(dfun(x) - dL1_f(x)))(t))
    title(r'$|d\Delta_1|$')
    show()
    
    plot(t, pylab.vectorize(lambda x: abs(dfun(x) - dL2_f(x)))(t))
    title(r'$|d\Delta_2|$')
    show()
    
    plot(t, Ifun(t))
    title(r"$∫\tanh(x)$")
    show()
    
    plot(t, IL1_f(t))
    title(r'$∫L_1$')
    show()
    
    plot(t, IL2_f(t))
    title(r'$∫L_2$')
    show()
    
    plot(t, pylab.vectorize(lambda x: abs(Ifun(x) - IL1_f(x)))(t))
    title(r'$|∫\Delta_1|$')
    show()
    
    plot(t, pylab.vectorize(lambda x: abs(Ifun(x) - IL2_f(x)))(t))
    title(r'$|∫\Delta_2|$')
    show()
    
graphics()



In [7]:
def errors(L, start, end):
    L_f = lambdify(x, L, 'numpy')
    err = maximum(lambda x: abs(fun(x) - L_f(x)), start, end)
    
    dL = lambdify(x, diff(L, x), 'numpy')
    errd = maximum(lambda x: abs(dfun(x) - dL(x)), start, end)
    
    IL = lambdify(x, integrate(L, x), 'numpy')
    errI = maximum(lambda x: abs(Ifun(x) - IL(x)), start, end)
    
    return (err, errd, errI)

def approximate(n, start, end):
    unifiedPoints = pylab.linspace(start, end, n)
    chebyshevPoints = chebspace(start, end, n)
    
    L1 = interpolate(fun, unifiedPoints)
    Ω1 = absOmega(unifiedPoints)
    err1, errd1, errI1 = errors(L1, start, end)
    
    L2 = interpolate(fun, chebyshevPoints)
    Ω2 = absOmega(chebyshevPoints)
    err2, errd2, errI2 = errors(L2, start, end)
    
    teorRel = maximum(Ω2, start, end)/maximum(Ω1, start, end)
    rel = abs(err2/err1)
    
    return (err1, err2, errd1, errd2, errI1, errI2, teorRel, rel)

In [10]:
results = []
for n in range(5,51,5):
    results.append(approximate(n, -2, 2))
    
DataFrame(results, index=range(5,51,5), columns=('Δ1','Δ2', 'dΔ1', 'dΔ2', '∫Δ1', '∫Δ2', '|Ω2|/|Ω1|', 'Δ2/Δ1'))


Out[10]:
Δ1 Δ2 dΔ1 dΔ2 ∫Δ1 ∫Δ2 |Ω2|/|Ω1| Δ2/Δ1
5 0.046375 6.100162e-02 0.157950 0.142640 0.029685 4.520015e-02 1.409745 1.315392
10 0.009435 9.015862e-04 0.006591 0.006651 0.002098 2.113101e-04 6.185908 0.095554
15 0.000013 3.637260e-05 0.001177 0.000383 0.000024 1.323782e-05 6.240735 2.711021
20 0.000028 6.887169e-07 0.003695 0.000008 0.000003 6.430116e-08 0.085092 0.024583
25 0.000075 2.568681e-08 0.000876 0.000000 0.000006 4.586019e-09 0.000996 0.000341
30 0.000009 7.069596e-07 0.000068 0.000007 0.000002 2.955602e-11 0.003820 0.077082
35 0.000196 2.695300e-11 0.003702 0.000537 0.000028 2.963574e-12 0.000027 0.000000
40 2.897544 1.723268e-03 38.922051 0.002179 0.202777 7.770916e-05 0.000004 0.000595
45 851.245321 2.928571e-01 17504.749642 4.407052 40.861886 1.129222e-02 0.000001 0.000344
50 164778.384058 5.337629e-01 3369125.076461 3.883600 7179.272673 7.628976e-02 0.000000 0.000003