Mercurial > hg > octave-nkf
diff scripts/polynomial/polyeig.m @ 15186:504fec921af5
polyeig: new function
author | Fotios Kasolis <fotios.kasolis@gmail.com> |
---|---|
date | Thu, 19 Jul 2012 04:50:43 +0100 |
parents | |
children | 045ae93e8fe9 |
line wrap: on
line diff
new file mode 100644 --- /dev/null +++ b/scripts/polynomial/polyeig.m @@ -0,0 +1,78 @@ +## Copyright (C) 2012 Fotios Kasolis +## +## This file is part of Octave. +## +## Octave is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or (at +## your option) any later version. +## +## Octave is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Octave; see the file COPYING. If not, see +## <http://www.gnu.org/licenses/>. + +## -*- texinfo -*- +## @deftypefn {Function File} {@var{z} =} polyeig (@var{C0}, @var{C1}, @dots{}, @var{Cl}) +## @deftypefnx {Function File} {[ @var{v}, @var{z} ] =} polyeig (@var{C0}, @var{C1}, @dots{}, @var{Cl}) +## Solve the polynomial eigenvalue problem of degree @var{l}. +## +## Given a @var{n*n} matrix polynomial @var{C(s)} = @var{C0 + C1 s + @dots{} + Cl s^l} polyeig +## solves the eigenvalue problem (@var{C0} + @var{C1} + @dots{} + @var{Cl})v = 0. +## Note that the eigenvalues @var{z} are the zeros of the matrix polynomial. @var{z} is a +## @var{lxn} vector and @var{v} is a @var{(n x n)l} matrix with columns that correspond to +## the eigenvectors. +## @seealso{eig, eigs, compan} +## @end deftypefn + +## Author: Fotios Kasolis + +function [ z, varargout ] = polyeig (varargin) + + if ( nargout > 2 ) + print_usage (); + endif + + nin = numel (varargin); + + n = zeros (1, nin); + + for cnt = 1 : nin + if ! ( issquare (varargin{cnt}) ) + error ("polyeig: coefficients must be square matrices"); + endif + n(cnt) = size (varargin{cnt}, 1); + endfor + + if numel (unique (n)) > 1 + error ("polyeig: coefficients must have the same dimensions"); + endif + n = unique (n); + + # matrix polynomial degree + l = nin - 1; + + # form needed matrices + C = [ zeros(n * (l - 1), n), eye(n * (l - 1)); -cell2mat(varargin(1 : end - 1)) ]; + D = [ eye(n * (l - 1)), zeros(n * (l - 1), n); zeros(n, n * (l - 1)), varargin{end} ]; + + % solve generalized eigenvalue problem + if ( isequal (nargout, 1) ) + z = eig (C, D); + else + [ z, v ] = eig (C, D); + varargout{1} = diag (v); + endif + +endfunction + +## sanity test +%!test +%! C0 = [8, 0; 0, 0]; C1 = [1, 0; 0, 0]; +%! z = polyeig (C0, C1); +%! assert (isequal (z(1), -8), true); +