changeset 23430:32d532b8e7d0

qz.cc: Overhaul qz function. * qz.cc: Add "#include <cmath>" and use std::abs rather than <cfloat> and fabs. Add "#include <cctype>" for access to std::toupper. Remove other #include of header files which are unused. Remove "volatile" keyword from declarations which don't require it. Use std::string::find_first_of to check OPT. Update debug code print statements. Update comments throughout code. Use std::fill_n to initialize QQ and ZZ. Rename variables ii, jj to i,j for simplicity. Rename variables compq, compv to comp_q, comp_v for clarity. Rename howmny to howmany for clarity. Wrap long lines < 80 characters.
author Rik <rik@octave.org>
date Sun, 23 Apr 2017 21:25:45 -0700
parents b976347c1341
children 39045e50ea45
files libinterp/corefcn/qz.cc
diffstat 1 files changed, 163 insertions(+), 170 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/qz.cc	Sat Apr 22 20:56:13 2017 -0700
+++ b/libinterp/corefcn/qz.cc	Sun Apr 23 21:25:45 2017 -0700
@@ -32,10 +32,15 @@
 #  include "config.h"
 #endif
 
-#include <cfloat>
+#include <cctype>
+#include <cmath>
 
-#include <iostream>
-#include <iomanip>
+#if defined (DEBUG) || defined (DEBUG_SORT) || defined (DEBUG_EIG)
+#  include <iostream>
+#  if defined (DEBUG_EIG)
+#    include <iomanip>
+#  endif
+#endif
 
 #include "f77-fcn.h"
 #include "lo-lapack-proto.h"
@@ -47,15 +52,9 @@
 #include "error.h"
 #include "errwarn.h"
 #include "ovl.h"
-#include "oct-map.h"
-#include "ov.h"
-#include "pager.h"
 #if defined (DEBUG) || defined (DEBUG_SORT)
 #  include "pr-output.h"
 #endif
-#include "symtab.h"
-#include "utils.h"
-#include "variables.h"
 
 typedef F77_INT (*sort_function) (const F77_INT& LSIZE,
                                   const double& ALPHA, const double& BETA,
@@ -63,8 +62,8 @@
 
 extern "C"
 {
-  // Van Dooren's code (netlib.org: toms/590) for reordering
-  // GEP.  Only processes Z, not Q.
+  // Van Dooren's code (netlib.org: toms/590) for reordering GEP.
+  // Only processes Z, not Q.
   F77_RET_T
   F77_FUNC (dsubsp, DSUBSP) (const F77_INT& NMAX, const F77_INT& N,
                              F77_DBLE* A, F77_DBLE* B, F77_DBLE* Z,
@@ -97,9 +96,9 @@
   F77_INT retval;
 
   if (lsize == 1)
-    retval = (fabs (alpha) < fabs (beta) ? 1 : -1);
+    retval = (std::abs (alpha) < std::abs (beta) ? 1 : -1);
   else
-    retval = (fabs (p) < 1 ? 1 : -1);
+    retval = (std::abs (p) < 1 ? 1 : -1);
 
 #if defined (DEBUG)
   std::cout << "qz: fin: retval=" << retval << std::endl;
@@ -123,9 +122,9 @@
       const double&, const double& p)
 {
   if (lsize == 1)
-    return (fabs (alpha) >= fabs (beta) ? 1 : -1);
+    return (std::abs (alpha) >= std::abs (beta) ? 1 : -1);
   else
-    return (fabs (p) >= 1 ? 1 : -1);
+    return (std::abs (p) >= 1 ? 1 : -1);
 }
 
 //FIXME: Matlab does not produce lambda as the first output argument.
@@ -235,7 +234,7 @@
 @seealso{eig, balance, lu, chol, hess, qr, qzhess, schur, svd}
 @end deftypefn */)
 {
-  volatile int nargin = args.length ();
+  int nargin = args.length ();
 
 #if defined (DEBUG)
   std::cout << "qz: nargin = " << nargin
@@ -246,30 +245,30 @@
     print_usage ();
 
   if (nargin == 3 && (nargout < 3 || nargout > 4))
-    error ("qz: invalid number of output arguments for form [3] call");
+    error ("qz: invalid number of output arguments for form 3 call");
 
 #if defined (DEBUG)
   std::cout << "qz: determine ordering option" << std::endl;
 #endif
 
   // Determine ordering option.
-  volatile char ord_job = 0;
-  static double safmin;
+  // declared volatile to avoid compiler warnings about long jumps vforks.
+  volatile char ord_job;
+  double safmin;
 
   if (nargin == 2)
     ord_job = 'N';
   else
     {
-      std::string tmp = args(2).xstring_value ("qz: OPT must be a string");
+      std::string opt = args(2).xstring_value ("qz: OPT must be a string");
 
-      if (! tmp.empty ())
-        ord_job = tmp[0];
+      if (! opt.empty ())
+        ord_job = std::toupper (opt[0]);
 
-      if (! (ord_job == 'N' || ord_job == 'n'
-             || ord_job == 'S' || ord_job == 's'
-             || ord_job == 'B' || ord_job == 'b'
-             || ord_job == '+' || ord_job == '-'))
-        error ("qz: invalid order option");
+      std::string valid_opts = "NSB+-";
+
+      if (valid_opts.find_first_of (ord_job) == std::string::npos)
+        error ("qz: invalid order option '%c'", ord_job);
 
       // overflow constant required by dlag2
       F77_FUNC (xdlamch, XDLAMCH) (F77_CONST_CHAR_ARG2 ("S", 1),
@@ -303,30 +302,26 @@
     }
 
 #if defined (DEBUG)
-  std::cout << "qz: check argument 1" << std::endl;
+  std::cout << "qz: check matrix A" << std::endl;
 #endif
 
-  // Argument 1: check if it's okay dimensioned.
+  // Matrix A: check dimensions.
   F77_INT nn = octave::to_f77_int (args(0).rows ());
   F77_INT nc = octave::to_f77_int (args(0).columns ());
 
 #if defined (DEBUG)
-  std::cout << "argument 1 dimensions: ("
-            << nn << "," << nc << ")"
-            << std::endl;
+  std::cout << "Matrix A dimensions: (" << nn << "," << nc << ")" << std::endl;
 #endif
 
-  octave_value_list retval;
-
   if (args(0).is_empty ())
     {
-      warn_empty_arg ("qz: parameter 1; continuing");
+      warn_empty_arg ("qz: A");
       return octave_value_list (2, Matrix ());
     }
   else if (nc != nn)
     err_square_matrix_required ("qz", "A");
 
-  // Argument 1: dimensions look good; get the value.
+  // Matrix A: get value.
   Matrix aa;
   ComplexMatrix caa;
 
@@ -336,7 +331,7 @@
     aa = args(0).matrix_value ();
 
 #if defined (DEBUG)
-  std::cout << "qz: check argument 2" << std::endl;
+  std::cout << "qz: check matrix B" << std::endl;
 #endif
 
   // Extract argument 2 (bb, or cbb if complex).
@@ -354,34 +349,39 @@
   else
     bb = args(1).matrix_value ();
 
-  // Both matrices loaded, now let's check what kind of arithmetic:
-  // declared volatile to avoid compiler warnings about long jumps,
-  // vforks.
+  // Both matrices loaded, now check whether to calculate complex or real val.
 
-  volatile int complex_case
+  // declared volatile to avoid compiler warnings about long jumps vforks.
+  volatile bool complex_case
     = (args(0).is_complex_type () || args(1).is_complex_type ());
 
   if (nargin == 3 && complex_case)
     error ("qz: cannot re-order complex qz decomposition");
 
-  // First, declare variables used in both the real and complex case.
-  Matrix QQ(nn,nn), ZZ(nn,nn), VR(nn,nn), VL(nn,nn);
-  RowVector alphar(nn), alphai(nn), betar(nn);
-  ComplexRowVector xalpha(nn), xbeta(nn);
-  ComplexMatrix CQ(nn,nn), CZ(nn,nn), CVR(nn,nn), CVL(nn,nn);
+  // First, declare variables used in both the real and complex cases.
+  // FIXME: There are a lot of excess variables declared.
+  //        Probably a better way to handle this.
+  Matrix QQ (nn,nn), ZZ (nn,nn), VR (nn,nn), VL (nn,nn);
+  RowVector alphar (nn), alphai (nn), betar (nn);
+  ComplexRowVector xalpha (nn), xbeta (nn);
+  ComplexMatrix CQ (nn,nn), CZ (nn,nn), CVR (nn,nn), CVL (nn,nn);
   F77_INT ilo, ihi, info;
-  char compq = (nargout >= 3 ? 'V' : 'N');
-  char compz = ((nargout >= 4 || nargin == 3)? 'V' : 'N');
+  char comp_q = (nargout >= 3 ? 'V' : 'N');
+  char comp_z = ((nargout >= 4 || nargin == 3)? 'V' : 'N');
 
-  // Initialize Q, Z to identity if we need either of them.
-  if (compq == 'V' || compz == 'V')
-    for (F77_INT ii = 0; ii < nn; ii++)
-      for (F77_INT jj = 0; jj < nn; jj++)
+  // Initialize Q, Z to identity matrix if either is needed
+  if (comp_q == 'V' || comp_z == 'V')
+    {
+      double *QQptr = QQ.fortran_vec (); 
+      double *ZZptr = ZZ.fortran_vec (); 
+      std::fill_n (QQptr, QQ.numel (), 0.0);
+      std::fill_n (ZZptr, ZZ.numel (), 0.0);
+      for (F77_INT i = 0; i < nn; i++)
         {
-          octave_quit ();
-
-          QQ(ii,jj) = ZZ(ii,jj) = (ii == jj ? 1.0 : 0.0);
+          QQ(i,i) = 1.0;
+          ZZ(i,i) = 1.0;
         }
+    }
 
   // Always perform permutation balancing.
   const char bal_job = 'P';
@@ -390,7 +390,7 @@
   if (complex_case)
     {
 #if defined (DEBUG)
-      if (compq == 'V')
+      if (comp_q == 'V')
         std::cout << "qz: performing balancing; CQ=" << std::endl
                   << CQ << std::endl;
 #endif
@@ -400,10 +400,10 @@
       if (args(1).is_real_type ())
         cbb = ComplexMatrix (bb);
 
-      if (compq == 'V')
+      if (comp_q == 'V')
         CQ = ComplexMatrix (QQ);
 
-      if (compz == 'V')
+      if (comp_z == 'V')
         CZ = ComplexMatrix (ZZ);
 
       F77_XFCN (zggbal, ZGGBAL,
@@ -417,7 +417,7 @@
   else
     {
 #if defined (DEBUG)
-      if (compq == 'V')
+      if (comp_q == 'V')
         std::cout << "qz: performing balancing; QQ=" << std::endl
                   << QQ << std::endl;
 #endif
@@ -430,11 +430,13 @@
                  F77_CHAR_ARG_LEN (1)));
     }
 
+  // Only permutation balance above is done.  Skip scaling balance.
+
+#if 0
   // Since we just want the balancing matrices, we can use dggbal
   // for both the real and complex cases; left first
 
-#if 0
-  if (compq == 'V')
+  if (comp_q == 'V')
     {
       F77_XFCN (dggbak, DGGBAK,
                 (F77_CONST_CHAR_ARG2 (&bal_job, 1),
@@ -445,13 +447,13 @@
                  F77_CHAR_ARG_LEN (1)));
 
 #if defined (DEBUG)
-      if (compq == 'V')
+      if (comp_q == 'V')
         std::cout << "qz: balancing done; QQ=" << std::endl << QQ << std::endl;
 #endif
   }
 
   // then right
-  if (compz == 'V')
+  if (comp_z == 'V')
     {
       F77_XFCN (dggbak, DGGBAK,
                 (F77_CONST_CHAR_ARG2 (&bal_job, 1),
@@ -462,14 +464,13 @@
                  F77_CHAR_ARG_LEN (1)));
 
 #if defined (DEBUG)
-      if (compz == 'V')
+      if (comp_z == 'V')
         std::cout << "qz: balancing done; ZZ=" << std::endl << ZZ << std::endl;
 #endif
     }
 #endif
 
-  static char qz_job;
-  qz_job = (nargout < 2 ? 'E' : 'S');
+  char qz_job = (nargout < 2 ? 'E' : 'S');
 
   if (complex_case)
     {
@@ -484,8 +485,8 @@
       CQ = CQ * cbqr.Q ();
 
       F77_XFCN (zgghrd, ZGGHRD,
-                (F77_CONST_CHAR_ARG2 (&compq, 1),
-                 F77_CONST_CHAR_ARG2 (&compz, 1),
+                (F77_CONST_CHAR_ARG2 (&comp_q, 1),
+                 F77_CONST_CHAR_ARG2 (&comp_z, 1),
                  nn, ilo, ihi, F77_DBLE_CMPLX_ARG (caa.fortran_vec ()),
                  nn, F77_DBLE_CMPLX_ARG (cbb.fortran_vec ()), nn,
                  F77_DBLE_CMPLX_ARG (CQ.fortran_vec ()), nn,
@@ -493,12 +494,12 @@
                  F77_CHAR_ARG_LEN (1)
                  F77_CHAR_ARG_LEN (1)));
 
-      ComplexRowVector cwork (1 * nn);
+      ComplexRowVector cwork (nn);
 
       F77_XFCN (zhgeqz, ZHGEQZ,
                 (F77_CONST_CHAR_ARG2 (&qz_job, 1),
-                 F77_CONST_CHAR_ARG2 (&compq, 1),
-                 F77_CONST_CHAR_ARG2 (&compz, 1),
+                 F77_CONST_CHAR_ARG2 (&comp_q, 1),
+                 F77_CONST_CHAR_ARG2 (&comp_z, 1),
                  nn, ilo, ihi,
                  F77_DBLE_CMPLX_ARG (caa.fortran_vec ()), nn,
                  F77_DBLE_CMPLX_ARG (cbb.fortran_vec ()), nn,
@@ -506,12 +507,13 @@
                  F77_DBLE_CMPLX_ARG (xbeta.fortran_vec ()),
                  F77_DBLE_CMPLX_ARG (CQ.fortran_vec ()), nn,
                  F77_DBLE_CMPLX_ARG (CZ.fortran_vec ()), nn,
-                 F77_DBLE_CMPLX_ARG (cwork.fortran_vec ()), nn, rwork.fortran_vec (), info
+                 F77_DBLE_CMPLX_ARG (cwork.fortran_vec ()), nn,
+                                     rwork.fortran_vec (), info
                  F77_CHAR_ARG_LEN (1)
                  F77_CHAR_ARG_LEN (1)
                  F77_CHAR_ARG_LEN (1)));
 
-      if (compq == 'V')
+      if (comp_q == 'V')
         {
           // Left eigenvector.
           F77_XFCN (zggbak, ZGGBAK,
@@ -523,9 +525,9 @@
                      F77_CHAR_ARG_LEN (1)));
         }
 
-      // Right eigenvector.
-      if (compz == 'V')
+      if (comp_z == 'V')
         {
+          // Right eigenvector.
           F77_XFCN (zggbak, ZGGBAK,
                     (F77_CONST_CHAR_ARG2 (&bal_job, 1),
                      F77_CONST_CHAR_ARG2 ("R", 1),
@@ -539,14 +541,14 @@
   else
     {
 #if defined (DEBUG)
-      std::cout << "qz: peforming qr decomposition of bb" << std::endl;
+      std::cout << "qz: performing qr decomposition of bb" << std::endl;
 #endif
 
       // Compute the QR factorization of bb.
       octave::math::qr<Matrix> bqr (bb);
 
 #if defined (DEBUG)
-      std::cout << "qz: qr (bb) done; now peforming qz decomposition"
+      std::cout << "qz: qr (bb) done; now performing qz decomposition"
                 << std::endl;
 #endif
 
@@ -562,11 +564,11 @@
       std::cout << "qz: updated aa " << std::endl;
       std::cout << "bqr.Q () = " << std::endl << bqr.Q () << std::endl;
 
-      if (compq == 'V')
+      if (comp_q == 'V')
         std::cout << "QQ =" << QQ << std::endl;
 #endif
 
-      if (compq == 'V')
+      if (comp_q == 'V')
         QQ = QQ * bqr.Q ();
 
 #if defined (DEBUG)
@@ -574,28 +576,28 @@
 #endif
 
 #if defined (DEBUG)
-      std::cout << "qz: compq = " << compq << ", compz = " << compz
+      std::cout << "qz: comp_q = " << comp_q << ", comp_z = " << comp_z
                 << std::endl;
 #endif
 
       // Reduce to generalized Hessenberg form.
       F77_XFCN (dgghrd, DGGHRD,
-                (F77_CONST_CHAR_ARG2 (&compq, 1),
-                 F77_CONST_CHAR_ARG2 (&compz, 1),
+                (F77_CONST_CHAR_ARG2 (&comp_q, 1),
+                 F77_CONST_CHAR_ARG2 (&comp_z, 1),
                  nn, ilo, ihi, aa.fortran_vec (),
                  nn, bb.fortran_vec (), nn, QQ.fortran_vec (), nn,
                  ZZ.fortran_vec (), nn, info
                  F77_CHAR_ARG_LEN (1)
                  F77_CHAR_ARG_LEN (1)));
 
-      // Check if just computing generalized eigenvalues or if we're
-      // actually computing the decomposition.
+      // Check if just computing generalized eigenvalues,
+      // or if we're actually computing the decomposition.
 
       // Reduce to generalized Schur form.
       F77_XFCN (dhgeqz, DHGEQZ,
                 (F77_CONST_CHAR_ARG2 (&qz_job, 1),
-                 F77_CONST_CHAR_ARG2 (&compq, 1),
-                 F77_CONST_CHAR_ARG2 (&compz, 1),
+                 F77_CONST_CHAR_ARG2 (&comp_q, 1),
+                 F77_CONST_CHAR_ARG2 (&comp_z, 1),
                  nn, ilo, ihi, aa.fortran_vec (), nn, bb.fortran_vec (),
                  nn, alphar.fortran_vec (), alphai.fortran_vec (),
                  betar.fortran_vec (), QQ.fortran_vec (), nn,
@@ -604,7 +606,7 @@
                  F77_CHAR_ARG_LEN (1)
                  F77_CHAR_ARG_LEN (1)));
 
-      if (compq == 'V')
+      if (comp_q == 'V')
         {
           F77_XFCN (dggbak, DGGBAK,
                     (F77_CONST_CHAR_ARG2 (&bal_job, 1),
@@ -615,14 +617,14 @@
                      F77_CHAR_ARG_LEN (1)));
 
 #if defined (DEBUG)
-          if (compq == 'V')
+          if (comp_q == 'V')
             std::cout << "qz: balancing done; QQ=" << std::endl
                       << QQ << std::endl;
 #endif
         }
 
       // then right
-      if (compz == 'V')
+      if (comp_z == 'V')
         {
           F77_XFCN (dggbak, DGGBAK,
                     (F77_CONST_CHAR_ARG2 (&bal_job, 1),
@@ -633,7 +635,7 @@
                      F77_CHAR_ARG_LEN (1)));
 
 #if defined (DEBUG)
-          if (compz == 'V')
+          if (comp_z == 'V')
             std::cout << "qz: balancing done; ZZ=" << std::endl
                       << ZZ << std::endl;
 #endif
@@ -642,11 +644,11 @@
     }
 
   // Order the QZ decomposition?
-  if (! (ord_job == 'N' || ord_job == 'n'))
+  if (ord_job != 'N')
     {
       if (complex_case)
         // Probably not needed, but better be safe.
-        error ("qz: cannot re-order complex qz decomposition");
+        error ("qz: cannot re-order complex QZ decomposition");
 
 #if defined (DEBUG_SORT)
       std::cout << "qz: ordering eigenvalues: ord_job = "
@@ -660,12 +662,10 @@
       switch (ord_job)
         {
         case 'S':
-        case 's':
           sort_test = &fin;
           break;
 
         case 'B':
-        case 'b':
           sort_test = &fout;
           break;
 
@@ -678,8 +678,8 @@
           break;
 
         default:
-          // Invalid order option (should never happen, since we
-          // checked the options at the top).
+          // Invalid order option
+          // (should never happen since options were checked at the top).
           panic_impossible ();
           break;
         }
@@ -698,7 +698,7 @@
       octave_print_internal (std::cout, aa, 0);
       std::cout << std::endl << "bb="  << std::endl;
       octave_print_internal (std::cout, bb, 0);
-      if (compz == 'V')
+      if (comp_z == 'V')
         {
           std::cout << std::endl << "ZZ="  << std::endl;
           octave_print_internal (std::cout, ZZ, 0);
@@ -727,7 +727,7 @@
       octave_print_internal (std::cout, aa, 0);
       std::cout << std::endl << "bb="  << std::endl;
       octave_print_internal (std::cout, bb, 0);
-      if (compz == 'V')
+      if (comp_z == 'V')
         {
           std::cout << std::endl << "ZZ="  << std::endl;
           octave_print_internal (std::cout, ZZ, 0);
@@ -736,21 +736,21 @@
 #endif
 
       // Manually update alphar, alphai, betar.
-      static F77_INT jj;
+      static F77_INT j;
 
-      jj = 0;
-      while (jj < nn)
+      j = 0;
+      while (j < nn)
         {
 #if defined (DEBUG_EIG)
-          std::cout << "computing gen eig #" << jj << std::endl;
+          std::cout << "computing gen eig #" << j << std::endl;
 #endif
 
           // Number of zeros in this block.
           static F77_INT zcnt;
 
-          if (jj == (nn-1))
+          if (j == (nn-1))
             zcnt = 1;
-          else if (aa(jj+1,jj) == 0)
+          else if (aa(j+1,j) == 0)
             zcnt = 1;
           else zcnt = 2;
 
@@ -759,16 +759,16 @@
               // Real zero.
 #if defined (DEBUG_EIG)
               std::cout << "  single gen eig:" << std::endl;
-              std::cout << "  alphar(" << jj << ") = " << aa(jj,jj)
+              std::cout << "  alphar(" << j << ") = " << aa(j,j)
                         << std::endl;
-              std::cout << "  betar(" << jj << ") = " << bb(jj,jj)
+              std::cout << "  betar(" << j << ") = " << bb(j,j)
                         << std::endl;
-              std::cout << "  alphai(" << jj << ") = 0" << std::endl;
+              std::cout << "  alphai(" << j << ") = 0" << std::endl;
 #endif
 
-              alphar(jj) = aa(jj,jj);
-              alphai(jj) = 0;
-              betar(jj) = bb(jj,jj);
+              alphar(j) = aa(j,j);
+              alphai(j) = 0;
+              betar(j) = bb(j,j);
             }
           else
             {
@@ -779,9 +779,9 @@
                         << setiosflags (std::ios::scientific)
                         << safmin << std::endl;
 
-              for (F77_INT idr = jj; idr <= jj+1; idr++)
+              for (F77_INT idr = j; idr <= j+1; idr++)
                 {
-                  for (F77_INT idc = jj; idc <= jj+1; idc++)
+                  for (F77_INT idc = j; idc <= j+1; idc++)
                     {
                       std::cout << "aa(" << idr << "," << idc << ")="
                                 << aa(idr,idc) << std::endl;
@@ -792,11 +792,11 @@
 #endif
 
               // FIXME: probably should be using
-              // fortran_vec instead of &aa(jj,jj) here.
+              // fortran_vec instead of &aa(j,j) here.
 
               double scale1, scale2, wr1, wr2, wi;
-              const double *aa_ptr = aa.data () + jj * nn + jj;
-              const double *bb_ptr = bb.data () + jj * nn + jj;
+              const double *aa_ptr = aa.data () + j * nn + j;
+              const double *bb_ptr = bb.data () + j * nn + j;
               F77_XFCN (dlag2, DLAG2,
                         (aa_ptr, nn, bb_ptr, nn, safmin,
                          scale1, scale2, wr1, wr2, wi));
@@ -811,23 +811,23 @@
               // Just to be safe, check if it's a real pair.
               if (wi == 0)
                 {
-                  alphar(jj) = wr1;
-                  alphai(jj) = 0;
-                  betar(jj) = scale1;
-                  alphar(jj+1) = wr2;
-                  alphai(jj+1) = 0;
-                  betar(jj+1) = scale2;
+                  alphar(j) = wr1;
+                  alphai(j) = 0;
+                  betar(j) = scale1;
+                  alphar(j+1) = wr2;
+                  alphai(j+1) = 0;
+                  betar(j+1) = scale2;
                 }
               else
                 {
-                  alphar(jj) = alphar(jj+1) = wr1;
-                  alphai(jj) = -(alphai(jj+1) = wi);
-                  betar(jj)  = betar(jj+1) = scale1;
+                  alphar(j) = alphar(j+1) = wr1;
+                  alphai(j) = -(alphai(j+1) = wi);
+                  betar(j)  = betar(j+1) = scale1;
                 }
             }
 
           // Advance past this block.
-          jj += zcnt;
+          j += zcnt;
         }
 
 #if defined (DEBUG_SORT)
@@ -836,7 +836,7 @@
       std::cout << std::endl << "bb="  << std::endl;
       octave_print_internal (std::cout, bb, 0);
 
-      if (compz == 'V')
+      if (comp_z == 'V')
         {
           std::cout << std::endl << "ZZ="  << std::endl;
           octave_print_internal (std::cout, ZZ, 0);
@@ -853,23 +853,17 @@
 #endif
     }
 
-  // Compute generalized eigenvalues?
+  // Compute the generalized eigenvalues as well?
   ComplexColumnVector gev;
 
   if (nargout < 2 || nargout == 7 || (nargin == 3 && nargout == 4))
     {
       if (complex_case)
         {
-          F77_INT cnt = 0;
-
-          for (F77_INT ii = 0; ii < nn; ii++)
-            cnt++;
+          ComplexColumnVector tmp (nn);
 
-          ComplexColumnVector tmp (cnt);
-
-          cnt = 0;
-          for (F77_INT ii = 0; ii < nn; ii++)
-            tmp(cnt++) = xalpha(ii) / xbeta(ii);
+          for (F77_INT i = 0; i < nn; i++)
+            tmp(i) = xalpha(i) / xbeta(i);
 
           gev = tmp;
         }
@@ -880,18 +874,14 @@
 #endif
 
           // Return finite generalized eigenvalues.
-          F77_INT cnt = 0;
-
-          for (F77_INT ii = 0; ii < nn; ii++)
-            if (betar(ii) != 0)
-              cnt++;
+          ComplexColumnVector tmp (nn);
 
-          ComplexColumnVector tmp (cnt);
+          F77_INT cnt = 0;
+          for (F77_INT i = 0; i < nn; i++)
+            if (betar(i) != 0)
+              tmp(cnt++) = Complex (alphar(i), alphai(i)) / betar(i);
 
-          cnt = 0;
-          for (F77_INT ii = 0; ii < nn; ii++)
-            if (betar(ii) != 0)
-              tmp(cnt++) = Complex(alphar(ii), alphai(ii))/betar(ii);
+          tmp.resize (cnt);  // Trim vector to number of return values
 
           gev = tmp;
         }
@@ -903,7 +893,7 @@
       // Which side to compute?
       char side = (nargout == 5 ? 'R' : 'B');
       // Compute all of them and backtransform
-      char howmny = 'B';
+      char howmany = 'B';
       // Dummy pointer; select is not used.
       F77_INT *select = 0;
 
@@ -917,12 +907,13 @@
 
           F77_XFCN (ztgevc, ZTGEVC,
                     (F77_CONST_CHAR_ARG2 (&side, 1),
-                     F77_CONST_CHAR_ARG2 (&howmny, 1),
+                     F77_CONST_CHAR_ARG2 (&howmany, 1),
                      select, nn, F77_DBLE_CMPLX_ARG (caa.fortran_vec ()), nn,
                      F77_DBLE_CMPLX_ARG (cbb.fortran_vec ()),
                      nn, F77_DBLE_CMPLX_ARG (CVL.fortran_vec ()), nn,
                      F77_DBLE_CMPLX_ARG (CVR.fortran_vec ()), nn, nn,
-                     m, F77_DBLE_CMPLX_ARG (cwork2.fortran_vec ()), rwork2.fortran_vec (), info
+                     m, F77_DBLE_CMPLX_ARG (cwork2.fortran_vec ()),
+                     rwork2.fortran_vec (), info
                      F77_CHAR_ARG_LEN (1)
                      F77_CHAR_ARG_LEN (1)));
         }
@@ -938,7 +929,7 @@
 
           F77_XFCN (dtgevc, DTGEVC,
                     (F77_CONST_CHAR_ARG2 (&side, 1),
-                     F77_CONST_CHAR_ARG2 (&howmny, 1),
+                     F77_CONST_CHAR_ARG2 (&howmany, 1),
                      select, nn, aa.fortran_vec (), nn, bb.fortran_vec (),
                      nn, VL.fortran_vec (), nn, VR.fortran_vec (), nn, nn,
                      m, work.fortran_vec (), info
@@ -946,9 +937,9 @@
                      F77_CHAR_ARG_LEN (1)));
 
           // Now construct the complex form of VV, WW.
-          F77_INT jj = 0;
+          F77_INT j = 0;
 
-          while (jj < nn)
+          while (j < nn)
             {
               octave_quit ();
 
@@ -957,57 +948,59 @@
               // Column increment; assume complex eigenvalue.
               int cinc = 2;
 
-              if (jj == (nn-1))
+              if (j == (nn-1))
                 // Single column.
                 cinc = 1;
-              else if (aa(jj+1,jj) == 0)
+              else if (aa(j+1,j) == 0)
                 cinc = 1;
 
               // Now copy the eigenvector (s) to CVR, CVL.
               if (cinc == 1)
                 {
-                  for (F77_INT ii = 0; ii < nn; ii++)
-                    CVR(ii,jj) = VR(ii,jj);
+                  for (F77_INT i = 0; i < nn; i++)
+                    CVR(i,j) = VR(i,j);
 
                   if (side == 'B')
-                    for (F77_INT ii = 0; ii < nn; ii++)
-                      CVL(ii,jj) = VL(ii,jj);
+                    for (F77_INT i = 0; i < nn; i++)
+                      CVL(i,j) = VL(i,j);
                 }
               else
                 {
                   // Double column; complex vector.
 
-                  for (F77_INT ii = 0; ii < nn; ii++)
+                  for (F77_INT i = 0; i < nn; i++)
                     {
-                      CVR(ii,jj) = Complex (VR(ii,jj), VR(ii,jj+1));
-                      CVR(ii,jj+1) = Complex (VR(ii,jj), -VR(ii,jj+1));
+                      CVR(i,j) = Complex (VR(i,j), VR(i,j+1));
+                      CVR(i,j+1) = Complex (VR(i,j), -VR(i,j+1));
                     }
 
                   if (side == 'B')
-                    for (F77_INT ii = 0; ii < nn; ii++)
+                    for (F77_INT i = 0; i < nn; i++)
                       {
-                        CVL(ii,jj) = Complex (VL(ii,jj), VL(ii,jj+1));
-                        CVL(ii,jj+1) = Complex (VL(ii,jj), -VL(ii,jj+1));
+                        CVL(i,j) = Complex (VL(i,j), VL(i,j+1));
+                        CVL(i,j+1) = Complex (VL(i,j), -VL(i,j+1));
                       }
                 }
 
               // Advance to next eigenvectors (if any).
-              jj += cinc;
+              j += cinc;
             }
         }
     }
 
+  octave_value_list retval (nargout);
+
   switch (nargout)
     {
     case 7:
       retval(6) = gev;
 
     case 6:
-      // Return eigenvectors.
+      // Return left eigenvectors.
       retval(5) = CVL;
 
     case 5:
-      // Return eigenvectors.
+      // Return right eigenvectors.
       retval(4) = CVR;
 
     case 4:
@@ -1015,7 +1008,7 @@
         {
 #if defined (DEBUG)
           std::cout << "qz: sort: retval(3) = gev = " << std::endl;
-          octave_print_internal (std::cout, gev);
+          octave_print_internal (std::cout, ComplexMatrix (gev));
           std::cout << std::endl;
 #endif
           retval(3) = gev;
@@ -1101,7 +1094,7 @@
 %!assert (qz (a,b), 1)
 %!assert (isempty (qz (a,c)))
 
-## Exaple 7.7.3 in Golub & Van Loan
+## Example 7.7.3 in Golub & Van Loan
 %!test
 %! a = [ 10  1  2;
 %!        1  2 -1;
@@ -1120,6 +1113,6 @@
 %! A = [0, 0, -1, 0; 1, 0, 0, 0; -1, 0, -2, -1; 0, -1, 1, 0];
 %! B = [0, 0, 0, 0; 0, 1, 0, 0; 0, 0, 1, 0; 0, 0, 0, 1];
 %! [AA, BB, Q, Z1] = qz (A, B);
-%! [AA, BB, Z2] = qz (A, B, '-');
+%! [AA, BB, Z2] = qz (A, B, "-");
 %! assert (Z1, Z2);
 */