Accord.Math.Decompositions.JaggedGeneralizedEigenvalueDecomposition.qzhes C# (CSharp) Method

qzhes() private static method

Adaptation of the original Fortran QZHES routine from EISPACK.
This subroutine is the first step of the qz algorithm for solving generalized matrix eigenvalue problems, Siam J. Numer. anal. 10, 241-256(1973) by Moler and Stewart. This subroutine accepts a pair of real general matrices and reduces one of them to upper Hessenberg form and the other to upper triangular form using orthogonal transformations. it is usually followed by qzit, qzval and, possibly, qzvec. For the full documentation, please check the original function.
private static qzhes ( int n, double a, double b, bool matz, double z ) : int
n int
a double
b double
matz bool
z double
return int
        private static int qzhes(int n, double[][] a, double[][] b, bool matz, double[][] z)
        {
            int i, j, k, l;
            double r, s, t;
            int l1;
            double u1, u2, v1, v2;
            int lb, nk1;
            double rho;


            if (matz)
            {
                // If we are interested in computing the
                //  eigenvectors, set Z to identity(n,n)
                for (j = 0; j < n; ++j)
                {
                    for (i = 0; i < n; ++i)
                        z[i][j] = 0.0;
                    z[j][j] = 1.0;
                }
            }

            // Reduce b to upper triangular form
            if (n <= 1) return 0;
            for (l = 0; l < n - 1; ++l)
            {
                l1 = l + 1;
                s = 0.0;

                for (i = l1; i < n; ++i)
                    s += (System.Math.Abs(b[i][l]));

                if (s == 0.0) continue;
                s += (System.Math.Abs(b[l][l]));
                r = 0.0;

                for (i = l; i < n; ++i)
                {
                    // Computing 2nd power
                    b[i][l] /= s;
                    r += b[i][l] * b[i][l];
                }

                r = Special.Sign(System.Math.Sqrt(r), b[l][l]);
                b[l][l] += r;
                rho = r * b[l][l];

                for (j = l1; j < n; ++j)
                {
                    t = 0.0;
                    for (i = l; i < n; ++i)
                        t += b[i][l] * b[i][j];
                    t = -t / rho;
                    for (i = l; i < n; ++i)
                        b[i][j] += t * b[i][l];
                }

                for (j = 0; j < n; ++j)
                {
                    t = 0.0;
                    for (i = l; i < n; ++i)
                        t += b[i][l] * a[i][j];
                    t = -t / rho;
                    for (i = l; i < n; ++i)
                        a[i][j] += t * b[i][l];
                }

                b[l][l] = -s * r;
                for (i = l1; i < n; ++i)
                    b[i][l] = 0.0;
            }

            // Reduce a to upper Hessenberg form, while keeping b triangular
            if (n == 2) 
                return 0;

            for (k = 0; k < n - 2; ++k)
            {
                nk1 = n - 2 - k;

                // for l=n-1 step -1 until k+1 do
                for (lb = 0; lb < nk1; ++lb)
                {
                    l = n - lb - 2;
                    l1 = l + 1;

                    // Zero a(l+1,k)
                    s = (System.Math.Abs(a[l][k])) + (System.Math.Abs(a[l1][k]));

                    if (s == 0.0) continue;
                    u1 = a[l][k] / s;
                    u2 = a[l1][k] / s;
                    r = Special.Sign(Math.Sqrt(u1 * u1 + u2 * u2), u1);
                    v1 = -(u1 + r) / r;
                    v2 = -u2 / r;
                    u2 = v2 / v1;

                    for (j = k; j < n; ++j)
                    {
                        t = a[l][j] + u2 * a[l1][j];
                        a[l][j] += t * v1;
                        a[l1][j] += t * v2;
                    }

                    a[l1][k] = 0.0;

                    for (j = l; j < n; ++j)
                    {
                        t = b[l][j] + u2 * b[l1][j];
                        b[l][j] += t * v1;
                        b[l1][j] += t * v2;
                    }

                    // Zero b(l+1,l)
                    s = (System.Math.Abs(b[l1][l1])) + (System.Math.Abs(b[l1][l]));

                    if (s == 0.0) continue;
                    u1 = b[l1][l1] / s;
                    u2 = b[l1][l] / s;
                    r = Special.Sign(Math.Sqrt(u1 * u1 + u2 * u2), u1);
                    v1 = -(u1 + r) / r;
                    v2 = -u2 / r;
                    u2 = v2 / v1;

                    for (i = 0; i <= l1; ++i)
                    {
                        t = b[i][l1] + u2 * b[i][l];
                        b[i][l1] += t * v1;
                        b[i][l] += t * v2;
                    }

                    b[l1][l] = 0.0;

                    for (i = 0; i < n; ++i)
                    {
                        t = a[i][l1] + u2 * a[i][l];
                        a[i][l1] += t * v1;
                        a[i][l] += t * v2;
                    }

                    if (matz)
                    {
                        for (i = 0; i < n; ++i)
                        {
                            t = z[i][l1] + u2 * z[i][l];
                            z[i][l1] += t * v1;
                            z[i][l] += t * v2;
                        }
                    }
                }
            }

            return 0;
        }