from demos.setup import np, plt, demo
from numpy.linalg import norm, cond
from compecon import BasisChebyshev
import warnings
%matplotlib inline
warnings.simplefilter('ignore')
runge = lambda x: 1 / (1 + 25 * x ** 2)
Set points of approximation interval
a, b = -1, 1
Construct plotting grid
nplot = 1001
x = np.linspace(a, b, nplot)
y = runge(x)
Plot Runge's Function
Initialize data matrices
n = np.arange(3, 33, 2)
nn = n.size
errunif, errcheb = (np.zeros([nn, nplot]) for k in range(2))
nrmunif, nrmcheb, conunif, concheb = (np.zeros(nn) for k in range(4))
Compute approximation errors on refined grid and interpolation matrix condition numbers
for i in range(nn):
# Uniform-node monomial-basis approximant
xnodes = np.linspace(a, b, n[i])
c = np.polyfit(xnodes, runge(xnodes), n[i])
yfit = np.polyval(c, x)
phi = xnodes.reshape(-1, 1) ** np.arange(n[i])
errunif[i] = yfit - y
nrmunif[i] = np.log10(norm(yfit - y, np.inf))
conunif[i] = np.log10(cond(phi, 2))
for i in range(nn):
# Uniform-node monomial-basis approximant
xnodes = np.linspace(a, b, n[i])
c = np.polyfit(xnodes, runge(xnodes), n[i])
yfit = np.polyval(c, x)
phi = xnodes.reshape(-1, 1) ** np.arange(n[i])
errunif[i] = yfit - y
nrmunif[i] = np.log10(norm(yfit - y, np.inf))
conunif[i] = np.log10(cond(phi, 2))
# Chebychev-node Chebychev-basis approximant
yapprox = BasisChebyshev(n[i], a, b, f=runge)
yfit = yapprox(x) # [0] no longer needed? # index zero is to eliminate one dimension
phi = yapprox.Phi()
errcheb[i] = yfit - y
nrmcheb[i] = np.log10(norm(yfit - y, np.inf))
concheb[i] = np.log10(cond(phi, 2))
Plot Chebychev- and uniform node polynomial approximation errors
plt.figure(figsize=[8, 12])
demo.subplot(2,1,1, "Runge's Function", '', 'y')
plt.plot(x, y)
plt.text(-0.8, 0.8, r'$y = \frac{1}{1+25x^2}$', fontsize=18)
plt.xticks=[]
demo.subplot(2,1,2, "Runge's Function $11^{th}$-Degree\nPolynomial Approximation Error.",
'x', 'Error')
plt.hlines(0, a, b, 'gray', '--')
plt.plot(x, errcheb[4], label='Chebychev Nodes')
plt.plot(x, errunif[4], label='Uniform Nodes')
plt.legend(loc='upper center')
Plot approximation error per degree of approximation
plt.figure(figsize=[8, 12])
demo.subplot(2,1,1, "Log10 Polynomial Approximation Error for Runge's Function",
'', 'Log10 Error')
plt.plot(n, nrmcheb, label='Chebychev Nodes')
plt.plot(n, nrmunif, label='Uniform Nodes')
plt.legend(loc='upper left')
plt.xticks=[]
demo.subplot(2,1,2, "Log10 Interpolation Matrix Condition Number",
'Degree of Approximating Polynomial', 'Log10 Condition Number')
plt.plot(n, concheb, label='Chebychev Polynomial Basis')
plt.plot(n, conunif, label='Mononomial Basis')
plt.legend(loc='upper left')