from __future__ import division
import numpy as np
import numpy.linalg as la
import matplotlib.pyplot as pt
np.random.seed(40)
# Generate matrix with eigenvalues 1...25
n = 25
eigvals = np.linspace(1., n, n)
eigvecs = np.random.randn(n, n)
print eigvals
A = la.solve(eigvecs, np.dot(np.diag(eigvals), eigvecs))
print la.eig(A)[0]
# Initialize Arnoldi iteration
# Set up Q and H
Q = np.zeros((n, n))
H = np.zeros((n, n))
k = 0
# Pick a starting vector, normalize it
x0 = np.random.randn(n)
x0 = x0/la.norm(x0)
# Poke it into the first column of Q
Q[:, k] = x0
del x0
# ritz_values = []
# Carry out one iteration of Arnoldi iteration
# Run this cell in-place (Ctrl-Enter) until H is filled.
print k
u = np.dot(A, Q[:, k])
# Carry out Gram-Schmidt on u against Q
for j in range(k+1):
qj = Q[:, j]
H[j,k] = np.dot(qj, u)
u = u - H[j,k]*qj
if k+1 < n:
H[k+1, k] = la.norm(u)
Q[:, k+1] = u/H[k+1, k]
k += 1
pt.spy(H)
# ritz_values.append(la.eig(H)[0])
# Check that Q^T A Q = H
la.norm(
np.dot(np.dot(Q.T, A), Q)
- H) / la.norm(A)
# Check that Q is orthogonal
la.norm(
np.dot(Q.T, Q) - np.eye(n))
# Enable the Ritz value collection above to make this work.
for i, rv in enumerate(ritz_values):
plot([i] * len(rv), rv, "x")