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