00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifdef HAVE_CONFIG_H
00024 #include <config.h>
00025 #endif
00026
00027 #include "CmplxHESS.h"
00028 #include "f77-fcn.h"
00029 #include "lo-error.h"
00030
00031 extern "C"
00032 {
00033 F77_RET_T
00034 F77_FUNC (zgebal, ZGEBAL) (F77_CONST_CHAR_ARG_DECL,
00035 const octave_idx_type&, Complex*,
00036 const octave_idx_type&, octave_idx_type&,
00037 octave_idx_type&, double*, octave_idx_type&
00038 F77_CHAR_ARG_LEN_DECL);
00039
00040 F77_RET_T
00041 F77_FUNC (zgehrd, ZGEHRD) (const octave_idx_type&, const octave_idx_type&,
00042 const octave_idx_type&, Complex*,
00043 const octave_idx_type&, Complex*, Complex*,
00044 const octave_idx_type&, octave_idx_type&);
00045
00046 F77_RET_T
00047 F77_FUNC (zunghr, ZUNGHR) (const octave_idx_type&, const octave_idx_type&,
00048 const octave_idx_type&, Complex*,
00049 const octave_idx_type&, Complex*, Complex*,
00050 const octave_idx_type&, octave_idx_type&);
00051
00052 F77_RET_T
00053 F77_FUNC (zgebak, ZGEBAK) (F77_CONST_CHAR_ARG_DECL,
00054 F77_CONST_CHAR_ARG_DECL,
00055 const octave_idx_type&, const octave_idx_type&,
00056 const octave_idx_type&, double*,
00057 const octave_idx_type&, Complex*,
00058 const octave_idx_type&, octave_idx_type&
00059 F77_CHAR_ARG_LEN_DECL
00060 F77_CHAR_ARG_LEN_DECL);
00061 }
00062
00063 octave_idx_type
00064 ComplexHESS::init (const ComplexMatrix& a)
00065 {
00066 octave_idx_type a_nr = a.rows ();
00067 octave_idx_type a_nc = a.cols ();
00068
00069 if (a_nr != a_nc)
00070 {
00071 (*current_liboctave_error_handler)
00072 ("ComplexHESS requires square matrix");
00073 return -1;
00074 }
00075
00076 char job = 'N';
00077 char side = 'R';
00078
00079 octave_idx_type n = a_nc;
00080 octave_idx_type lwork = 32 * n;
00081 octave_idx_type info;
00082 octave_idx_type ilo;
00083 octave_idx_type ihi;
00084
00085 hess_mat = a;
00086 Complex *h = hess_mat.fortran_vec ();
00087
00088 Array<double> scale (dim_vector (n, 1));
00089 double *pscale = scale.fortran_vec ();
00090
00091 F77_XFCN (zgebal, ZGEBAL, (F77_CONST_CHAR_ARG2 (&job, 1),
00092 n, h, n, ilo, ihi, pscale, info
00093 F77_CHAR_ARG_LEN (1)));
00094
00095 Array<Complex> tau (dim_vector (n-1, 1));
00096 Complex *ptau = tau.fortran_vec ();
00097
00098 Array<Complex> work (dim_vector (lwork, 1));
00099 Complex *pwork = work.fortran_vec ();
00100
00101 F77_XFCN (zgehrd, ZGEHRD, (n, ilo, ihi, h, n, ptau, pwork, lwork, info));
00102
00103 unitary_hess_mat = hess_mat;
00104 Complex *z = unitary_hess_mat.fortran_vec ();
00105
00106 F77_XFCN (zunghr, ZUNGHR, (n, ilo, ihi, z, n, ptau, pwork,
00107 lwork, info));
00108
00109 F77_XFCN (zgebak, ZGEBAK, (F77_CONST_CHAR_ARG2 (&job, 1),
00110 F77_CONST_CHAR_ARG2 (&side, 1),
00111 n, ilo, ihi, pscale, n, z, n, info
00112 F77_CHAR_ARG_LEN (1)
00113 F77_CHAR_ARG_LEN (1)));
00114
00115
00116
00117
00118
00119 if (n > 2)
00120 for (octave_idx_type j = 0; j < a_nc; j++)
00121 for (octave_idx_type i = j+2; i < a_nr; i++)
00122 hess_mat.elem (i, j) = 0;
00123
00124 return info;
00125 }