# qz#

## Purpose#

Compute the complex QZ, or generalized Schur, form of a pair of real or complex general matrices with an option to sort the eigenvalues.

## Format#

{ S, T, Q, Z } = qz(A, B[, sort_type])#
Parameters:
• A (NxN matrix) – real or complex general matrix

• B (NxN matrix) – real or complex general matrix

• sort_type (scalar or string) –

Optional input, specifying how to sort the eigenvalues. Options include:

 1 ”udi” Absolute value of the eigenvalue less than 1.0. (Unit disk inside) 2 ”udo” Absolute value of the eigenvalue greater than or equal to 1.0. (Unit disk outside) 3 ”lhp” Value of the real portion of the eigenvalue less than 0. (Left hand plane) 4 ”rhp” Value of the real portion of the eigenvalue greater than 0. (Right hand plane) 5 ”ref” Real eigenvalues first. (Complex portion less than imagtol see remarks section) 6 ”cef” Complex eigenvalues first. (Complex portion greater than imagtol see remarks section)

Returns:
• S (NxN matrix) – Schur form of A

• T (NxN matrix) – Schur form of B

• Q (NxN matrix) – left Schur vectors

• Z (NxN matrix) – right Schur vectors

## Examples#

### Basic usage#

// For repeatable random numbers
rndseed 23434;

// Matrix dimensions
order = 4;

// Create 2 square, real matricies
A = rndn(order, order);
B = rndn(order, order);

// Perform 'QZ' decomposition
{ S, T, Q, Z } =  qz(A, B);

// Calculate generalized eigenvalues
eig_vals = diag(S) ./ diag(T);

print "Generalized eigenvalues = ";
print eig_vals;

print "Absolute value of the generalized eigenvalues = ";
print abs(eig_vals);


The above code should return the following output:

Generalized eigenvalues =

20.703871 -    1.9686543e-16i
0.16170711 -    1.6939178e-17i
-0.83402664 -       0.34681937i
-0.83402664 +       0.34681937i

Absolute value of the generalized eigenvalues =

20.703871
0.16170711
0.90326303
0.90326303


### Ordering eigenvalues#

You can order the eigenvalues, by passing in the optional third input, sort_type. The code below uses the same A and B variables made in the example above.

// Perform 'QZ' decomposition and
// reorder generalized eigenvalues, placing
// those with absolute value less than 1
// on the upper left
{ S, T, Q, Z } =  qz(A, B, "udi");

// Calculate generalized eigenvalues
eig_vals = diag(S) ./ diag(T);

print "Generalized eigenvalues = ";
print (eig_vals);

print "Absolute value of the generalized eigenvalues = ";
print abs(eig_vals);


The code above should print out the sorted eigenvalues as we see below.

Generalized eigenvalues =

0.16170711 -    1.6819697e-17i
-0.83402664 -       0.34681937i
-0.83402664 +       0.34681937i
20.703871 -    2.1311282e-14i

Absolute value of the generalized eigenvalues =

0.16170711
0.90326303
0.90326303
20.703871


## Remarks#

• The pair of matrices S and T are in generalized complex Schur form if S and T are upper triangular and the diagonal of T contains positive real numbers.

• The real generalized eigenvalues can be computed by dividing the diagonal element of S by the corresponding diagonal element of T.

• The generalized Schur vectors Q and Z are orthogonal matrices ($$Q'Q = I$$ and $$Z'Z = I$$) that reduce A and B to Schur form:

\begin{align}\begin{aligned}S = Q'A*Z T = Q'B*Z\\A = Q*S*Z' B = Q*T*Z'\end{aligned}\end{align}
• For the real generalized schur decomposition, call lapgschur().

• If only the generalized eigenvalues are needed, you can call lapgeig(), or lapgeigv().

• By default imagtol is set to 2.23e-16. If your program requires imagtol to be a different value, you may change it using sysstate() case 21, like this:

// Set imagtol to 1e-15
imagtol_org = sysstate(21, 1e-15);


Note that while the function qz() IS threadsafe, setting imagtol is NOT threadsafe. Therefore, imagtol should not be changed inside of a Format or Format block.

• This procedure calls the LAPACK routine ZGGES.