SCHUR

The Schur decomposition factors a square matrix A into a unitary matrix Z and an upper triangular matrix T such that A = ZTZ^H.

Excel Usage

=SCHUR(matrix, schur_output, schur_ret_type)
  • matrix (list[list], required): Square 2D array of numeric values to decompose.
  • schur_output (str, optional, default: “real”): Construct the real or complex Schur decomposition.
  • schur_ret_type (str, optional, default: “t”): The component of the decomposition to return.

Returns (list[list]): 2D array representing the requested component (T or Z).

Example 1: Schur form T of 3x3 matrix

Inputs:

matrix schur_ret_type
0 2 2 t
0 1 2
1 0 1

Excel formula:

=SCHUR({0,2,2;0,1,2;1,0,1}, "t")

Expected output:

Result
2.65897 1.4244 -1.92933
0 -0.329484 -0.490637
0 1.31179 -0.329484
Example 2: Transformation matrix Z

Inputs:

matrix schur_ret_type
0 2 2 z
0 1 2
1 0 1

Excel formula:

=SCHUR({0,2,2;0,1,2;1,0,1}, "z")

Expected output:

Result
0.727116 -0.601562 0.330796
0.528394 0.798019 0.289768
0.438294 0.0359041 -0.898114
Example 3: Complex Schur decomposition (T real part) 2x2

Inputs:

matrix schur_output schur_ret_type
0 1 complex t
-1 0

Excel formula:

=SCHUR({0,1;-1,0}, "complex", "t")

Expected output:

Result
[object Object] [object Object]
0 [object Object]

Python Code

import numpy as np
from scipy.linalg import schur as scipy_schur

def schur(matrix, schur_output='real', schur_ret_type='t'):
    """
    Compute Schur decomposition of a matrix.

    See: https://docs.scipy.org/doc/scipy/reference/generated/scipy.linalg.schur.html

    This example function is provided as-is without any representation of accuracy.

    Args:
        matrix (list[list]): Square 2D array of numeric values to decompose.
        schur_output (str, optional): Construct the real or complex Schur decomposition. Valid options: Real, Complex. Default is 'real'.
        schur_ret_type (str, optional): The component of the decomposition to return. Valid options: Schur Form (T), Unitary Matrix (Z). Default is 't'.

    Returns:
        list[list]: 2D array representing the requested component (T or Z).
    """
    try:
        def to2d(x):
            return [[x]] if not isinstance(x, list) else x

        matrix = to2d(matrix)

        if not isinstance(matrix, list) or not matrix or not all(isinstance(row, list) for row in matrix):
            return "Error: matrix must be a non-empty 2D list"

        n = len(matrix)
        if any(len(row) != n for row in matrix):
            return "Error: matrix must be square (n x n)"

        try:
            a = np.array(matrix, dtype=float)
        except (ValueError, TypeError):
            return "Error: matrix must contain numeric values"

        if not np.all(np.isfinite(a)):
            return "Error: matrix must contain only finite numbers"

        try:
            T, Z = scipy_schur(a, output=schur_output.lower())
        except Exception as e:
            return f"Error: {str(e)}"

        def format_complex(res):
            if not np.iscomplexobj(res):
                return (res.reshape(1, -1) if res.ndim == 1 else res).tolist()

            out = []
            for row in (res.reshape(1, -1) if res.ndim == 1 else res):
                out_row = []
                for val in row:
                    if val.imag == 0.0:
                        out_row.append(float(val.real))
                    else:
                        out_row.append({
                            "type": "Double",
                            "basicValue": float(val.real),
                            "properties": {
                                "Real": {"type": "Double", "basicValue": float(val.real)},
                                "Imaginary": {"type": "Double", "basicValue": float(val.imag)},
                                "Magnitude": {"type": "Double", "basicValue": float(np.abs(val))},
                                "Phase": {"type": "Double", "basicValue": float(np.angle(val))}
                            }
                        })
                out.append(out_row)
            return out

        if schur_ret_type.lower() == "t":
            return format_complex(T)
        else:
            return format_complex(Z)

    except Exception as e:
        return f"Error: {str(e)}"

Online Calculator

Square 2D array of numeric values to decompose.
Construct the real or complex Schur decomposition.
The component of the decomposition to return.