3
Copyright (C) 1996, 1997, 1999, 2000, 2004, 2005, 2006, 2007
6
This file is part of Octave.
8
Octave is free software; you can redistribute it and/or modify it
9
under the terms of the GNU General Public License as published by the
10
Free Software Foundation; either version 3 of the License, or (at your
11
option) any later version.
13
Octave is distributed in the hope that it will be useful, but WITHOUT
14
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18
You should have received a copy of the GNU General Public License
19
along with Octave; see the file COPYING. If not, see
20
<http://www.gnu.org/licenses/>.
30
#include "CmplxSCHUR.h"
31
#include "dbleSCHUR.h"
33
#include "defun-dld.h"
39
DEFUN_DLD (schur, args, nargout,
41
@deftypefn {Loadable Function} {@var{s} =} schur (@var{a})\n\
42
@deftypefnx {Loadable Function} {[@var{u}, @var{s}] =} schur (@var{a}, @var{opt})\n\
43
@cindex Schur decomposition\n\
44
The Schur decomposition is used to compute eigenvalues of a\n\
45
square matrix, and has applications in the solution of algebraic\n\
46
Riccati equations in control (see @code{are} and @code{dare}).\n\
47
@code{schur} always returns\n\
54
@code{s = u' * a * u}\n\
65
is a unitary matrix\n\
68
($U^T U$ is identity)\n\
72
(@code{u'* u} is identity)\n\
83
is upper triangular. The eigenvalues of\n\
90
@code{a} (and @code{s})\n\
92
are the diagonal elements of\n\
110
is real, then the real Schur decomposition is computed, in which the\n\
129
is block upper triangular\n\
130
with blocks of size at most\n\
139
along the diagonal. The diagonal elements of\n\
148
(or the eigenvalues of the\n\
158
appropriate) are the eigenvalues of\n\
177
The eigenvalues are optionally ordered along the diagonal according to\n\
178
the value of @code{opt}. @code{opt = \"a\"} indicates that all\n\
179
eigenvalues with negative real parts should be moved to the leading\n\
189
(used in @code{are}), @code{opt = \"d\"} indicates that all eigenvalues\n\
190
with magnitude less than one should be moved to the leading block of\n\
199
(used in @code{dare}), and @code{opt = \"u\"}, the default, indicates that\n\
200
no ordering of eigenvalues should occur. The leading\n\
225
@code{a}-invariant\n\
227
subspace corresponding to the\n\
236
leading eigenvalues of\n\
247
octave_value_list retval;
249
int nargin = args.length ();
251
if (nargin < 1 || nargin > 2 || nargout > 2)
257
octave_value arg = args(0);
263
ord = args(1).string_value ();
267
error ("schur: expecting string as second argument");
272
char ord_char = ord.empty () ? 'U' : ord[0];
274
if (ord_char != 'U' && ord_char != 'A' && ord_char != 'D'
275
&& ord_char != 'u' && ord_char != 'a' && ord_char != 'd')
277
warning ("schur: incorrect ordered schur argument `%c'",
282
octave_idx_type nr = arg.rows ();
283
octave_idx_type nc = arg.columns ();
285
int arg_is_empty = empty_arg ("schur", nr, nc);
287
if (arg_is_empty < 0)
289
else if (arg_is_empty > 0)
290
return octave_value_list (2, Matrix ());
294
gripe_square_matrix_required ("schur");
298
if (arg.is_real_type ())
300
Matrix tmp = arg.matrix_value ();
304
if (nargout == 0 || nargout == 1)
306
SCHUR result (tmp, ord, false);
307
retval(0) = result.schur_matrix ();
311
SCHUR result (tmp, ord, true);
312
retval(1) = result.schur_matrix ();
313
retval(0) = result.unitary_matrix ();
317
else if (arg.is_complex_type ())
319
ComplexMatrix ctmp = arg.complex_matrix_value ();
324
if (nargout == 0 || nargout == 1)
326
ComplexSCHUR result (ctmp, ord, false);
327
retval(0) = result.schur_matrix ();
331
ComplexSCHUR result (ctmp, ord, true);
332
retval(1) = result.schur_matrix ();
333
retval(0) = result.unitary_matrix ();
339
gripe_wrong_type_arg ("schur", arg);
346
;;; Local Variables: ***