35 #if defined (HAVE_CONFIG_H)
42 #if defined (DEBUG_EIG)
55 #if defined (DEBUG) || defined (DEBUG_SORT)
62 DEFUN (qz, args, nargout,
132 int nargin = args.length ();
136 <<
", nargout = " << nargout << std::endl;
139 if (nargin < 2 || nargin > 3 || nargout > 6)
142 bool complex_case =
true;
146 std::string opt = args(2).xstring_value (
"qz: OPT must be a string");
150 if (args(0).iscomplex () || args(1).iscomplex ())
152 warning (
"qz: ignoring 'real' option with complex matrices");
156 complex_case =
false;
158 else if (opt ==
"complex")
161 error (
"qz: OPT must be 'real' or 'complex'");
169 F77_INT nn = to_f77_int (args(0).rows ());
170 F77_INT nc = to_f77_int (args(0).columns ());
173 octave_stdout <<
"Matrix A dimensions: (" << nn <<
',' << nc <<
')'
184 if (args(0).iscomplex ())
185 caa = args(0).complex_matrix_value ();
187 aa = args(0).matrix_value ();
194 F77_INT b_nr = to_f77_int (args(1).rows ());
195 F77_INT b_nc = to_f77_int (args(1).columns ());
197 if (nn != b_nc || nn != b_nr)
203 if (args(1).iscomplex ())
204 cbb = args(1).complex_matrix_value ();
206 bb = args(1).matrix_value ();
211 Matrix QQ (nn, nn), ZZ (nn, nn),
VR (nn, nn),
VL (nn, nn);
212 RowVector alphar (nn), alphai (nn), betar (nn);
216 char comp_q = (nargout >= 3 ?
'V' :
'N');
217 char comp_z = (nargout >= 4 ?
'V' :
'N');
220 if (comp_q ==
'V' || comp_z ==
'V')
222 double *QQptr = QQ.fortran_vec ();
223 double *ZZptr = ZZ.fortran_vec ();
224 std::fill_n (QQptr, QQ.numel (), 0.0);
225 std::fill_n (ZZptr, ZZ.numel (), 0.0);
226 for (
F77_INT i = 0; i < nn; i++)
234 const char bal_job =
'P';
235 RowVector lscale (nn), rscale (nn), work (6 * nn), rwork (nn);
241 octave_stdout <<
"qz: performing balancing; CQ =\n" <<
CQ << std::endl;
243 if (args(0).isreal ())
246 if (args(1).isreal ())
256 (F77_CONST_CHAR_ARG2 (&bal_job, 1),
259 nn, ilo, ihi, lscale.fortran_vec (),
260 rscale.fortran_vec (), work.fortran_vec (), info
261 F77_CHAR_ARG_LEN (1)));
267 octave_stdout <<
"qz: performing balancing; QQ =\n" << QQ << std::endl;
271 (F77_CONST_CHAR_ARG2 (&bal_job, 1),
273 nn, ilo, ihi, lscale.fortran_vec (),
274 rscale.fortran_vec (), work.fortran_vec (), info
275 F77_CHAR_ARG_LEN (1)));
280 char qz_job = (nargout < 2 ?
'E' :
'S');
287 math::qr<ComplexMatrix> cbqr (cbb);
291 caa = (cbqr.Q ().hermitian ()) * caa;
295 (F77_CONST_CHAR_ARG2 (&comp_q, 1),
296 F77_CONST_CHAR_ARG2 (&comp_z, 1),
302 F77_CHAR_ARG_LEN (1)));
307 (F77_CONST_CHAR_ARG2 (&qz_job, 1),
308 F77_CONST_CHAR_ARG2 (&comp_q, 1),
309 F77_CONST_CHAR_ARG2 (&comp_z, 1),
321 F77_CHAR_ARG_LEN (1)));
327 (F77_CONST_CHAR_ARG2 (&bal_job, 1),
328 F77_CONST_CHAR_ARG2 (
"L", 1),
329 nn, ilo, ihi, lscale.data (), rscale.data (),
332 F77_CHAR_ARG_LEN (1)));
339 (F77_CONST_CHAR_ARG2 (&bal_job, 1),
340 F77_CONST_CHAR_ARG2 (
"R", 1),
341 nn, ilo, ihi, lscale.data (), rscale.data (),
344 F77_CHAR_ARG_LEN (1)));
351 octave_stdout <<
"qz: performing qr decomposition of bb" << std::endl;
355 math::qr<Matrix> bqr (bb);
358 octave_stdout <<
"qz: qr (bb) done; now performing qz decomposition"
368 aa = (bqr.Q ()).transpose () * aa;
386 octave_stdout <<
"qz: comp_q = " << comp_q <<
", comp_z = " << comp_z
392 (F77_CONST_CHAR_ARG2 (&comp_q, 1),
393 F77_CONST_CHAR_ARG2 (&comp_z, 1),
396 ZZ.fortran_vec (), nn, info
398 F77_CHAR_ARG_LEN (1)));
405 (F77_CONST_CHAR_ARG2 (&qz_job, 1),
406 F77_CONST_CHAR_ARG2 (&comp_q, 1),
407 F77_CONST_CHAR_ARG2 (&comp_z, 1),
409 nn, alphar.fortran_vec (), alphai.fortran_vec (),
411 ZZ.fortran_vec (), nn, work.fortran_vec (), nn, info
414 F77_CHAR_ARG_LEN (1)));
419 (F77_CONST_CHAR_ARG2 (&bal_job, 1),
420 F77_CONST_CHAR_ARG2 (
"L", 1),
421 nn, ilo, ihi, lscale.data (), rscale.data (),
422 nn, QQ.fortran_vec (), nn, info
424 F77_CHAR_ARG_LEN (1)));
428 octave_stdout <<
"qz: balancing done; QQ=\n" << QQ << std::endl;
436 (F77_CONST_CHAR_ARG2 (&bal_job, 1),
437 F77_CONST_CHAR_ARG2 (
"R", 1),
438 nn, ilo, ihi, lscale.data (), rscale.data (),
439 nn, ZZ.fortran_vec (), nn, info
441 F77_CHAR_ARG_LEN (1)));
445 octave_stdout <<
"qz: balancing done; ZZ=\n" << ZZ << std::endl;
455 char side = (nargout == 5 ?
'R' :
'B');
470 (F77_CONST_CHAR_ARG2 (&side, 1),
471 F77_CONST_CHAR_ARG2 (&howmany, 1),
479 F77_CHAR_ARG_LEN (1)));
484 octave_stdout <<
"qz: computing generalized eigenvectors" << std::endl;
492 (F77_CONST_CHAR_ARG2 (&side, 1),
493 F77_CONST_CHAR_ARG2 (&howmany, 1),
495 nn,
VL.fortran_vec (), nn,
VR.fortran_vec (), nn, nn,
496 m, work.fortran_vec (), info
498 F77_CHAR_ARG_LEN (1)));
531 retval(2) =
CQ.hermitian ();
533 retval(2) = QQ.transpose ();
574 "qz: requesting a single output argument no longer returns eigenvalues since version 9");
578 if (nargin == 2 && args(0).isreal () && args(1).isreal ()
579 && retval(0).iscomplex ())
582 "qz: returns the complex QZ by default on real matrices since version 9");
654 OCTAVE_END_NAMESPACE(
octave)
T * fortran_vec()
Size of the specified dimension.
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
#define DEFUN(name, args_name, nargout_name, doc)
Macro to define a builtin function.
void warning(const char *fmt,...)
void warning_with_id(const char *id, const char *fmt,...)
void() error(const char *fmt,...)
void disable_warning(const std::string &id)
void err_square_matrix_required(const char *fcn, const char *name)
#define F77_DBLE_CMPLX_ARG(x)
#define F77_XFCN(f, F, args)
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
void octave_print_internal(std::ostream &os, const float_display_format &fmt, bool d, bool pr_as_read_syntax)