35 #if defined (HAVE_CONFIG_H)
42 #if defined (DEBUG_EIG)
55 #if defined (DEBUG) || defined (DEBUG_SORT)
65 DEFUN (qz, args, nargout,
173 int nargin = args.length ();
177 <<
", nargout = " << nargout << std::endl;
180 if (nargin < 2 || nargin > 3 || nargout > 7)
183 if (nargin == 3 && (nargout < 3 || nargout > 4))
184 error (
"qz: invalid number of output arguments for form 3 call");
187 octave_stdout <<
"qz: determine ordering option" << std::endl;
197 std::string opt = args(2).xstring_value (
"qz: OPT must be a string");
200 error (
"qz: OPT must be a non-empty string");
202 ord_job = std::toupper (opt[0]);
204 std::string valid_opts =
"NSB+-";
206 if (valid_opts.find_first_of (ord_job) == std::string::npos)
207 error (
"qz: invalid order option '%c'", ord_job);
212 F77_CHAR_ARG_LEN (1));
214 #if defined (DEBUG_EIG)
216 << setiosflags (std::ios::scientific)
217 << safmin << std::endl;
224 #if defined (DEBUG_EIG)
231 F77_CHAR_ARG_LEN (1));
233 #if defined (DEBUG_EIG)
235 << setiosflags (std::ios::scientific)
236 << safmin << std::endl;
246 F77_INT nn = to_f77_int (args(0).rows ());
247 F77_INT nc = to_f77_int (args(0).columns ());
254 if (args(0).isempty ())
266 if (args(0).iscomplex ())
267 caa = args(0).complex_matrix_value ();
269 aa = args(0).matrix_value ();
276 F77_INT b_nr = to_f77_int (args(1).rows ());
277 F77_INT b_nc = to_f77_int (args(1).columns ());
279 if (
nn != b_nc ||
nn != b_nr)
285 if (args(1).iscomplex ())
286 cbb = args(1).complex_matrix_value ();
288 bb = args(1).matrix_value ();
292 bool complex_case = (args(0).iscomplex () || args(1).iscomplex ());
294 if (nargin == 3 && complex_case)
295 error (
"qz: cannot re-order complex qz decomposition");
305 char comp_q = (nargout >= 3 ?
'V' :
'N');
306 char comp_z = ((nargout >= 4 || nargin == 3)?
'V' :
'N');
309 if (comp_q ==
'V' || comp_z ==
'V')
311 double *QQptr = QQ.fortran_vec ();
312 double *ZZptr = ZZ.fortran_vec ();
313 std::fill_n (QQptr, QQ.numel (), 0.0);
314 std::fill_n (ZZptr, ZZ.numel (), 0.0);
323 const char bal_job =
'P';
330 octave_stdout <<
"qz: performing balancing; CQ =\n" <<
CQ << std::endl;
332 if (args(0).isreal ())
335 if (args(1).isreal ())
345 (F77_CONST_CHAR_ARG2 (&bal_job, 1),
348 nn, ilo, ihi, lscale.fortran_vec (),
349 rscale.fortran_vec (), work.fortran_vec (), info
350 F77_CHAR_ARG_LEN (1)));
356 octave_stdout <<
"qz: performing balancing; QQ =\n" << QQ << std::endl;
360 (F77_CONST_CHAR_ARG2 (&bal_job, 1),
362 nn, ilo, ihi, lscale.fortran_vec (),
363 rscale.fortran_vec (), work.fortran_vec (), info
364 F77_CHAR_ARG_LEN (1)));
376 (F77_CONST_CHAR_ARG2 (&bal_job, 1),
377 F77_CONST_CHAR_ARG2 (
"L", 1),
378 nn, ilo, ihi, lscale.data (), rscale.data (),
379 nn, QQ.fortran_vec (),
nn, info
381 F77_CHAR_ARG_LEN (1)));
385 octave_stdout <<
"qz: balancing done; QQ =\n" << QQ << std::endl;
393 (F77_CONST_CHAR_ARG2 (&bal_job, 1),
394 F77_CONST_CHAR_ARG2 (
"R", 1),
395 nn, ilo, ihi, lscale.data (), rscale.data (),
396 nn, ZZ.fortran_vec (),
nn, info
398 F77_CHAR_ARG_LEN (1)));
402 octave_stdout <<
"qz: balancing done; ZZ=\n" << ZZ << std::endl;
407 char qz_job = (nargout < 2 ?
'E' :
'S');
414 math::qr<ComplexMatrix> cbqr (cbb);
418 caa = (cbqr.Q ().hermitian ()) * caa;
422 (F77_CONST_CHAR_ARG2 (&comp_q, 1),
423 F77_CONST_CHAR_ARG2 (&comp_z, 1),
429 F77_CHAR_ARG_LEN (1)));
434 (F77_CONST_CHAR_ARG2 (&qz_job, 1),
435 F77_CONST_CHAR_ARG2 (&comp_q, 1),
436 F77_CONST_CHAR_ARG2 (&comp_z, 1),
448 F77_CHAR_ARG_LEN (1)));
454 (F77_CONST_CHAR_ARG2 (&bal_job, 1),
455 F77_CONST_CHAR_ARG2 (
"L", 1),
456 nn, ilo, ihi, lscale.data (), rscale.data (),
459 F77_CHAR_ARG_LEN (1)));
466 (F77_CONST_CHAR_ARG2 (&bal_job, 1),
467 F77_CONST_CHAR_ARG2 (
"R", 1),
468 nn, ilo, ihi, lscale.data (), rscale.data (),
471 F77_CHAR_ARG_LEN (1)));
478 octave_stdout <<
"qz: performing qr decomposition of bb" << std::endl;
482 math::qr<Matrix> bqr (bb);
485 octave_stdout <<
"qz: qr (bb) done; now performing qz decomposition"
513 octave_stdout <<
"qz: comp_q = " << comp_q <<
", comp_z = " << comp_z
519 (F77_CONST_CHAR_ARG2 (&comp_q, 1),
520 F77_CONST_CHAR_ARG2 (&comp_z, 1),
523 ZZ.fortran_vec (),
nn, info
525 F77_CHAR_ARG_LEN (1)));
532 (F77_CONST_CHAR_ARG2 (&qz_job, 1),
533 F77_CONST_CHAR_ARG2 (&comp_q, 1),
534 F77_CONST_CHAR_ARG2 (&comp_z, 1),
536 nn, alphar.fortran_vec (), alphai.fortran_vec (),
538 ZZ.fortran_vec (),
nn, work.fortran_vec (),
nn, info
541 F77_CHAR_ARG_LEN (1)));
546 (F77_CONST_CHAR_ARG2 (&bal_job, 1),
547 F77_CONST_CHAR_ARG2 (
"L", 1),
548 nn, ilo, ihi, lscale.data (), rscale.data (),
549 nn, QQ.fortran_vec (),
nn, info
551 F77_CHAR_ARG_LEN (1)));
555 octave_stdout <<
"qz: balancing done; QQ=\n" << QQ << std::endl;
563 (F77_CONST_CHAR_ARG2 (&bal_job, 1),
564 F77_CONST_CHAR_ARG2 (
"R", 1),
565 nn, ilo, ihi, lscale.data (), rscale.data (),
566 nn, ZZ.fortran_vec (),
nn, info
568 F77_CHAR_ARG_LEN (1)));
572 octave_stdout <<
"qz: balancing done; ZZ=\n" << ZZ << std::endl;
583 error (
"qz: cannot re-order complex QZ decomposition");
585 #if defined (DEBUG_SORT)
587 << ord_job << std::endl;
592 for (
int j = 0; j <
nn; j++)
597 select(j) = alphar(j)*alphar(j) + alphai(j)*alphai(j) < betar(j)*betar(j);
601 select(j) = alphar(j)*alphar(j) + alphai(j)*alphai(j) >= betar(j)*betar(j);
605 select(j) = alphar(j) * betar(j) >= 0;
609 select(j) = alphar(j) * betar(j) < 0;
621 F77_INT ijob = 0, mm, lrwork3 = 4*
nn+16, liwork =
nn;
631 alphar.fortran_vec (),
632 alphai.fortran_vec (),
635 ZZ.fortran_vec (),
nn,
643 #if defined (DEBUG_SORT)
667 if (nargout < 2 || nargout == 7 || (nargin == 3 && nargout == 4))
674 tmp(i) = xalpha(i) / xbeta(i);
681 octave_stdout <<
"qz: computing generalized eigenvalues" << std::endl;
690 tmp(i) =
Complex (alphar(i), alphai(i)) / betar(i);
703 char side = (nargout == 5 ?
'R' :
'B');
718 (F77_CONST_CHAR_ARG2 (&side, 1),
719 F77_CONST_CHAR_ARG2 (&howmany, 1),
727 F77_CHAR_ARG_LEN (1)));
732 octave_stdout <<
"qz: computing generalized eigenvectors" << std::endl;
740 (F77_CONST_CHAR_ARG2 (&side, 1),
741 F77_CONST_CHAR_ARG2 (&howmany, 1),
744 m, work.fortran_vec (), info
746 F77_CHAR_ARG_LEN (1)));
763 else if (aa(j+1, j) == 0)
770 CVR(i, j) =
VR(i, j);
774 CVL(i, j) =
VL(i, j);
848 retval(2) =
CQ.hermitian ();
850 retval(2) = QQ.transpose ();
886 octave_stdout <<
"qz: retval(0) = gev = " << gev << std::endl;
892 error (
"qz: too many return arguments");
N Dimensional Array with copy-on-write semantics.
OCTARRAY_API T * fortran_vec(void)
Size of the specified dimension.
Vector representing the dimensions (size) of an Array.
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
OCTINTERP_API void print_usage(void)
#define DEFUN(name, args_name, nargout_name, doc)
Macro to define a builtin function.
void error(const char *fmt,...)
#define panic_impossible()
void err_square_matrix_required(const char *fcn, const char *name)
void warn_empty_arg(const char *name)
#define F77_DBLE_CMPLX_ARG(x)
#define F77_XFCN(f, F, args)
octave_f77_int_type F77_LOGICAL
octave_f77_int_type F77_INT
void err_nonconformant(const char *op, octave_idx_type op1_len, octave_idx_type op2_len)
F77_RET_T F77_INT const F77_INT F77_DBLE const F77_INT F77_DBLE const F77_INT F77_DBLE const F77_INT F77_DBLE * VR
F77_RET_T const F77_INT const F77_INT const F77_INT F77_DBLE_CMPLX const F77_INT F77_DBLE_CMPLX const F77_INT F77_DBLE_CMPLX F77_DBLE_CMPLX F77_DBLE_CMPLX const F77_INT F77_DBLE_CMPLX * CZ
F77_RET_T const F77_INT const F77_INT const F77_INT F77_DBLE_CMPLX const F77_INT F77_DBLE_CMPLX const F77_INT F77_DBLE_CMPLX F77_DBLE_CMPLX F77_DBLE_CMPLX * CQ
F77_RET_T F77_INT const F77_INT F77_DBLE const F77_INT F77_DBLE const F77_INT F77_DBLE * VL
class OCTAVE_API ComplexMatrix
std::complex< double > Complex
void octave_print_internal(std::ostream &os, const float_display_format &fmt, bool d, bool pr_as_read_syntax)
static void transpose(octave_idx_type N, const octave_idx_type *ridx, const octave_idx_type *cidx, octave_idx_type *ridx2, octave_idx_type *cidx2)
subroutine xdlamch(cmach, retval)
F77_RET_T F77_FUNC(xerbla, XERBLA)(F77_CONST_CHAR_ARG_DEF(s_arg