SS2TF

Converts a linear state-space representation back into a continuous-time polynomial transfer function.

Given the state-space matrices \mathbf{A}, \mathbf{B}, \mathbf{C}, and \mathbf{D}, the equivalent transfer function matrix \mathbf{H}(s) is calculated using the formula:

\mathbf{H}(s) = \mathbf{C}(s\mathbf{I} - \mathbf{A})^{-1}\mathbf{B} + \mathbf{D}

Excel Usage

=SS2TF(A, B, C, D)
  • A (list[list], required): System matrix (nxn)
  • B (list[list], required): Control matrix (nxm)
  • C (list[list], required): Output matrix (pxn)
  • D (list[list], required): Feedforward matrix (pxm)

Returns (list[list]): A 2D array where the first row contains the numerator coefficients and the second row contains the denominator coefficients.

Example 1: Convert a 2-state SISO system

Inputs:

A B C D
-1 -2 5 7 8 9
3 -4 6

Excel formula:

=SS2TF({-1,-2;3,-4}, {5;6}, {7,8}, {9})

Expected output:

Result
9 128 314
1 5 10
Example 2: Integrator state space to TF

Inputs:

A B C D
0 1 1 0

Excel formula:

=SS2TF({0}, {1}, {1}, {0})

Expected output:

Result
1
1 0
Example 3: State space with complex poles

Inputs:

A B C D
0 1 0 1 0 0
-2 -2 1

Excel formula:

=SS2TF({0,1;-2,-2}, {0;1}, {1,0}, {0})

Expected output:

Result
0 1
1 2 2
Example 4: Simple pass-through gain

Inputs:

A B C D
-1 1 1 5

Excel formula:

=SS2TF({-1}, {1}, {1}, {5})

Expected output:

Result
5 6
1 1

Python Code

Show Code
import control as ct
import numpy as np

def ss2tf(A, B, C, D):
    """
    Transform a state-space system into a transfer function.

    See: https://python-control.readthedocs.io/en/latest/generated/control.ss2tf.html

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

    Args:
        A (list[list]): System matrix (nxn)
        B (list[list]): Control matrix (nxm)
        C (list[list]): Output matrix (pxn)
        D (list[list]): Feedforward matrix (pxm)

    Returns:
        list[list]: A 2D array where the first row contains the numerator coefficients and the second row contains the denominator coefficients.
    """
    try:
        def to2d(x):
            return [[x]] if not isinstance(x, list) else x

        A = to2d(A)
        B = to2d(B)
        C = to2d(C)
        D = to2d(D)

        # Convert input lists to numpy arrays
        A_arr = np.array(A, dtype=float)
        B_arr = np.array(B, dtype=float)
        C_arr = np.array(C, dtype=float)
        D_arr = np.array(D, dtype=float)

        # Basic dimension checks
        if A_arr.ndim != 2 or A_arr.shape[0] != A_arr.shape[1]:
            return "Error: A must be a square 2D matrix"

        n = A_arr.shape[0]
        if B_arr.shape[0] != n:
            return "Error: B must have the same number of rows as A"
        if C_arr.shape[1] != n:
            return "Error: C must have the same number of columns as A"

        m = B_arr.shape[1] if B_arr.ndim == 2 else 1
        p = C_arr.shape[0] if C_arr.ndim == 2 else 1

        expected_d_shape = (p, m)
        if D_arr.shape != expected_d_shape:
            return f"Error: D must have shape {expected_d_shape}"

        sys_tf = ct.ss2tf(A_arr, B_arr, C_arr, D_arr)

        # Extract num and den (for SISO systems)
        if sys_tf.ninputs > 1 or sys_tf.noutputs > 1:
            return "Error: Function currently only formats outputs for SISO systems"

        num = sys_tf.num[0][0]
        den = sys_tf.den[0][0]

        # Clean up small numerical artifacts
        num[np.abs(num) < 1e-12] = 0.0
        den[np.abs(den) < 1e-12] = 0.0

        # Ensure rectangular output
        num_list = list(num)
        den_list = list(den)
        max_len = max(len(num_list), len(den_list))

        padded_num = num_list + [""] * (max_len - len(num_list))
        padded_den = den_list + [""] * (max_len - len(den_list))

        return [padded_num, padded_den]
    except Exception as e:
        return f"Error: {str(e)}"

Online Calculator

System matrix (nxn)
Control matrix (nxm)
Output matrix (pxn)
Feedforward matrix (pxm)