S = Matrices.realSchur(A); (S, QZ, alphaReal, alphaImag) = Matrices.realSchur(A);
Function realSchur calculates the real Schur form of a real square matrix A, i.e.
A = QZ*S*transpose(QZ)
with the real nxn matrices S and QZ. S is a block upper triangular matrix with 1x1 and 2x2 blocks in the diagonal. QZ is an orthogonal matrix. The 1x1 blocks contains the real eigenvalues of A. The 2x2 blocks [s11, s12; s21, s11] represents the conjugated complex pairs of eigenvalues, whereas the real parts of the eigenvalues are the elements of the diagonal (s11). The imaginary parts are the positive and negative square roots of the product of the two elements s12 and s21 (imag = +-sqrt(s12*s21)).
The calculation in lapack.dgees is performed stepwise, i.e., using the internal methods of balancing and scaling of dgees.
Real A[3,3] = [1, 2, 3; 4, 5, 6; 7, 8, 9]; Real T[3,3]; Real Z[3,3]; Real alphaReal[3]; Real alphaImag[3]; algorithm (T, Z, alphaReal, alphaImag):=Modelica.Math.Matrices.realSchur(A); // T = [16.12, 4.9, 1.59E-015; // 0, -1.12, -1.12E-015; // 0, 0, -1.30E-015] // Z = [-0.23, -0.88, 0.41; // -0.52, -0.24, -0.82; // -0.82, 0.4, 0.41] //alphaReal = {16.12, -1.12, -1.32E-015} //alphaImag = {0, 0, 0}
function realSchur extends Modelica.Icons.Function; import Modelica.Math.Matrices; input Real A[:, size(A, 1)] "Square matrix"; output Real S[size(A, 1), size(A, 2)] "Real Schur form of A"; output Real QZ[size(A, 1), size(A, 2)] "Schur vector Matrix"; output Real alphaReal[size(A, 1)] "Real part of eigenvalue=alphaReal+i*alphaImag"; output Real alphaImag[size(A, 1)] "Imaginary part of eigenvalue=alphaReal+i*alphaImag"; end realSchur;