hess.cc

Go to the documentation of this file.
00001 /*
00002 
00003 Copyright (C) 1996-2012 John W. Eaton
00004 
00005 This file is part of Octave.
00006 
00007 Octave is free software; you can redistribute it and/or modify it
00008 under the terms of the GNU General Public License as published by the
00009 Free Software Foundation; either version 3 of the License, or (at your
00010 option) any later version.
00011 
00012 Octave is distributed in the hope that it will be useful, but WITHOUT
00013 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00014 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00015 for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with Octave; see the file COPYING.  If not, see
00019 <http://www.gnu.org/licenses/>.
00020 
00021 */
00022 
00023 #ifdef HAVE_CONFIG_H
00024 #include <config.h>
00025 #endif
00026 
00027 #include "CmplxHESS.h"
00028 #include "dbleHESS.h"
00029 #include "fCmplxHESS.h"
00030 #include "floatHESS.h"
00031 
00032 #include "defun-dld.h"
00033 #include "error.h"
00034 #include "gripes.h"
00035 #include "oct-obj.h"
00036 #include "utils.h"
00037 
00038 DEFUN_DLD (hess, args, nargout,
00039   "-*- texinfo -*-\n\
00040 @deftypefn  {Loadable Function} {@var{H} =} hess (@var{A})\n\
00041 @deftypefnx {Loadable Function} {[@var{P}, @var{H}] =} hess (@var{A})\n\
00042 @cindex Hessenberg decomposition\n\
00043 Compute the Hessenberg decomposition of the matrix @var{A}.\n\
00044 \n\
00045 The Hessenberg decomposition is\n\
00046 @tex\n\
00047 $$\n\
00048 A = PHP^T\n\
00049 $$\n\
00050 where $P$ is a square unitary matrix ($P^TP = I$), and $H$\n\
00051 is upper Hessenberg ($H_{i,j} = 0, \\forall i \\ge j+1$).\n\
00052 @end tex\n\
00053 @ifnottex\n\
00054 @code{@var{P} * @var{H} * @var{P}' = @var{A}} where @var{P} is a square\n\
00055 unitary matrix (@code{@var{P}' * @var{P} = I}, using complex-conjugate\n\
00056 transposition) and @var{H} is upper Hessenberg\n\
00057 (@code{@var{H}(i, j) = 0 forall i >= j+1)}.\n\
00058 @end ifnottex\n\
00059 \n\
00060 The Hessenberg decomposition is usually used as the first step in an\n\
00061 eigenvalue computation, but has other applications as well (see Golub,\n\
00062 Nash, and Van Loan, IEEE Transactions on Automatic Control, 1979).\n\
00063 @end deftypefn")
00064 {
00065   octave_value_list retval;
00066 
00067   int nargin = args.length ();
00068 
00069   if (nargin != 1 || nargout > 2)
00070     {
00071       print_usage ();
00072       return retval;
00073     }
00074 
00075   octave_value arg = args(0);
00076 
00077   octave_idx_type nr = arg.rows ();
00078   octave_idx_type nc = arg.columns ();
00079 
00080   int arg_is_empty = empty_arg ("hess", nr, nc);
00081 
00082   if (arg_is_empty < 0)
00083     return retval;
00084   else if (arg_is_empty > 0)
00085     return octave_value_list (2, Matrix ());
00086 
00087   if (nr != nc)
00088     {
00089       gripe_square_matrix_required ("hess");
00090       return retval;
00091     }
00092 
00093   if (arg.is_single_type ())
00094     {
00095       if (arg.is_real_type ())
00096         {
00097          FloatMatrix tmp = arg.float_matrix_value ();
00098 
00099           if (! error_state)
00100             {
00101               FloatHESS result (tmp);
00102 
00103               if (nargout <= 1)
00104                 retval(0) = result.hess_matrix ();
00105               else
00106                 {
00107                   retval(1) = result.hess_matrix ();
00108                   retval(0) = result.unitary_hess_matrix ();
00109                 }
00110             }
00111         }
00112       else if (arg.is_complex_type ())
00113         {
00114           FloatComplexMatrix ctmp = arg.float_complex_matrix_value ();
00115 
00116           if (! error_state)
00117             {
00118               FloatComplexHESS result (ctmp);
00119 
00120               if (nargout <= 1)
00121                 retval(0) = result.hess_matrix ();
00122               else
00123                 {
00124                   retval(1) = result.hess_matrix ();
00125                   retval(0) = result.unitary_hess_matrix ();
00126                 }
00127             }
00128         }
00129     }
00130   else
00131     {
00132       if (arg.is_real_type ())
00133         {
00134           Matrix tmp = arg.matrix_value ();
00135 
00136           if (! error_state)
00137             {
00138               HESS result (tmp);
00139 
00140               if (nargout <= 1)
00141                 retval(0) = result.hess_matrix ();
00142               else
00143                 {
00144                   retval(1) = result.hess_matrix ();
00145                   retval(0) = result.unitary_hess_matrix ();
00146                 }
00147             }
00148         }
00149       else if (arg.is_complex_type ())
00150         {
00151           ComplexMatrix ctmp = arg.complex_matrix_value ();
00152 
00153           if (! error_state)
00154             {
00155               ComplexHESS result (ctmp);
00156 
00157               if (nargout <= 1)
00158                 retval(0) = result.hess_matrix ();
00159               else
00160                 {
00161                   retval(1) = result.hess_matrix ();
00162                   retval(0) = result.unitary_hess_matrix ();
00163                 }
00164             }
00165         }
00166       else
00167         {
00168           gripe_wrong_type_arg ("hess", arg);
00169         }
00170     }
00171 
00172   return retval;
00173 }
00174 
00175 /*
00176 
00177 %!test
00178 %! a = [1, 2, 3; 5, 4, 6; 8, 7, 9];
00179 %! [p, h] = hess (a);
00180 %! assert(p * h * p', a, sqrt(eps));
00181 
00182 %!test
00183 %! a = single([1, 2, 3; 5, 4, 6; 8, 7, 9]);
00184 %! [p, h] = hess (a);
00185 %! assert(p * h * p', a, sqrt(eps ('single')));
00186 
00187 %!error <Invalid call to hess> hess ();
00188 %!error <Invalid call to hess> hess ([1, 2; 3, 4], 2);
00189 %!error hess ([1, 2; 3, 4; 5, 6]);
00190 
00191 */
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines