8.2. Eigenvector Animation¶
Eigenvectors and eigenvalues can be difficult to understand at first.
Hence, the eigdemo.
script shows an animation to help readers
visualize what makes a vector an eigenvector. The file is in the
downloadable code from the book’s website. The code plots an animation
when a \(2{\times}2\) matrix is passed to it. The matrix must have
real eigenvectors and eigenvalues, which is always achieved when it is
symmetric (equal to its transpose). The animation shows the product of
the matrix with a rotating unit vector. The scaled eigenvectors,
\(\lambda_i\,\bm{x_i}\), are also shown. The product of the matrix
and vector is equivalent to the scaled eigenvector when the unit vector
is over an eigenvector.
function eigdemo(A)
%% Eigenvector, eigenvalue Demo for input 2x2 matrix.
%
% When eigenvectors of A are mulitiplied by A, the result is a scalar
% multiple of the vector. The scalar values (lambda) are the eigenvalues
% of A. It is the orientation of the eigenvectors that makes them special.
%
% A*x == lambda*x, C*A*x == C*lambda*x
%
% This function shows an animation demonstrating that the product (A*x) is
% inline with the vector x when, and only when, x is an eigenvector. The A
% (input) matrix must be a 2x2 matrix with real eigenvalues.
%
% The red rotating line shows possible unit vectors, x.
% The blue moving line is v = A*x.
% The green fixed arrows are the product (lamda*eigenvectors == A*ex),
%
% Notice that when the red rotating vector is inline win an eigenvector
% that the blue line matches the green arrows. The blue line is also (-1)
% of the green arrow when the red rotating line is (-1) of an eigenvector.
%
if size(A,1) ~= 2 || size(A,2) ~= 2
disp('Matrix A must be 2x2')
return;
end
theta = linspace(2*pi,0,100);
xv = cos(theta);
yv = sin(theta);
v = A*[xv; yv];
[ex, lambda] = eig(A);
if ~isreal(ex) || ~isreal(lambda)
disp('Complex Eigenvector results, use another A matrix');
return;
end
ep = A*ex; % same as A*ex == lambda*ev
fprintf('eigenvector 1: %f %f\n', ex(1,1), ex(2,1));
fprintf('eigenvector 2: %f %f\n', ex(1,2), ex(2,2));
fprintf('A*eigenvector 1: %f %f\n', ep(1,1), ep(2,1));
fprintf('A*eigenvector 2: %f %f\n', ep(1,2), ep(2,2));
fprintf('lambda: %f %f\n', lambda(1,1), lambda(2,2));
M = ceil(max(vecnorm(v)));
figure; axis([-M M -M M]);
daspect([1 1 1]);
hold on
l1 = line([0 1], [0 0], 'LineWidth', 3, 'Color', 'r');
l2 = line([0 1], [0 0], 'LineWidth', 3, 'Color', 'b');
plot2vector(ep(:,1), 'g', 2); % lamda 1 * eigenvector 1
plot2vector(ep(:,2), 'g', 2); % lamda 2 * eigenvector 2
hold off
for k = 1:3 % make three loops
for i = 1:100
l1.set('XData', [0 xv(i)], 'YData', [0 yv(i)]);
l2.set('XData', [0 v(1,i)], 'YData', [0 v(2,i)]);
drawnow;
pause(0.1);
end
end
end
function plot2vector(x, color, LineWidth)
if iscolumn(x)
x = x';
end
plot([0, x(1)], [0, x(2)], 'Color', color, 'LineWidth', LineWidth)
end