[37] | 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 | |
---|