GNU Octave  3.8.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
hess.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 1996-2013 John W. Eaton
4 
5 This file is part of Octave.
6 
7 Octave is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11 
12 Octave is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with Octave; see the file COPYING. If not, see
19 <http://www.gnu.org/licenses/>.
20 
21 */
22 
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26 
27 #include "CmplxHESS.h"
28 #include "dbleHESS.h"
29 #include "fCmplxHESS.h"
30 #include "floatHESS.h"
31 
32 #include "defun.h"
33 #include "error.h"
34 #include "gripes.h"
35 #include "oct-obj.h"
36 #include "utils.h"
37 
38 DEFUN (hess, args, nargout,
39  "-*- texinfo -*-\n\
40 @deftypefn {Built-in Function} {@var{H} =} hess (@var{A})\n\
41 @deftypefnx {Built-in Function} {[@var{P}, @var{H}] =} hess (@var{A})\n\
42 @cindex Hessenberg decomposition\n\
43 Compute the Hessenberg decomposition of the matrix @var{A}.\n\
44 \n\
45 The Hessenberg decomposition is\n\
46 @tex\n\
47 $$\n\
48 A = PHP^T\n\
49 $$\n\
50 where $P$ is a square unitary matrix ($P^TP = I$), and $H$\n\
51 is upper Hessenberg ($H_{i,j} = 0, \\forall i \\ge j+1$).\n\
52 @end tex\n\
53 @ifnottex\n\
54 @code{@var{P} * @var{H} * @var{P}' = @var{A}} where @var{P} is a square\n\
55 unitary matrix (@code{@var{P}' * @var{P} = I}, using complex-conjugate\n\
56 transposition) and @var{H} is upper Hessenberg\n\
57 (@code{@var{H}(i, j) = 0 forall i >= j+1)}.\n\
58 @end ifnottex\n\
59 \n\
60 The Hessenberg decomposition is usually used as the first step in an\n\
61 eigenvalue computation, but has other applications as well (see Golub,\n\
62 Nash, and Van Loan, IEEE Transactions on Automatic Control, 1979).\n\
63 @seealso{eig, chol, lu, qr, qz, schur, svd}\n\
64 @end deftypefn")
65 {
66  octave_value_list retval;
67 
68  int nargin = args.length ();
69 
70  if (nargin != 1 || nargout > 2)
71  {
72  print_usage ();
73  return retval;
74  }
75 
76  octave_value arg = args(0);
77 
78  octave_idx_type nr = arg.rows ();
79  octave_idx_type nc = arg.columns ();
80 
81  int arg_is_empty = empty_arg ("hess", nr, nc);
82 
83  if (arg_is_empty < 0)
84  return retval;
85  else if (arg_is_empty > 0)
86  return octave_value_list (2, Matrix ());
87 
88  if (nr != nc)
89  {
91  return retval;
92  }
93 
94  if (arg.is_single_type ())
95  {
96  if (arg.is_real_type ())
97  {
98  FloatMatrix tmp = arg.float_matrix_value ();
99 
100  if (! error_state)
101  {
102  FloatHESS result (tmp);
103 
104  if (nargout <= 1)
105  retval(0) = result.hess_matrix ();
106  else
107  {
108  retval(1) = result.hess_matrix ();
109  retval(0) = result.unitary_hess_matrix ();
110  }
111  }
112  }
113  else if (arg.is_complex_type ())
114  {
116 
117  if (! error_state)
118  {
119  FloatComplexHESS result (ctmp);
120 
121  if (nargout <= 1)
122  retval(0) = result.hess_matrix ();
123  else
124  {
125  retval(1) = result.hess_matrix ();
126  retval(0) = result.unitary_hess_matrix ();
127  }
128  }
129  }
130  }
131  else
132  {
133  if (arg.is_real_type ())
134  {
135  Matrix tmp = arg.matrix_value ();
136 
137  if (! error_state)
138  {
139  HESS result (tmp);
140 
141  if (nargout <= 1)
142  retval(0) = result.hess_matrix ();
143  else
144  {
145  retval(1) = result.hess_matrix ();
146  retval(0) = result.unitary_hess_matrix ();
147  }
148  }
149  }
150  else if (arg.is_complex_type ())
151  {
152  ComplexMatrix ctmp = arg.complex_matrix_value ();
153 
154  if (! error_state)
155  {
156  ComplexHESS result (ctmp);
157 
158  if (nargout <= 1)
159  retval(0) = result.hess_matrix ();
160  else
161  {
162  retval(1) = result.hess_matrix ();
163  retval(0) = result.unitary_hess_matrix ();
164  }
165  }
166  }
167  else
168  {
169  gripe_wrong_type_arg ("hess", arg);
170  }
171  }
172 
173  return retval;
174 }
175 
176 /*
177 %!test
178 %! a = [1, 2, 3; 5, 4, 6; 8, 7, 9];
179 %! [p, h] = hess (a);
180 %! assert (p * h * p', a, sqrt (eps));
181 
182 %!test
183 %! a = single ([1, 2, 3; 5, 4, 6; 8, 7, 9]);
184 %! [p, h] = hess (a);
185 %! assert (p * h * p', a, sqrt (eps ("single")));
186 
187 %!error hess ()
188 %!error hess ([1, 2; 3, 4], 2)
189 %!error <argument must be a square matrix> hess ([1, 2; 3, 4; 5, 6])
190 */