function lambda = eigenvalue(T) % function lambda = eigenvalue(T) % QR iteration % eigenvalues lambda of a symmetric tridiagonal matrix % lower and main diagonal stored in T(:,1:2) TOL = 10^(-10); MAX_IT = 100; n = size(T,1); if n == 1; lambda = T(1,2); elseif n == 2; lambda = shift(T); else; T = [T; 0 0]; for i = 1:MAX_IT; [t_min, k_min] = min(abs(T(2:n,1))); if t_min < TOL; break; end; s = shift([T(n-1,2) T(n,1); T(n,1) T(n,2)]); v = [T(1,2) - s(1); T(2,1)]; for j = 1:n-1; A = [T(j,:) T(j+1,1);v(2) T(j+1,:);0 0 T(j+2,1)]; Q = g_par(v); A(1:2,:) = Q*A(1:2,:); A(:,2:3) = A(:,2:3)*Q'; T(j:j+1,:) = [A(1,1:2); A(2,2:3)]; T(j+2,1) = A(3,3); v = [A(2,2); A(3,2)]; end; end; lambda = [eigenvalue(T(1:k_min,:)); ... eigenvalue(T(k_min+1:n,:))]; end; lambda = sort(lambda); %%%%% local functions function s = shift(T) % eigenvalues of [T(1,2) T(2,1); T(2,1) T(2,2)] m = sum(T(:,2))/2; r = sqrt(m^2 - T(1,2)*T(2,2) + T(2,1)^2); s = [m-r; m+r]; if T(2,2) > T(1,2); s = s([2 1]); end; %%%%% function Q = g_par(v) % function Q = g_par(v) % Givens matrix based on the vector v if norm(v) == 0; v = [1; 0]; end; r = norm(v); sigma = sign(v(1)); if sigma == 0; sigma = 1; end; c = sigma*v(1)/r; s = -sigma*v(2)/r; Q = [c -s; s c];