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 "fCmplxSCHUR.h"
00028 #include "f77-fcn.h"
00029 #include "lo-error.h"
00030 #include "oct-locbuf.h"
00031
00032 extern "C"
00033 {
00034 F77_RET_T
00035 F77_FUNC (cgeesx, CGEESX) (F77_CONST_CHAR_ARG_DECL,
00036 F77_CONST_CHAR_ARG_DECL,
00037 FloatComplexSCHUR::select_function,
00038 F77_CONST_CHAR_ARG_DECL,
00039 const octave_idx_type&, FloatComplex*,
00040 const octave_idx_type&, octave_idx_type&,
00041 FloatComplex*, FloatComplex*,
00042 const octave_idx_type&, float&, float&,
00043 FloatComplex*, const octave_idx_type&,
00044 float*, octave_idx_type*, octave_idx_type&
00045 F77_CHAR_ARG_LEN_DECL
00046 F77_CHAR_ARG_LEN_DECL
00047 F77_CHAR_ARG_LEN_DECL);
00048 F77_RET_T
00049 F77_FUNC (crsf2csf, CRSF2CSF) (const octave_idx_type&, FloatComplex *,
00050 FloatComplex *, float *, float *);
00051 }
00052
00053 static octave_idx_type
00054 select_ana (const FloatComplex& a)
00055 {
00056 return a.real () < 0.0;
00057 }
00058
00059 static octave_idx_type
00060 select_dig (const FloatComplex& a)
00061 {
00062 return (abs (a) < 1.0);
00063 }
00064
00065 octave_idx_type
00066 FloatComplexSCHUR::init (const FloatComplexMatrix& a, const std::string& ord,
00067 bool calc_unitary)
00068 {
00069 octave_idx_type a_nr = a.rows ();
00070 octave_idx_type a_nc = a.cols ();
00071
00072 if (a_nr != a_nc)
00073 {
00074 (*current_liboctave_error_handler)
00075 ("FloatComplexSCHUR requires square matrix");
00076 return -1;
00077 }
00078 else if (a_nr == 0)
00079 {
00080 schur_mat.clear ();
00081 unitary_mat.clear ();
00082 return 0;
00083 }
00084
00085
00086
00087
00088 char jobvs;
00089 char sense = 'N';
00090 char sort = 'N';
00091
00092 if (calc_unitary)
00093 jobvs = 'V';
00094 else
00095 jobvs = 'N';
00096
00097 char ord_char = ord.empty () ? 'U' : ord[0];
00098
00099 if (ord_char == 'A' || ord_char == 'D' || ord_char == 'a' || ord_char == 'd')
00100 sort = 'S';
00101
00102 if (ord_char == 'A' || ord_char == 'a')
00103 selector = select_ana;
00104 else if (ord_char == 'D' || ord_char == 'd')
00105 selector = select_dig;
00106 else
00107 selector = 0;
00108
00109 octave_idx_type n = a_nc;
00110 octave_idx_type lwork = 8 * n;
00111 octave_idx_type info;
00112 octave_idx_type sdim;
00113 float rconde;
00114 float rcondv;
00115
00116 schur_mat = a;
00117 if (calc_unitary)
00118 unitary_mat.clear (n, n);
00119
00120 FloatComplex *s = schur_mat.fortran_vec ();
00121 FloatComplex *q = unitary_mat.fortran_vec ();
00122
00123 Array<float> rwork (dim_vector (n, 1));
00124 float *prwork = rwork.fortran_vec ();
00125
00126 Array<FloatComplex> w (dim_vector (n, 1));
00127 FloatComplex *pw = w.fortran_vec ();
00128
00129 Array<FloatComplex> work (dim_vector (lwork, 1));
00130 FloatComplex *pwork = work.fortran_vec ();
00131
00132
00133 octave_idx_type ntmp = (ord_char == 'N' || ord_char == 'n') ? 0 : n;
00134 Array<octave_idx_type> bwork (dim_vector (ntmp, 1));
00135 octave_idx_type *pbwork = bwork.fortran_vec ();
00136
00137 F77_XFCN (cgeesx, CGEESX, (F77_CONST_CHAR_ARG2 (&jobvs, 1),
00138 F77_CONST_CHAR_ARG2 (&sort, 1),
00139 selector,
00140 F77_CONST_CHAR_ARG2 (&sense, 1),
00141 n, s, n, sdim, pw, q, n, rconde, rcondv,
00142 pwork, lwork, prwork, pbwork, info
00143 F77_CHAR_ARG_LEN (1)
00144 F77_CHAR_ARG_LEN (1)
00145 F77_CHAR_ARG_LEN (1)));
00146
00147 return info;
00148 }
00149
00150 FloatComplexSCHUR::FloatComplexSCHUR (const FloatComplexMatrix& s,
00151 const FloatComplexMatrix& u)
00152 : schur_mat (s), unitary_mat (u), selector (0)
00153 {
00154 octave_idx_type n = s.rows ();
00155 if (s.columns () != n || u.rows () != n || u.columns () != n)
00156 (*current_liboctave_error_handler)
00157 ("schur: inconsistent matrix dimensions");
00158 }
00159
00160 FloatComplexSCHUR::FloatComplexSCHUR (const FloatSCHUR& s)
00161 : schur_mat (s.schur_matrix ()), unitary_mat (s.unitary_matrix ()),
00162 selector (0)
00163 {
00164 octave_idx_type n = schur_mat.rows ();
00165 if (n > 0)
00166 {
00167 OCTAVE_LOCAL_BUFFER (float, c, n-1);
00168 OCTAVE_LOCAL_BUFFER (float, sx, n-1);
00169
00170 F77_XFCN (crsf2csf, CRSF2CSF, (n, schur_mat.fortran_vec (),
00171 unitary_mat.fortran_vec (), c, sx));
00172 }
00173 }