Chapter 8: State-Space Modeling

Lesson 5: Relationship Between Transfer Function and State-Space Models

This lesson establishes the precise equivalence between input–output transfer-function models and internal (state-space) models for linear time-invariant (LTI) systems. We derive the fundamental formula \( G(s)=C(sI-A)^{-1}B + D \), prove invariance under similarity transformations, and show how to construct realizations (especially canonical realizations) from a given transfer function. We also connect poles/zeros to the matrices \(A,B,C,D\), and implement conversions and verification in Python, C++, Java, MATLAB/Simulink, and Wolfram Mathematica.

1. Big Picture: Two Equivalent Views of the Same LTI Dynamics

In Chapter 6, we represented LTI systems by transfer functions (input–output viewpoint). In this chapter, we represented the same dynamics by state-space models (internal viewpoint). For LTI systems, these are equivalent descriptions of the zero-state input–output behavior.

flowchart TD
  A["Physical laws / ODEs"] --> B["Choose state x(t)"]
  B --> C["State-space: xdot = A x + B u;  y = C x + D u"]
  C --> D["Laplace (zero IC)"]
  D --> E["Transfer function: G(s) = C*(sI - A)^(-1)*B + D"]
  E --> F["Interconnections (series/parallel/feedback)"]
  F --> G["Realize back to state-space (many equivalent realizations)"]
        

The key point is that many different state coordinate choices (Chapter 8, Lesson 4) can describe the same transfer function, because transfer functions are invariant under state similarity transformations.

2. Derivation: From State-Space to Transfer Function

Consider the continuous-time LTI state-space model (SISO or MIMO): \( x(t)\in\mathbb{R}^n \), \( u(t)\in\mathbb{R}^m \), \( y(t)\in\mathbb{R}^p \):

\[ \dot{x}(t) = A x(t) + B u(t), \qquad y(t) = C x(t) + D u(t), \]

Take Laplace transforms (Chapter 2). For any initial condition \(x(0)\), the Laplace transform of \(\dot{x}(t)\) is \(sX(s)-x(0)\). Hence:

\[ sX(s) - x(0) = AX(s) + BU(s) \;\;\Longrightarrow\;\; (sI - A)X(s) = x(0) + B U(s). \]

Assuming \(s\) is not an eigenvalue of \(A\) (so \((sI-A)\) is invertible), we solve:

\[ X(s) = (sI-A)^{-1}x(0) + (sI-A)^{-1}B\,U(s). \]

Then the output transform is:

\[ Y(s) = C(sI-A)^{-1}x(0) + \Big(C(sI-A)^{-1}B + D\Big)\,U(s). \]

Therefore, the transfer function matrix (the mapping from \(U(s)\) to \(Y(s)\)) is the zero-initial-condition input–output operator:

\[ \boxed{ G(s) \;=\; \left.\frac{Y(s)}{U(s)}\right|_{x(0)=0} \;=\; C(sI-A)^{-1}B + D.} \]

The additional term \(C(sI-A)^{-1}x(0)\) is the zero-input (free) response contribution; it is not part of the transfer function.

2.1. Impulse Response Connection

The state transition matrix solution (from ODE theory) gives, for zero initial condition:

\[ x(t) = \int_{0}^{t} e^{A(t-\tau)} B u(\tau)\,d\tau, \qquad y(t) = C\int_{0}^{t} e^{A(t-\tau)} B u(\tau)\,d\tau + D u(t). \]

Thus the impulse response matrix is:

\[ g(t) = C e^{At} B + D\,\delta(t), \]

and Laplace transforming yields \(G(s)=\mathcal{L}\{g(t)\}\), consistent with \(G(s)=C(sI-A)^{-1}B + D\).

3. Rational Structure: Why Transfer Functions Are Rational and How Poles Appear

The resolvent \((sI-A)^{-1}\) is a matrix whose entries are rational functions of \(s\). A fundamental identity (adjugate formula) is:

\[ (sI-A)^{-1} = \frac{\operatorname{adj}(sI-A)}{\det(sI-A)}, \qquad \text{for } \det(sI-A)\neq 0. \]

Hence every entry of \((sI-A)^{-1}\) has denominator \(\det(sI-A)\), so every entry of \(G(s)=C(sI-A)^{-1}B + D\) is a rational function whose poles are contained in the roots of \(\det(sI-A)\), i.e., in the eigenvalues of \(A\).

3.1. Theorem: Poles of \(G(s)\) are among eigenvalues of \(A\)

Theorem: Every pole of any entry of \(G(s)\) is a root of \(\det(sI-A)\).

Proof: Using the adjugate identity above, we write:

\[ G(s) = C\frac{\operatorname{adj}(sI-A)}{\det(sI-A)}B + D = \frac{C\,\operatorname{adj}(sI-A)\,B}{\det(sI-A)} + D. \]

The numerator \(C\,\operatorname{adj}(sI-A)\,B\) is a matrix whose entries are polynomials in \(s\), while \(\det(sI-A)\) is a polynomial of degree \(n\). Therefore, poles can only occur where \(\det(sI-A)=0\). ∎

3.2. Minimality and Pole–Eigenvalue Equality (Conceptual Statement)

In general, some eigenvalues of \(A\) may not appear as poles of \(G(s)\) due to pole–zero cancellations (non-minimal realizations). In Chapter 8 (Lesson 3), you saw controllable/observable canonical forms; a standard result is:

Proposition (informal here): If a realization is minimal (no redundant states; equivalently both controllable and observable in the sense developed in Lesson 3), then the poles of \(G(s)\) coincide with the eigenvalues of \(A\), counting multiplicity.

We will use this fact operationally: minimal realizations expose the true dynamic order (often called the McMillan degree).

4. Invariance: Transfer Function Does Not Change Under Similarity Transformations

From Chapter 8, Lesson 4, an invertible coordinate change \(x = Tz\) (with \(\det(T)\neq 0\)) yields an equivalent state-space representation:

\[ \dot{z} = A' z + B' u,\qquad y = C' z + D' u, \]

\[ A' = T^{-1}AT,\quad B' = T^{-1}B,\quad C' = CT,\quad D' = D. \]

4.1. Theorem: \(G'(s)=G(s)\)

Theorem: The transfer function matrix computed from \((A',B',C',D')\) equals that from \((A,B,C,D)\).

Proof: Start with:

\[ G'(s) = C'(sI-A')^{-1}B' + D'. \]

Note that:

\[ sI - A' = sI - T^{-1}AT = T^{-1}(sI-A)T. \]

Invert both sides (using \((XYZ)^{-1}=Z^{-1}Y^{-1}X^{-1}\) for invertible matrices):

\[ (sI-A')^{-1} = \big(T^{-1}(sI-A)T\big)^{-1} = T^{-1}(sI-A)^{-1}T. \]

Substitute into \(G'(s)\):

\[ \begin{aligned} G'(s) &= (CT)\big(T^{-1}(sI-A)^{-1}T\big)(T^{-1}B) + D \\ &= C(sI-A)^{-1}B + D \\ &= G(s). \end{aligned} \]

This theorem explains why a single transfer function corresponds to infinitely many (similar) state-space realizations.

5. Realization: Constructing State-Space Models from Transfer Functions (SISO Focus)

Consider a proper SISO transfer function written as:

\[ G(s) = \frac{b_{n-1}s^{n-1} + b_{n-2}s^{n-2} + \cdots + b_1 s + b_0}{s^n + a_{n-1}s^{n-1} + \cdots + a_1 s + a_0} + d, \]

where the fraction is strictly proper and \(d\) is the direct term (feedthrough). A standard realization is the controllable companion (controllable canonical) form.

flowchart TD
  A["Given G(s)=N(s)/D(s)+d"] --> B["Normalize D(s) to monic"]
  B --> C["Build companion A and B (controllable form)"]
  C --> D["Choose C to match N(s) and d"]
  D --> E["Verify: G(s)=C*(sI-A)^(-1)*B + D"]
  E --> F["Optionally apply similarity transform for desired coordinates"]
        

5.1. Controllable Companion Form (One Common Convention)

Define \(A\in\mathbb{R}^{n\times n}\), \(B\in\mathbb{R}^{n\times 1}\) as:

\[ A = \begin{bmatrix} 0 & 1 & 0 & \cdots & 0 \\ 0 & 0 & 1 & \cdots & 0 \\ \vdots & \vdots & \vdots & \ddots & \vdots \\ 0 & 0 & 0 & \cdots & 1 \\ -a_0 & -a_1 & -a_2 & \cdots & -a_{n-1} \end{bmatrix}, \qquad B = \begin{bmatrix} 0\\0\\ \vdots \\0\\1 \end{bmatrix}. \]

Choose \(D=d\). Then select \(C\in\mathbb{R}^{1\times n}\) to match the numerator. A convenient coefficient-matching choice is:

\[ C = \begin{bmatrix} b_0 - a_0 d & b_1 - a_1 d & \cdots & b_{n-2} - a_{n-2} d & b_{n-1} - a_{n-1} d \end{bmatrix}. \]

With these matrices, one can verify (by direct algebra using the structure of the companion matrix) that:

\[ G(s) = C(sI-A)^{-1}B + D. \]

5.2. Proof Sketch via Polynomial Identity

Let \(D(s)=s^n + a_{n-1}s^{n-1}+\cdots+a_0\). For the companion form above: \(\det(sI-A)=D(s)\). Also, \((sI-A)^{-1}B\) becomes a vector of rational functions whose common denominator is \(D(s)\). By choosing \(C\) as above, the numerator polynomial of \(C(sI-A)^{-1}B + d\) matches \(N(s)+dD(s)\), yielding the stated transfer function.

This realization is not unique: any similarity transform of this realization yields the same \(G(s)\).

6. MIMO Notes: Transfer Function Matrix and Zeros (Brief, Theoretical)

For MIMO systems, \(G(s)\in\mathbb{R}^{p\times m}\) is a matrix of rational functions: \(G(s)=C(sI-A)^{-1}B + D\). Poles are again contained in the eigenvalues of \(A\).

Zeros generalize beyond “roots of a numerator polynomial” because determinants and rank conditions matter. A classical, coordinate-invariant characterization uses the Rosenbrock system matrix:

\[ P(s) = \begin{bmatrix} sI - A & -B \\ C & D \end{bmatrix}. \]

Values of \(s\) where \(\operatorname{rank}(P(s))\) drops are called invariant (transmission) zeros; they are independent of state coordinate changes. This is a deeper topic that will reappear in later theoretical discussions of realizations and structural system properties.

7. Python Lab: Conversions, Verification, and “From Scratch” Frequency Response

Recommended libraries: \( \) control (python-control), scipy.signal, and optionally sympy for symbolic checks.


# pip install control scipy sympy

import numpy as np
import control as ct

# Example transfer function (strictly proper) and conversion to state-space
s = ct.TransferFunction.s
G = (s + 2) / (s**2 + 3*s + 2)

sys_ss = ct.tf2ss(G)     # realization
G_back = ct.ss2tf(sys_ss)

print("State-space realization (A,B,C,D):")
print(sys_ss)
print("\nBack-converted TF:")
print(G_back)

# Verify numerically by comparing frequency response values
w = np.logspace(-2, 2, 200)
mag_tf, phase_tf, _ = ct.frequency_response(G, w)
mag_ss, phase_ss, _ = ct.frequency_response(sys_ss, w)

err_mag = np.max(np.abs(mag_tf - mag_ss))
err_phase = np.max(np.abs(phase_tf - phase_ss))
print("\nMax |mag diff|:", err_mag)
print("Max |phase diff|:", err_phase)

# Minimal realization (cancels pole-zero pairs if any)
sys_min = ct.minreal(sys_ss, verbose=False)
print("\nMinimal realization:")
print(sys_min)

# ---- From scratch: evaluate G(s) = C (sI - A)^(-1) B + D without forming inverse
def eval_G_siso(A, B, C, D, s_complex):
    """
    SISO evaluation using linear solve:
      solve (sI - A) x = B, then G = C x + D
    """
    n = A.shape[0]
    SI_minus_A = s_complex*np.eye(n) - A
    x = np.linalg.solve(SI_minus_A, B)
    return (C @ x).item() + D

A = np.array(sys_ss.A, dtype=float)
B = np.array(sys_ss.B, dtype=float)
C = np.array(sys_ss.C, dtype=float)
D = float(sys_ss.D)

jw = 1j * 3.0
val1 = ct.evalfr(sys_ss, jw)          # library reference
val2 = eval_G_siso(A, B, C, D, jw)    # scratch evaluation
print("\nG(j*3) library:", val1)
print("G(j*3) scratch :", val2)
      

The scratch function avoids explicitly computing \((sI-A)^{-1}\); it instead solves a linear system, which is numerically preferred.

8. C++ Lab: Evaluate \(G(s)\) from \((A,B,C,D)\) Using Eigen

Recommended libraries: Eigen (linear algebra), std::complex. This example computes the complex frequency response \(G(j\omega)\) for a SISO model without forming an inverse.


#include <Eigen/Dense>
#include <complex>
#include <iostream>

std::complex<double> evalG_siso(
    const Eigen::MatrixXd& A,
    const Eigen::VectorXd& B,
    const Eigen::RowVectorXd& C,
    double D,
    std::complex<double> s
) {
    const int n = (int)A.rows();
    Eigen::MatrixXcd SI_minus_A = s * Eigen::MatrixXcd::Identity(n, n) - A.cast<std::complex<double> >();
    Eigen::VectorXcd Bc = B.cast<std::complex<double> >();
    Eigen::RowVectorXcd Cc = C.cast<std::complex<double> >();

    // Solve (sI - A) x = B
    Eigen::VectorXcd x = SI_minus_A.fullPivLu().solve(Bc);

    // G = C x + D
    return (Cc * x)(0,0) + std::complex<double>(D, 0.0);
}

int main() {
    // Example 2nd-order system:
    // xdot = A x + B u, y = C x + D u
    Eigen::MatrixXd A(2,2);
    A << 0.0, 1.0,
        -2.0, -3.0;

    Eigen::VectorXd B(2);
    B << 0.0, 1.0;

    Eigen::RowVectorXd C(2);
    C << 2.0, 1.0;

    double D = 0.0;

    double w = 3.0;
    std::complex<double> jw(0.0, w);

    auto G = evalG_siso(A, B, C, D, jw);
    std::cout << "G(j*"<< w << ") = " << G << std::endl;

    return 0;
}
      

This implements the mathematical definition \(G(s)=C(sI-A)^{-1}B + D\) via linear solves, mirroring the derivation in Section 2.

9. Java Lab: Frequency Response from State-Space Using Apache Commons Math

Recommended libraries: Apache Commons Math (complex numbers and linear algebra). The code below constructs \((sI-A)\) with complex entries and solves for \(x\) in \((sI-A)x=B\).


import org.apache.commons.math3.complex.Complex;
import org.apache.commons.math3.complex.ComplexField;
import org.apache.commons.math3.linear.Array2DRowFieldMatrix;
import org.apache.commons.math3.linear.ArrayFieldVector;
import org.apache.commons.math3.linear.FieldDecompositionSolver;
import org.apache.commons.math3.linear.FieldLUDecomposition;
import org.apache.commons.math3.linear.FieldMatrix;
import org.apache.commons.math3.linear.FieldVector;

public class StateSpaceFreqRespSISO {

    // Evaluate G(s) = C (sI - A)^(-1) B + D for SISO
    public static Complex evalG(
            double[][] A,
            double[] B,
            double[] C,
            double D,
            Complex s
    ) {
        int n = A.length;
        ComplexField field = ComplexField.getInstance();

        // Build SI_minus_A (complex)
        FieldMatrix<Complex> M = new Array2DRowFieldMatrix<>(field, n, n);
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                Complex val = new Complex(-A[i][j], 0.0);
                if (i == j) {
                    val = val.add(s); // s - A_ii
                }
                M.setEntry(i, j, val);
            }
        }

        // Build B (complex)
        FieldVector<Complex> Bc = new ArrayFieldVector<>(field, n);
        for (int i = 0; i < n; i++) {
            Bc.setEntry(i, new Complex(B[i], 0.0));
        }

        // Solve M x = B
        FieldDecompositionSolver<Complex> solver = new FieldLUDecomposition<>(M).getSolver();
        FieldVector<Complex> x = solver.solve(Bc);

        // Compute C x + D
        Complex y = Complex.ZERO;
        for (int i = 0; i < n; i++) {
            y = y.add(x.getEntry(i).multiply(C[i]));
        }
        return y.add(new Complex(D, 0.0));
    }

    public static void main(String[] args) {
        // Example system
        double[][] A = {
                {0.0, 1.0},
                {-2.0, -3.0}
        };
        double[] B = {0.0, 1.0};
        double[] C = {2.0, 1.0};
        double D = 0.0;

        double w = 3.0;
        Complex jw = new Complex(0.0, w);

        Complex G = evalG(A, B, C, D, jw);
        System.out.println("G(j*" + w + ") = " + G);
    }
}
      

This mirrors the theoretical definition by using complex LU decomposition on \(sI-A\).

10. MATLAB/Simulink Lab: tfss and Model Verification

Recommended toolboxes: Control System Toolbox, Simulink. MATLAB implements \(G(s)=C(sI-A)^{-1}B + D\) and provides robust conversion utilities.


% Define a transfer function
s = tf('s');
G = (s + 2)/(s^2 + 3*s + 2);

% Convert TF -> SS
sys_ss = ss(G);

% Convert back SS -> TF
G_back = tf(sys_ss);

disp('State-space realization:');
sys_ss

disp('Back-converted transfer function:');
G_back

% Minimal realization
sys_min = minreal(sys_ss);

% Numerical verification via frequency response
w = logspace(-2, 2, 200);
[mag_tf, ph_tf] = bode(G, w);
[mag_ss, ph_ss] = bode(sys_ss, w);

maxMagErr = max(abs(squeeze(mag_tf) - squeeze(mag_ss)));
maxPhErr  = max(abs(squeeze(ph_tf) - squeeze(ph_ss)));

fprintf('Max |mag diff| = %.3e\n', maxMagErr);
fprintf('Max |phase diff| = %.3e\n', maxPhErr);
      

10.1. Simulink Workflow (State-Space vs Transfer Function Block)

In Simulink you can confirm equivalence visually:

  • Use a Transfer Fcn block with numerator/denominator coefficients.
  • Use a State-Space block with matrices \(A,B,C,D\).
  • Drive both with the same input (e.g., Step), subtract outputs, and verify the difference is (numerically) zero.

% Programmatically create a simple Simulink model to compare TF and SS
model = 'tf_vs_ss_compare';
new_system(model); open_system(model);

% Add blocks
add_block('simulink/Sources/Step', [model '/Step']);
add_block('simulink/Continuous/Transfer Fcn', [model '/TF']);
add_block('simulink/Continuous/State-Space', [model '/SS']);
add_block('simulink/Math Operations/Subtract', [model '/Subtract']);
add_block('simulink/Sinks/Scope', [model '/Scope']);

% Configure TF block
set_param([model '/TF'], 'Numerator', '[1 2]', 'Denominator', '[1 3 2]');

% Convert to SS and configure SS block
[A,B,C,D] = tf2ss([1 2], [1 3 2]);
set_param([model '/SS'], 'A', mat2str(A), 'B', mat2str(B), 'C', mat2str(C), 'D', mat2str(D));

% Wire blocks
add_line(model, 'Step/1', 'TF/1');
add_line(model, 'Step/1', 'SS/1');
add_line(model, 'TF/1', 'Subtract/1');
add_line(model, 'SS/1', 'Subtract/2');
add_line(model, 'Subtract/1', 'Scope/1');

% Arrange and run
set_param(model, 'StopTime', '10');
sim(model);
      

11. Wolfram Mathematica Lab: Symbolic and Numeric Conversion

Mathematica natively supports both representations and exact (symbolic) conversion, which is helpful for proofs and verification.


(* Define a transfer function model *)
G = TransferFunctionModel[{ { {1, 2} }, { {1, 3, 2} } }, s];

(* Convert TF -> SS *)
sysSS = SystemsModelConvert[G, "StateSpace"];

(* Convert SS -> TF *)
Gback = SystemsModelConvert[sysSS, "TransferFunction"];

sysSS
Gback

(* Extract (A,B,C,D) *)
{A, B, C, D} = Normal[sysSS]["Matrices"];

(* Verify G(s) = C (sI - A)^(-1) B + D symbolically *)
I2 = IdentityMatrix[Length[A]];
Gexpr = Simplify[C . Inverse[s I2 - A] . B + D];

Gexpr
Simplify[Gexpr - Normal[G]]
      

12. Problems and Solutions

Problem 1 (Derive the Transfer Function): Starting from \(\dot{x}=Ax+Bu\), \(y=Cx+Du\), derive the mapping from \(U(s)\) to \(Y(s)\) and identify the transfer function. Explicitly show the term that depends on \(x(0)\).

Solution: Taking Laplace transforms gives:

\[ (sI-A)X(s)=x(0)+BU(s)\;\;\Longrightarrow\;\; X(s)=(sI-A)^{-1}x(0)+(sI-A)^{-1}B\,U(s). \]

Then:

\[ Y(s)=CX(s)+DU(s)=C(sI-A)^{-1}x(0)+\big(C(sI-A)^{-1}B+D\big)U(s). \]

Hence the transfer function (zero initial condition) is \(G(s)=C(sI-A)^{-1}B+D\), and the initial-condition term is \(C(sI-A)^{-1}x(0)\).


Problem 2 (Similarity Invariance): Let \(x=Tz\) with invertible \(T\). Prove that the transfer function of the transformed model equals the original transfer function.

Solution: Under \(x=Tz\) we have \(A'=T^{-1}AT\), \(B'=T^{-1}B\), \(C'=CT\), \(D'=D\). Then:

\[ sI-A' = T^{-1}(sI-A)T \;\;\Longrightarrow\;\; (sI-A')^{-1}=T^{-1}(sI-A)^{-1}T. \]

Therefore:

\[ \begin{aligned} G'(s) &=C'(sI-A')^{-1}B'+D' \\ &=(CT)\big(T^{-1}(sI-A)^{-1}T\big)(T^{-1}B)+D \\ &=C(sI-A)^{-1}B+D = G(s). \end{aligned} \]


Problem 3 (Pole Containment): Show that every pole of \(G(s)=C(sI-A)^{-1}B+D\) must be a root of \(\det(sI-A)\).

Solution: Use the adjugate identity:

\[ (sI-A)^{-1}=\frac{\operatorname{adj}(sI-A)}{\det(sI-A)}. \]

Then:

\[ G(s)=\frac{C\,\operatorname{adj}(sI-A)\,B}{\det(sI-A)}+D. \]

The numerator is polynomial in \(s\). Poles can occur only when the denominator \(\det(sI-A)\) is zero, i.e., at eigenvalues of \(A\).


Problem 4 (Construct a Controllable Canonical Realization): Given \(G(s)=\dfrac{s+2}{s^2+3s+2}\) (strictly proper), construct a realization in controllable companion form.

Solution: Here \(n=2\), \(D(s)=s^2+3s+2\) so \(a_1=3\), \(a_0=2\). The numerator is \(N(s)=s+2\) so \(b_1=1\), \(b_0=2\), and \(d=0\). Using the companion form:

\[ A=\begin{bmatrix}0 & 1\\ -2 & -3\end{bmatrix},\quad B=\begin{bmatrix}0\\1\end{bmatrix},\quad C=\begin{bmatrix}b_0 & b_1\end{bmatrix}=\begin{bmatrix}2 & 1\end{bmatrix},\quad D=0. \]

Then \(G(s)=C(sI-A)^{-1}B\) equals \((s+2)/(s^2+3s+2)\).


Problem 5 (Direct Evaluation at a Frequency): For the realization in Problem 4, compute \(G(j\omega)\) at \(\omega=3\) using \(G(s)=C(sI-A)^{-1}B\).

Solution: Let \(s=j3\). Compute:

\[ sI-A = \begin{bmatrix} j3 & -1\\ 2 & j3+3 \end{bmatrix}. \]

Solve \((sI-A)x=B\) with \(B=[0\;\;1]^T\), then compute \(G(s)=Cx\) with \(C=[2\;\;1]\). This is exactly what the scratch implementations in Python/C++/Java do numerically.

13. Summary

We derived the fundamental connection between state-space and transfer-function models: \(G(s)=C(sI-A)^{-1}B + D\), clarified that transfer functions describe the zero-state input–output response, proved invariance under similarity transformations, and constructed realizations (notably companion forms) from rational transfer functions. Implementations in multiple languages verified the equivalence by numeric frequency-response matching.

14. References

  1. Kalman, R.E. (1960). On the general theory of control systems. Proceedings of the First International Congress on Automatic Control, 481–492.
  2. Kalman, R.E., Ho, Y.C., & Narendra, K.S. (1963). Controllability of linear dynamical systems. Contributions to Differential Equations, 1, 189–213.
  3. Ho, B.L., & Kalman, R.E. (1966). Effective construction of linear state-variable models from input/output functions. Regelungstechnik, 14, 545–548.
  4. Rosenbrock, H.H. (1966). On the calculation of transfer functions from state-variable models. International Journal of Control, 3(3), 245–251.
  5. Silverman, L.M. (1969). Inversion of multivariable linear systems. IEEE Transactions on Automatic Control, 14(3), 270–276.
  6. Youla, D.C., Jabr, H.A., & Bongiorno, J.J. (1976). Modern Wiener–Hopf design of optimal controllers—Part I: The single-input-output case. IEEE Transactions on Automatic Control, 21(1), 3–13.
  7. Anderson, B.D.O., & Moore, J.B. (1968). Linear system realization: A survey. Proceedings of the IEEE, 56(8), 1116–1132.
  8. Fuhrmann, P.A. (1971). On the state space realization of rational transfer functions. IEEE Transactions on Automatic Control, 16(5), 447–452.
  9. Kailath, T. (1974). Linear systems: state-space representations and linear realizations (selected foundational papers). IEEE Transactions on Automatic Control, 19(6), 785–793.