Fixed-Point Iteration
http://iailab.kaist.ac.kr/
Industrial AI Lab at KAIST
Source
- By Prof. David J. Malan from Harvard University
- By Prof. Erik Demaine from MIT online lecture
1. Fixed-Point Iteration¶
1.1. Numerical approach¶
For the given equation:
f(x)=0⟹x=g(x)
Remark: always achievable
x=f(x)+x=g(x)x=−f(x)+x=g(x)
Goal: numerically find the solution of x=g(x)
Main idea:
Make a guess of the solution, xk
If g(xk) is 'nice', then hopefully, g(xk) will be closer to the answer. If so, we can iterate
Iteration algorithm
- choose an initial point x0
- Do the iteration xk+1=g(xk) until meeting stopping criteria
Convergence check (or analysis)
Let r be the exact solution, r=g(r)
xk+1=g(xk)error:ek=xk−rek+1=xk+1−r=g(xk)−g(r)=g′(η)(xk−r)=g′(η)ek,η∈(xk,r)⟹|ek+1|≤|g′(η)||ek|
If |g′(η)|<1,error decreases (iteration converges)
1) Example of x=cos(x)
# Computational Thinking on how to calculate cos(x) = x
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
x = np.linspace(-2*np.pi, 2*np.pi, 100)
y = np.cos(x)
plt.figure(figsize = (8,6))
plt.plot(x, y, linewidth = 2)
plt.plot(x, x, linewidth = 2)
# plt.xlim(-2*np.pi, 2*np.pi)
plt.axvline(x=0, color = 'k', linestyle = '--')
plt.axhline(y=0, color = 'k', linestyle = '--')
plt.legend(['cos(x)','x'])
plt.axis('equal')
plt.ylim([-1,1])
plt.show()
# naive approach
x = 0.3
print (np.cos(x))
print (np.cos(np.cos(x)))
print (np.cos(np.cos(np.cos(x))))
print (np.cos(np.cos(np.cos(np.cos(x)))))
print (np.cos(np.cos(np.cos(np.cos(np.cos(x))))))
print (np.cos(np.cos(np.cos(np.cos(np.cos(np.cos(x)))))))
print (np.cos(np.cos(np.cos(np.cos(np.cos(np.cos(np.cos(x))))))))
# better way
x = 0.3
for i in range(24):
tmp = np.cos(x)
x = np.cos(tmp)
print (x)
# better way
x = np.zeros((24, 1))
x[0] = 0.3
for i in range(23):
x[i+1] = np.cos(x[i])
print (x)
# better way
x = 10
for i in range(24):
x = np.cos(x)
print (x)
2) example of √2(x2=2)
# Use an idea of a fixed point
x = 2
for i in range(10):
x = 2/x
print (x)
x = np.linspace(-3, 3, 100)
y = 2/x
plt.figure(figsize = (8,6))
plt.plot(x, y, linewidth = 2)
plt.plot(x, x, linewidth = 2)
plt.axvline(x=0, color = 'k', linestyle = '--')
plt.axhline(y=0, color = 'k', linestyle = '--')
plt.legend(['2/x','x'])
plt.axis('equal')
plt.ylim([-1,1])
plt.show()
# How to overcome
# Use an idea of a fixed point + kind of *|damping|*
x = 3
for i in range(10):
x = (x + 2/x)/2
print (x)
x = np.linspace(-4, 4, 100)
y = (x + 2/x)/2
plt.figure(figsize = (8,6))
plt.plot(x, y, linewidth = 2)
plt.plot(x, x, linewidth = 2)
plt.axvline(x=0, color = 'k', linestyle = '--')
plt.axhline(y=0, color = 'k', linestyle = '--')
plt.axis('equal')
plt.ylim([-1,1])
plt.show()
Think about why it gives different results.
import numpy as np
import matplotlib.pyplot as plt
# matrix inverse
A = np.array([[4, -1, 1], [4, -8, 1], [-2, 1, 5]])
b = np.array([[7, -21, 15]]).T
x = np.linalg.inv(A).dot(b)
print (x)
This solution only possible for small size problems. There are many iterative methods for large problems.
4x1−x2+x3=7x1=14x2−14x3+744x1−8x2+x3=−21⟹x2=12x1+18x3+218−2x1+x2+5x3=15x3=25x1−15x2+155
- In a matrix form
[x1x2x3]=[014−141201825−150][x1x2x3]+[742183]
- iteration
[x(k+1)1x(k+1)2x(k+1)3]=[014−141201825−150][x(k)1x(k)2x(k)3]+[742183]
# Iterative way
A = np.array(([[0, 1/4, -1/4 ],
[4/8, 0, 1/8],
[2/5, -1/5, 0]]))
b = np.array([[7/4, 21/8, 15/5]]).T
# initial point
x = np.array([[1, 1, 2]]).T
A = np.asmatrix(A)
b = np.asmatrix(b)
x = np.asmatrix(x)
for i in range(20):
x = A*x + b
print (x)
Remark) try this one
x1=−3x1+x2−x3+7x2=4x1−7x2+x3+21x3=2x1−x2+−4x3+15
[x1x2x3]←[−31−14−712−1−4][x1x2x3]+[72115]
Convergence check
x←Ax+b
xk+1=Axk+b=A(Axk−1+b)+b=A2Xk−1+Ab+b⋮=Ak+1x0+Akb+⋯+Ab+b
# think about why this one does not work
A = np.array(([[3, 1, -1 ],
[4, 7, 1],
[2, -1, -4]]))
b = np.array([[7, 21, 15]]).T
# initial point
x = np.array([[1, 2, 2]]).T
for i in range(10):
x = A.dot(x) + b
print (x)
# stability, check eigenvalue of A
A = np.array(([[3, 1, -1 ],
[4, 7, 1],
[2, -1, -4]]))
np.linalg.eig(A)
# stability, check eigenvalue of A
A = np.array(([[0, 1/4, -1/4 ],
[4/8, 0, 1/8],
[2/5, -1/5, 0]]))
np.linalg.eig(A)
%%javascript
$.getScript('https://kmahelona.github.io/ipython_notebook_goodies/ipython_notebook_toc.js')