fCmplxSCHUR.cc

Go to the documentation of this file.
00001 /*
00002 
00003 Copyright (C) 1994-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 "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   // Workspace requirements may need to be fixed if any of the
00086   // following change.
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   // BWORK is not referenced for non-ordered Schur.
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 }
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines