Mercurial > octave-nkf
comparison scripts/polynomial/polyeig.m @ 18575:f57148641869 gui-release
polyeig.m: Overhaul function for Matlab compatibility (bug #41865).
* NEWS: Announce change in return format of polyeig.
* polyeig.m: Return a row vector of eigenvalues rather than a matrix with
eigenvalues on the diagonal. Improve docstring. Improve input validation.
Add %!error tests for input validation.
author | Rik <rik@octave.org> |
---|---|
date | Sat, 15 Mar 2014 16:29:46 -0700 |
parents | d63878346099 |
children | fe689210525c |
comparison
equal
deleted
inserted
replaced
18574:6b4f9cab88d6 | 18575:f57148641869 |
---|---|
24 ## | 24 ## |
25 ## Given an @var{n*n} matrix polynomial | 25 ## Given an @var{n*n} matrix polynomial |
26 ## @code{@var{C}(s) = @var{C0} + @var{C1} s + @dots{} + @var{Cl} s^l} | 26 ## @code{@var{C}(s) = @var{C0} + @var{C1} s + @dots{} + @var{Cl} s^l} |
27 ## polyeig solves the eigenvalue problem | 27 ## polyeig solves the eigenvalue problem |
28 ## @code{(@var{C0} + @var{C1} + @dots{} + @var{Cl})v = 0}. | 28 ## @code{(@var{C0} + @var{C1} + @dots{} + @var{Cl})v = 0}. |
29 ## | |
29 ## Note that the eigenvalues @var{z} are the zeros of the matrix polynomial. | 30 ## Note that the eigenvalues @var{z} are the zeros of the matrix polynomial. |
30 ## @var{z} is an @var{lxn} vector and @var{v} is an (@var{n} x @var{n})l matrix | 31 ## @var{z} is a row vector with @var{n*l} elements. @var{v} is a matrix |
31 ## with columns that correspond to the eigenvectors. | 32 ## (@var{n} x @var{n}*@var{l}) with columns that correspond to the |
33 ## eigenvectors. | |
32 ## | 34 ## |
33 ## @seealso{eig, eigs, compan} | 35 ## @seealso{eig, eigs, compan} |
34 ## @end deftypefn | 36 ## @end deftypefn |
35 | 37 |
36 ## Author: Fotios Kasolis | 38 ## Author: Fotios Kasolis |
37 | 39 |
38 function [ z, varargout ] = polyeig (varargin) | 40 function [z, v] = polyeig (varargin) |
39 | 41 |
40 if ( nargout > 2 ) | 42 if (nargin < 1 || nargout > 2) |
41 print_usage (); | 43 print_usage (); |
42 endif | 44 endif |
43 | 45 |
44 nin = numel (varargin); | 46 nin = numel (varargin); |
47 n = rows (varargin{1}); | |
45 | 48 |
46 n = zeros (1, nin); | 49 for i = 1 : nin |
47 | 50 if (! issquare (varargin{i})) |
48 for cnt = 1 : nin | 51 error ("polyeig: coefficients must be square matrices"); |
49 if (! issquare (varargin{cnt})) | |
50 error ("polyeig: coefficients must be square matrices"); | |
51 endif | 52 endif |
52 n(cnt) = size (varargin{cnt}, 1); | 53 if (rows (varargin{i}) != n) |
54 error ("polyeig: coefficients must have the same dimensions"); | |
55 endif | |
53 endfor | 56 endfor |
54 | |
55 if (numel (unique (n)) > 1) | |
56 error ("polyeig: coefficients must have the same dimensions"); | |
57 endif | |
58 n = unique (n); | |
59 | 57 |
60 ## matrix polynomial degree | 58 ## matrix polynomial degree |
61 l = nin - 1; | 59 l = nin - 1; |
62 | 60 |
63 ## form needed matrices | 61 ## form needed matrices |
64 C = [ zeros(n * (l - 1), n), eye(n * (l - 1)); | 62 C = [ zeros(n * (l - 1), n), eye(n * (l - 1)); |
65 -cell2mat(varargin(1 : end - 1)) ]; | 63 -cell2mat(varargin(1:end-1)) ]; |
66 | 64 |
67 D = [ eye(n * (l - 1)), zeros(n * (l - 1), n); | 65 D = [ eye(n * (l - 1)), zeros(n * (l - 1), n); |
68 zeros(n, n * (l - 1)), varargin{end} ]; | 66 zeros(n, n * (l - 1)), varargin{end} ]; |
69 | 67 |
70 ## solve generalized eigenvalue problem | 68 ## solve generalized eigenvalue problem |
71 if ( isequal (nargout, 1) ) | 69 if (nargout == 2) |
72 z = eig (C, D); | 70 [z, v] = eig (C, D); |
73 else | 71 v = diag (v); |
74 [ z, v ] = eig (C, D); | 72 ## return n-element eigenvectors normalized so that the infinity-norm = 1 |
75 varargout{1} = v; | |
76 ## return n-element eigenvectors normalized so | |
77 ## that the infinity-norm = 1 | |
78 z = z(1:n,:); | 73 z = z(1:n,:); |
79 ## max() takes the abs if complex: | 74 ## max() takes the abs if complex: |
80 t = max (z); | 75 t = max (z); |
81 z /= diag (t); | 76 z /= diag (t); |
77 else | |
78 z = eig (C, D); | |
82 endif | 79 endif |
83 | 80 |
84 endfunction | 81 endfunction |
85 | 82 |
86 | 83 |
84 %!shared C0, C1 | |
85 %! C0 = [8, 0; 0, 4]; C1 = [1, 0; 0, 1]; | |
86 | |
87 %!test | 87 %!test |
88 %! C0 = [8, 0; 0, 4]; C1 = [1, 0; 0, 1]; | 88 %! z = polyeig (C0, C1); |
89 %! assert (z, [-8; -4]); | |
90 | |
91 %!test | |
89 %! [v,z] = polyeig (C0, C1); | 92 %! [v,z] = polyeig (C0, C1); |
90 %! assert (isequal (z(1), -8), true); | 93 %! assert (z, [-8; -4]); |
94 %! z = diag (z); | |
91 %! d = C0*v + C1*v*z; | 95 %! d = C0*v + C1*v*z; |
92 %! assert (isequal (norm(d), 0.0), true); | 96 %! assert (norm (d), 0.0); |
93 | 97 |
98 %% Input validation tests | |
99 %!error polyeig () | |
100 %!error [a,b,c] = polyeig (1) | |
101 %!error <coefficients must be square matrices> polyeig (ones (3,2)) | |
102 %!error <coefficients must have the same dimensions> polyeig (ones (3,3), ones (2,2)) |