12.4.5. Iterative QR Algorithm¶
The iterative QR algorithm is a well-known algorithm for finding the eigenvalues of a matrix. We are specifically referring to the explicitly shifted QR algorithm. To be more precise, the QR algorithm moves a matrix from upper Hessenberg form to upper triangular form with the eigenvalues on the diagonal. The remaining algorithm steps build the diagonal eigenvalue matrix, , and the matrix consisting of the eigenvectors, . The iterative algorithm relies on the QR matrix factorization (QR Decomposition).
We begin by describing the general concept of the algorithm before introducing refinements. First, use QR factorization, , to find a new matrix . The original matrix and the modified matrix are similar matrices. Then QR factorization is repeated on to find continuing until is upper triangular, and additional iterations will not change the result. As the matrix converges toward upper triangular at each iteration, the matrix converge toward the identity matrix. When is upper triangular, the eigenvalues will be on its diagonal.
Since , then and establishes similarity between and .
12.4.5.1. Hessenberg Form, Wilkinson Shift, and Deflation¶
Three algorithm refinements lend to faster convergence. First, convert the matrix to upper Hessenberg form by similarity transforms ( Hessenberg Decomposition). The second refinement reduces the diagonal by a scalar shift, , before each QR decomposition. [1] The shift is added back to the diagonal values after the decomposition. When the next eigenvalue to find is real, the value of the last diagonal element works for the shift. A better approach that finds complex eigenvalues is to calculate the two eigenvalues of the lower-right submatrix. The eigenvalue closest to the last diagonal value is selected for the shift. This is called a Wilkinson shift [WILKINSON65]. The algorithm cannot find the complex eigenvalues of a real matrix without the shift. Suppose a pair of complex conjugate eigenvalues is found from the submatrix. In that case, the complex eigenvalues will be on the diagonal with repeated iterations as the subdiagonal elements converge to zero. The algorithm finds eigenvalue when the element at , converges to within the tolerance value to zero. The third algorithm refinement is deflation, which reduces the size of the matrix to exclude the last row after finding each eigenvalue.
Note
If we only wanted to find the eigenvalues, then we would also remove the last column with deflation. However, if we want to find the eigenvectors from the Schur vectors and the eigenvectors of the upper triangular matrix, then we need to keep the columns as part of what is passed the QR decomposition function. The multiplications that happen during the QR decomposition need to affect everything above the diagonal. Thus, deflation causes us to perform the QR decomposition on underdetermined matrices.
function [lambda1, lambda2] = eig22(A)
% EIG22 - Quick eigenvalue calculation of a 2-by-2 matrix
% [lambda1, lambda2] = EIG22(A) returns the eigenvalues in two
% variables.
m = (A(1,1) + A(2,2))/2;
p = A(1,1)*A(2,2) - A(1,2)*A(2,1);
s = sqrt(m^2 - p);
lambda1 = m + s;
lambda2 = m - s;
end
12.4.5.2. The eigQR
Function¶
The eigQR
function is a simple
implementation of the iterative QR algorithm that finds eigenvalues and
eigenvectors. It first finds the Schur decomposition.
function [X, Lambda] = eigQR(A)
% EIGQR - Iterative QR algorithm to find eigenvalues. This
% is the explicitly-shifted QR algorithm.
%
% A - Square matrix
% EIGQR(A) or L = EIGQR(A) returns the eigenvalues of A.
% [X, L] = EIGQR(A) returns the eigenvectors of A as the columns
% of the X matrix and the eigenvalues of A are along the diagonal
% of matrix L.
%
% NOTE: This code is for educational purposes.
% For other purposes, use MATLAB's eig function.
%
% See also: EIG, EIG22, HESS, QR, EIGFRANCIS, UTEIGVECT
[m, n] = size(A);
if m ~= n
error("Matrix must be square to find eigenvalues")
end
% Start with Hessenberg - zeros below first
[Q,T] = hess(A);
tol = 1e-14;
eigs = zeros(n,1);
k = n;
I = eye(n);
while k > 1
[rho1, rho2] = eig22(T(k-1:k,k-1:k));
if abs(T(k,k)-rho1) < abs(T(k,k)-rho2)
shift = rho1*I; else, shift = rho2*I;
end
% MATLAB's qr is faster, but qrFactor allows for
% breakpoints to understand the algorithm better.
B = T(1:k,1:n) - shift;
[Qi, R] = qrFactor(B); % qr(B);
Qn = eye(n);
Qn(1:k,1:k) = Qi;
T(1:k,1:n) = R*Qn + shift;
Q = Q*Qn;
% Converge when kth subdiagonal near zero
if abs(T(k,k-1)) < tol*(abs(T(k,k)) + abs(T(k-1,k-1)))
T(k,k-1) = 0;
eigs(k) = T(k,k); % kth eigenvalue
k = k - 1; % deflation
I = eye(k, n);
end
end
eigs(1) = T(1,1);
if nargout <= 1 % only want eigenvalues
X = sort(eigs);
else % eigenvectors also
Lambda = diag(eigs);
V = UTeigVect(T);
X = Q*V;
end
end
[1] | Since the shift changes the matrix before each QR decomposition, the matrices can not be used to find the eigenvectors. |