40 template <
class Matrix>
60 DEFUN (schur, args, nargout,
62 @deftypefn {Built-in Function} {@var{S} =} schur (@var{A})\n\
63 @deftypefnx {Built-in Function} {@var{S} =} schur (@var{A}, \"real\")\n\
64 @deftypefnx {Built-in Function} {@var{S} =} schur (@var{A}, \"complex\")\n\
65 @deftypefnx {Built-in Function} {@var{S} =} schur (@var{A}, @var{opt})\n\
66 @deftypefnx {Built-in Function} {[@var{U}, @var{S}] =} schur (@dots{})\n\
67 @cindex Schur decomposition\n\
68 Compute the Schur@tie{}decomposition of @var{A}.\n\
70 The Schur@tie{}decomposition is defined as\n\
79 @code{@var{S} = @var{U}' * @var{A} * @var{U}}\n\
83 where @var{U} is a unitary matrix\n\
85 ($U^T U$ is identity)\n\
88 (@code{@var{U}'* @var{U}} is identity)\n\
90 and @var{S} is upper triangular. The eigenvalues of @var{A} (and @var{S})\n\
91 are the diagonal elements of @var{S}. If the matrix @var{A} is real, then\n\
92 the real Schur@tie{}decomposition is computed, in which the matrix @var{U}\n\
93 is orthogonal and @var{S} is block upper triangular with blocks of size at\n\
101 along the diagonal. The diagonal elements of @var{S}\n\
102 (or the eigenvalues of the\n\
109 blocks, when appropriate) are the eigenvalues of @var{A} and @var{S}.\n\
111 The default for real matrices is a real Schur@tie{}decomposition.\n\
112 A complex decomposition may be forced by passing the flag\n\
113 @qcode{\"complex\"}.\n\
115 The eigenvalues are optionally ordered along the diagonal according to the\n\
116 value of @var{opt}. @code{@var{opt} = \"a\"} indicates that all eigenvalues\n\
117 with negative real parts should be moved to the leading block of @var{S}\n\
118 (used in @code{are}), @code{@var{opt} = \"d\"} indicates that all\n\
119 eigenvalues with magnitude less than one should be moved to the leading\n\
120 block of @var{S} (used in @code{dare}), and @code{@var{opt} = \"u\"}, the\n\
121 default, indicates that no ordering of eigenvalues should occur. The\n\
122 leading @var{k} columns of @var{U} always span the @var{A}-invariant\n\
123 subspace corresponding to the @var{k} leading eigenvalues of @var{S}.\n\
125 The Schur@tie{}decomposition is used to compute eigenvalues of a square\n\
126 matrix, and has applications in the solution of algebraic Riccati equations\n\
127 in control (see @code{are} and @code{dare}).\n\
128 @seealso{rsf2csf, ordschur, lu, chol, hess, qr, qz, svd}\n\
133 int nargin = args.
length ();
135 if (nargin < 1 || nargin > 2 || nargout > 2)
147 if (args(1).is_string ())
148 ord = args(1).string_value ();
151 error (
"schur: second argument must be a string");
156 bool force_complex =
false;
160 ord = std::string ();
162 else if (ord ==
"complex")
164 force_complex =
true;
165 ord = std::string ();
169 char ord_char = ord.empty () ?
'U' : ord[0];
171 if (ord_char !=
'U' && ord_char !=
'A' && ord_char !=
'D'
172 && ord_char !=
'u' && ord_char !=
'a' && ord_char !=
'd')
174 warning (
"schur: incorrect ordered schur argument '%s'",
199 if (nargout == 0 || nargout == 1)
219 if (nargout == 0 || nargout == 1)
241 if (nargout == 0 || nargout == 1)
243 SCHUR result (tmp, ord,
false);
248 SCHUR result (tmp, ord,
true);
261 if (nargout == 0 || nargout == 1)
299 DEFUN (rsf2csf, args, nargout,
301 @deftypefn {Function File} {[@var{U}, @var{T}] =} rsf2csf (@var{UR}, @var{TR})\n\
302 Convert a real, upper quasi-triangular Schur@tie{}form @var{TR} to a complex,\n\
303 upper triangular Schur@tie{}form @var{T}.\n\
305 Note that the following relations hold:\n\
308 $UR \\cdot TR \\cdot {UR}^T = U T U^{\\dagger}$ and\n\
309 $U^{\\dagger} U$ is the identity matrix I.\n\
312 @tcode{@var{UR} * @var{TR} * @var{UR}' = @var{U} * @var{T} * @var{U}'} and\n\
313 @code{@var{U}' * @var{U}} is the identity matrix I.\n\
316 Note also that @var{U} and @var{T} are not unique.\n\
322 if (args.length () == 2 && nargout <= 2)
324 if (! args(0).is_numeric_type ())
326 else if (! args(1).is_numeric_type ())
328 else if (args(0).is_complex_type () || args(1).is_complex_type ())
329 error (
"rsf2csf: UR and TR must be real matrices");
333 if (args(0).is_single_type () || args(1).is_single_type ())
347 Matrix u = args(0).matrix_value ();
348 Matrix t = args(1).matrix_value ();
static octave_value mark_upper_triangular(const Matrix &a)
bool is_real_type(void) const
void gripe_wrong_type_arg(const char *name, const char *s, bool is_error)
octave_idx_type rows(void) const
FloatComplexMatrix float_complex_matrix_value(bool frc_str_conv=false) const
OCTINTERP_API void print_usage(void)
octave_idx_type length(void) const
bool is_numeric_type(void) const
#define DEFUN(name, args_name, nargout_name, doc)
void error(const char *fmt,...)
ComplexMatrix schur_matrix(void) const
void gripe_square_matrix_required(const char *name)
FloatComplexMatrix unitary_matrix(void) const
octave_idx_type rows(void) const
octave_idx_type columns(void) const
FloatComplexMatrix schur_matrix(void) const
ComplexMatrix unitary_matrix(void) const
Matrix matrix_value(bool frc_str_conv=false) const
MatrixType matrix_type(void) const
void warning(const char *fmt,...)
FloatMatrix schur_matrix(void) const
FloatMatrix unitary_matrix(void) const
ComplexMatrix complex_matrix_value(bool frc_str_conv=false) const
FloatMatrix float_matrix_value(bool frc_str_conv=false) const
bool is_single_type(void) const
Matrix unitary_matrix(void) const
octave_idx_type columns(void) const
Matrix schur_matrix(void) const