1 | function [V, D] = eig(A) |
---|
2 | % EIG Eigenvalues and eigenvectors. |
---|
3 | % (Quaternion overloading of standard Matlab function, with limitations.) |
---|
4 | % |
---|
5 | % Acceptable calling sequences are: [V,D] = EIG(X) and V = EIG(X). |
---|
6 | % The results are as for the standard Matlab EIG function (q.v.). |
---|
7 | |
---|
8 | % Copyright © 2005 Stephen J. Sangwine and Nicolas Le Bihan. |
---|
9 | % See the file : Copyright.m for further details. |
---|
10 | |
---|
11 | error(nargchk(1, 1, nargin)), error(nargoutchk(0, 2, nargout)) |
---|
12 | |
---|
13 | [r, c] = size(A); |
---|
14 | |
---|
15 | if r ~= c |
---|
16 | error('Matrix must be square'); |
---|
17 | end |
---|
18 | |
---|
19 | if r == 1 |
---|
20 | |
---|
21 | % The argument is a single quaternion. This case could be handled by |
---|
22 | % using the standard Matlab eig() function on the complex adjoint of |
---|
23 | % A, but there are problems if A is a complexified quaternion, since |
---|
24 | % we cannot make a complex value with complex parts. |
---|
25 | % |
---|
26 | % For this reason we output an error message and leave it to the user |
---|
27 | % to use the appropriate adjoint. |
---|
28 | |
---|
29 | A = inputname(1); if A == '' A = 'A'; end |
---|
30 | |
---|
31 | disp('The eig function is not implemented for single quaternions.'); |
---|
32 | disp(sprintf('Try using eig(adjoint(%s, ''real'')) or', A)); |
---|
33 | disp(sprintf(' eig(adjoint(%s, ''complex'')', A)); |
---|
34 | error('Implementation restriction - see advice above'); |
---|
35 | end |
---|
36 | |
---|
37 | % The method used depends on whether A is Hermitian or otherwise. |
---|
38 | |
---|
39 | if ishermitian(A) |
---|
40 | |
---|
41 | % For a Hermitian matrix the eigenvalues and eigenvectors are real if A is a |
---|
42 | % real quaternion matrix and complex if A is a complexified quaternion matrix. |
---|
43 | % The first step is to tridiagonalize A using Householder transformations to |
---|
44 | % obtain P and B where B is a real or complex tridiagonal symmetric matrix, |
---|
45 | % and P is the product of the Householder matrices used to compute B |
---|
46 | % such that P'*B*P = A. |
---|
47 | |
---|
48 | [P, B] = tridiagonalize(A); |
---|
49 | else |
---|
50 | |
---|
51 | % For a general (i.e. non Hermitian) matrix, we don't currently have a method to |
---|
52 | % convert A to a real matrix. The only feasible approach is to use an adjoint |
---|
53 | % matrix, but we leave this to the user. |
---|
54 | |
---|
55 | disp('The eig function is not implemented for non-Hermitian quaternion matrices.'); |
---|
56 | disp('Eigenvalues and eigenvectors can be computed by using the standard Matlab'); |
---|
57 | disp('eig function on an adjoint matrix by using the function adjoint() (q.v.).'); |
---|
58 | error('Implementation restriction - see advice above'); |
---|
59 | |
---|
60 | end |
---|
61 | |
---|
62 | % We now have: P' * B * P = A. |
---|
63 | |
---|
64 | % The second step is to compute the eigenvectors and eigenvalues of B using the standard |
---|
65 | % Matlab routine, for a real or complex matrix (which happens to be tridiagonal). |
---|
66 | |
---|
67 | if nargout == 0 |
---|
68 | eig(B) |
---|
69 | elseif nargout == 1 |
---|
70 | V = eig(B); |
---|
71 | else |
---|
72 | [V, D] = eig(B); |
---|
73 | V = P' * V; % Combine P (from the tridiagonalization) with V. |
---|
74 | end |
---|
75 | |
---|
76 | |
---|