Chapter 4: State Variables and State-Space Models
Lesson 5: Comparison: State-Space vs Transfer Function Perspectives
This lesson contrasts the transfer function viewpoint (external input-output mapping in the Laplace domain) with the state-space viewpoint (internal dynamics driven by inputs). We emphasize what each representation preserves or hides: initial conditions, internal modes, coupling (MIMO), coordinate freedom, and computational implications. A key outcome is a precise equivalence statement: under mild assumptions, both describe the same forced input-output behavior, while state-space carries strictly richer internal information.
1. Big Picture: Two Lenses on the Same Dynamics
In classical control, the system is often summarized by a transfer function \( G(s) \), which maps the Laplace transform of the input to the Laplace transform of the output (typically assuming zero initial conditions). In modern control, the system is described by a state vector \( x(t) \) that evolves via a first-order vector differential equation and produces the output.
The state-space description is structural: it explicitly models internal energy storage and coupling. The transfer function is behavioral: it characterizes how inputs affect outputs (for linear time-invariant systems) but does not, by itself, specify unique internal coordinates.
flowchart TD
A["Start: modeling goal"] --> B["Need internal variables \n(energy storage), constraints, or MIMO structure?"]
B -->|"yes"| SS["Use state-space: \nxdot = A x + B u; y = C x + D u"]
B -->|"no"| C["Primarily SISO frequency/time response \nwith zero initial conditions?"]
C -->|"yes"| TF["Use transfer function: \nG(s) = Y(s)/U(s) (IC = 0)"]
C -->|"no"| D["Need both internal model \nand classical plots?"]
D -->|"yes"| BOTH["Use state-space and \nderive G(s) for analysis"]
D -->|"no"| SS
In this chapter we have introduced \( (A,B,C,D) \) models and the meaning of state. In the next chapter(s), we will develop deeper bridges (including canonical forms and realization issues). Here, we focus on rigorous comparison using only tools already introduced: linear ODEs, matrix exponentials, and Laplace transforms.
2. Formal Definitions (LTI, Continuous-Time)
The standard continuous-time LTI state-space model is
\[ \dot{x}(t) = A x(t) + B u(t), \qquad y(t) = C x(t) + D u(t), \]
where \( x(t) \in \mathbb{R}^n \), \( u(t) \in \mathbb{R}^m \), \( y(t) \in \mathbb{R}^p \), and \( A,B,C,D \) are constant matrices of compatible sizes.
The transfer function viewpoint (SISO) is often introduced via Laplace transforms: for a causal LTI system with \( x(0)=0 \), the transfer function is \( G(s) = \dfrac{Y(s)}{U(s)} \). For MIMO, one uses a transfer matrix \( G(s) \in \mathbb{C}^{p \times m} \) so that \( Y(s) = G(s)U(s) \) (again, under zero initial conditions).
Two important qualifiers:
- Initial conditions: transfer functions usually describe the forced response with \( x(0)=0 \).
- Properness: the presence of \( D \neq 0 \) corresponds to direct feedthrough (output depends instantaneously on input), which affects whether \( G(s) \) is strictly proper or merely proper.
3. Bridge Theorem: From State-Space to Transfer Function (and What Transfer Functions Omit)
The state-space model yields a complete time-domain solution (natural + forced response). Using the matrix exponential (from Chapter 3), the solution of \( \dot{x}(t)=Ax(t)+Bu(t) \) is:
\[ x(t) = e^{At}x(0) + \int_{0}^{t} e^{A(t-\tau)}B\,u(\tau)\,d\tau. \]
Substituting into \( y(t)=Cx(t)+Du(t) \) gives the fundamental decomposition:
\[ y(t) = C e^{At}x(0) + \int_{0}^{t} C e^{A(t-\tau)}B\,u(\tau)\,d\tau + D u(t). \]
The first term is the natural response driven solely by the initial state; the integral term is the forced response; the \( D u(t) \) term is instantaneous feedthrough.
3.1 Derivation (Proof) via Laplace Transform
Taking Laplace transforms (assuming signals of exponential order, so transforms exist for \( \operatorname{Re}(s) \) sufficiently large), we use \( \mathcal{L}\{\dot{x}(t)\}(s)=sX(s)-x(0) \). Then:
\[ sX(s) - x(0) = A X(s) + B U(s). \]
Rearranging:
\[ (sI - A)X(s) = x(0) + B U(s). \]
For \( s \) such that \( (sI-A) \) is invertible, we obtain
\[ X(s) = (sI-A)^{-1}x(0) + (sI-A)^{-1}B\,U(s). \]
Now transform the output:
\[ Y(s) = C X(s) + D U(s) = C(sI-A)^{-1}x(0) + \big(C(sI-A)^{-1}B + D\big)U(s). \]
Therefore the transfer matrix associated with the state-space realization is
\[ G(s) = C(sI-A)^{-1}B + D, \qquad \text{so if } x(0)=0 \text{ then } Y(s)=G(s)U(s). \]
Key conclusion: a transfer function (or transfer matrix) captures the forced input-output map under \( x(0)=0 \). It does not by itself encode the natural response term \( C(sI-A)^{-1}x(0) \), nor does it uniquely determine a state coordinate choice.
4. Information Content: Internal vs External Descriptions
A concise comparison (LTI, continuous-time):
| Aspect | State-Space Perspective | Transfer Function Perspective |
|---|---|---|
| Initial conditions | Explicit: \( x(0) \) appears in \( x(t) \) and \( y(t) \) | Typically assumed zero; otherwise requires extra terms (not part of \( G(s) \)) |
| MIMO systems | Natural: \( u \in \mathbb{R}^m \), \( y \in \mathbb{R}^p \) | Possible via transfer matrix \( G(s) \), but internal coupling is less explicit |
| Internal variables | Explicit states store energy/memory of past | Hidden inside denominator structure; no explicit internal coordinates |
| Non-uniqueness | Many \( (A,B,C,D) \) can represent same behavior (coordinate changes) | Given an input-output map, \( G(s) \) is (largely) fixed; but does not pick a unique internal model |
| Time-domain simulation | Direct by integrating \( \dot{x}=Ax+Bu \) | Often indirect: via ODE forms or numerical TF blocks; IC handling can be subtle |
| Structural design readiness | Supports internal design methods (later chapters) | Supports classical frequency-domain design methods |
A technically important detail: the matrix \( (sI-A)^{-1} \) implies that the values of \( s \) near eigenvalues of \( A \) can strongly influence the response. These eigenvalues represent internal modes. Whether every internal mode appears as a pole of the input-output transfer function may depend on additional structural properties (treated carefully in later chapters). For now, it suffices that the denominator of \( G(s) \) is built from \( \det(sI-A) \) through \( (sI-A)^{-1} = \dfrac{\operatorname{adj}(sI-A)}{\det(sI-A)} \).
\[ (sI-A)^{-1} = \frac{\operatorname{adj}(sI-A)}{\det(sI-A)} \quad \Rightarrow \quad G(s) = \frac{C\,\operatorname{adj}(sI-A)\,B}{\det(sI-A)} + D. \]
This identity already shows why state-space is often the more direct language for multi-state dynamics: the internal generator of dynamics is \( A \), while the transfer function compresses dynamics into rational functions.
5. Coordinate Freedom: Many State-Space Models, One Input-Output Map
A state vector is a modeling choice (Chapter 4, Lessons 3–4). If we change state coordinates by an invertible matrix \( T \) via \( x = T z \), then:
\[ \dot{x} = A x + B u \;\Rightarrow\; T\dot{z} = A(Tz) + Bu \;\Rightarrow\; \dot{z} = (T^{-1}AT)z + (T^{-1}B)u. \]
The output becomes:
\[ y = Cx + Du = C(Tz) + Du = (CT)z + Du. \]
Hence the transformed realization is: \( \bar{A}=T^{-1}AT,\; \bar{B}=T^{-1}B,\; \bar{C}=CT,\; \bar{D}=D \).
5.1 Theorem (Transfer Function Invariance Under Similarity)
Claim: \( \bar{G}(s)=G(s) \), where \( G(s)=C(sI-A)^{-1}B + D \) and \( \bar{G}(s)=\bar{C}(sI-\bar{A})^{-1}\bar{B} + \bar{D} \).
Proof:
First note: \( sI-\bar{A} = sI - T^{-1}AT = T^{-1}(sI-A)T \). Inverting both sides (for invertible \( sI-A \)):
\[ (sI-\bar{A})^{-1} = \big(T^{-1}(sI-A)T\big)^{-1} = T^{-1}(sI-A)^{-1}T. \]
Substitute into \( \bar{G}(s) \):
\[ \bar{G}(s) = (CT)\big(T^{-1}(sI-A)^{-1}T\big)(T^{-1}B) + D = C(sI-A)^{-1}B + D = G(s). \]
This proves that coordinate changes alter \( (A,B,C) \) but preserve the same input-output transfer function. Therefore, a transfer function does not uniquely determine the state coordinates.
6. Worked Example: Mass-Spring-Damper (SISO)
Consider the familiar second-order model (from classical control background):
\[ m\ddot{q}(t) + b\dot{q}(t) + k q(t) = u(t), \qquad y(t)=q(t). \]
Define the state \( x_1=q \), \( x_2=\dot{q} \). Then:
\[ \dot{x}(t) = \begin{bmatrix} 0 & 1 \\ -\frac{k}{m} & -\frac{b}{m} \end{bmatrix} x(t) + \begin{bmatrix} 0 \\ \frac{1}{m} \end{bmatrix} u(t), \qquad y(t) = \begin{bmatrix} 1 & 0 \end{bmatrix} x(t). \]
Thus \( A=\begin{bmatrix}0&1\\-k/m&-b/m\end{bmatrix} \), \( B=\begin{bmatrix}0\\1/m\end{bmatrix} \), \( C=\begin{bmatrix}1&0\end{bmatrix} \), \( D=0 \).
The corresponding transfer function (forced response, \( x(0)=0 \)) is:
\[ G(s) = C(sI-A)^{-1}B = \frac{1}{m s^2 + b s + k}. \]
The state-space representation additionally predicts the natural response via \( C(sI-A)^{-1}x(0) \). This is exactly the information that classical transfer functions (as commonly used) omit.
7. Practical Computation: Evaluating Frequency Response and Time Response
For sinusoidal steady-state (classical frequency response), one evaluates \( G(j\omega) \). From state-space:
\[ G(j\omega) = C(j\omega I - A)^{-1}B + D. \]
For time-domain simulation, state-space integrates \( \dot{x}=Ax+Bu \) directly, while transfer function simulation often proceeds by converting to an ODE or using numerical TF blocks that implicitly maintain internal states.
flowchart TD
U["Input u(t) or U(s)"] --> SS1["State-space route"]
U --> TF1["Transfer route"]
SS1 --> SS2["Compute xdot = A x + B u; y = C x + D u"]
SS2 --> SS3["Time sim: \nintegrate x(t)"]
SS1 --> SS4["Freq: \nG(s) = C (sI - A)^-1 B + D"]
TF1 --> TF2["Given G(s) (rational)"]
TF2 --> TF3["Freq: \nevaluate G(jw)"]
TF2 --> TF4["Time sim: \nconvert to ODE/realization"]
SS3 --> OUT["Output y(t)"]
TF4 --> OUT
SS4 --> OUT2["Same forced IO map (IC=0)"]
TF3 --> OUT2
The diagram highlights an important interpretation: most numerical transfer function simulators must internally construct a state-like realization anyway; state-space simply makes this explicit and controllable.
8. Implementation Labs: Same System, Two Perspectives
We implement the mass-spring-damper example with parameters \( m=1 \), \( b=0.4 \), \( k=4 \). We will:
- Build \( (A,B,C,D) \) and compute \( G(s) \).
- Evaluate \( G(j\omega) \) by (i) state-space formula and (ii) transfer function polynomial form.
- Simulate step response by integrating the state ODE.
8.1 Python (libraries: numpy, scipy, control)
import numpy as np
from numpy.linalg import inv
import scipy.signal as sig
# Optional (recommended) for control workflows:
# pip install control
import control as ct
# Parameters
m, b, k = 1.0, 0.4, 4.0
A = np.array([[0.0, 1.0],
[-k/m, -b/m]])
B = np.array([[0.0],
[1.0/m]])
C = np.array([[1.0, 0.0]])
D = np.array([[0.0]])
# State-space model
sys_ss = ct.ss(A, B, C, D)
# Transfer function derived from state-space
sys_tf = ct.tf(sys_ss)
print("G(s) from state-space:", sys_tf)
# Direct polynomial transfer function: 1 / (m s^2 + b s + k)
num = [1.0]
den = [m, b, k]
sys_tf_poly = ct.tf(num, den)
# Compare frequency response G(jw) by two routes
w = np.logspace(-2, 2, 10)
for wi in w:
s = 1j * wi
G_ss = C @ inv(s*np.eye(A.shape[0]) - A) @ B + D
G_tf = (num[0]) / (m*s*s + b*s + k)
print(f"w={wi:8.4f} | G_ss={G_ss[0,0]: .6e} | G_tf={G_tf: .6e} | diff={abs(G_ss[0,0]-G_tf):.3e}")
# Step response (forced response, IC=0)
t = np.linspace(0, 20, 2000)
t1, y1 = ct.step_response(sys_ss, T=t) # state-space
t2, y2 = ct.step_response(sys_tf_poly, T=t) # transfer function (internally realized)
print("Max |y_ss - y_tf| on grid:", np.max(np.abs(y1 - y2)))
# Demonstrate the role of initial conditions (nonzero x0) using forced_response
x0 = np.array([1.0, 0.0]) # initial displacement
u = np.ones_like(t) # step input
t3, y3, x3 = ct.forced_response(sys_ss, T=t, U=u, X0=x0, return_x=True)
print("y(t) includes natural response due to x0 != 0; transfer function alone does not encode this term.")
Notes:
-
controlprovides a direct bridge betweenssandtf, plus classical plots. It still uses an internal realization to simulatetf. - The last part explicitly highlights the natural-response term generated by \( x(0)\neq 0 \).
8.2 C++ (libraries: Eigen for matrices; complex arithmetic)
#include <iostream>
#include <complex>
#include <vector>
#include <Eigen/Dense>
int main() {
using std::complex;
using Eigen::Matrix2d;
using Eigen::Vector2d;
using Eigen::RowVector2d;
using Eigen::MatrixXd;
using Eigen::VectorXd;
// Parameters
const double m = 1.0, b = 0.4, k = 4.0;
Matrix2d A;
A << 0.0, 1.0,
-k/m, -b/m;
Vector2d B;
B << 0.0, 1.0/m;
RowVector2d C;
C << 1.0, 0.0;
const double D = 0.0;
// Frequency response comparison
std::vector<double> w = {0.01, 0.03, 0.1, 0.3, 1.0, 3.0, 10.0};
for (double wi : w) {
complex<double> s(0.0, wi);
// Compute G(s) = C (sI - A)^{-1} B + D
Eigen::Matrix<complex<double>, 2, 2> M;
M << s - A(0,0), -A(0,1),
-A(1,0), s - A(1,1);
Eigen::Matrix<complex<double>, 2, 2> Minv = M.inverse();
Eigen::Matrix<complex<double>, 2, 1> Bc;
Bc << B(0), B(1);
Eigen::Matrix<complex<double>, 1, 2> Cc;
Cc << C(0), C(1);
complex<double> G_ss = (Cc * Minv * Bc)(0,0) + D;
// Transfer function polynomial route: 1 / (m s^2 + b s + k)
complex<double> G_tf = 1.0 / (m*s*s + b*s + k);
std::cout << "w=" << wi
<< " G_ss=" << G_ss
<< " G_tf=" << G_tf
<< " diff=" << std::abs(G_ss - G_tf)
<< std::endl;
}
// Simple time simulation by RK4 on xdot = A x + B u, step input u=1
auto f = [&](const Vector2d& x, double u) {
return A*x + B*u;
};
const double dt = 0.001;
const int N = 20000; // 20 seconds
Vector2d x; x << 0.0, 0.0; // x(0)=0
for (int i = 0; i < N; ++i) {
double u = 1.0;
Vector2d k1 = f(x, u);
Vector2d k2 = f(x + 0.5*dt*k1, u);
Vector2d k3 = f(x + 0.5*dt*k2, u);
Vector2d k4 = f(x + dt*k3, u);
x = x + (dt/6.0)*(k1 + 2.0*k2 + 2.0*k3 + k4);
if (i % 2000 == 0) {
double y = (C*x)(0) + D*u;
std::cout << "t=" << (i*dt) << " y=" << y << std::endl;
}
}
return 0;
}
Notes:
- This code demonstrates the equivalence numerically: evaluating \( G(j\omega) \) using either representation.
- The RK4 integrator directly simulates state-space. A pure transfer function simulator would internally realize an equivalent state model (even if hidden from the user).
8.3 Java (libraries: EJML for matrices; complex numbers)
import org.ejml.data.DMatrixRMaj;
import org.ejml.dense.row.CommonOps_DDRM;
public class StateSpaceVsTF {
// Minimal complex class for demonstration
static class C {
double re, im;
C(double re, double im){ this.re=re; this.im=im; }
C add(C o){ return new C(re+o.re, im+o.im); }
C sub(C o){ return new C(re-o.re, im-o.im); }
C mul(C o){ return new C(re*o.re - im*o.im, re*o.im + im*o.re); }
C div(C o){
double den = o.re*o.re + o.im*o.im;
return new C((re*o.re + im*o.im)/den, (im*o.re - re*o.im)/den);
}
double abs(){ return Math.hypot(re, im); }
public String toString(){ return String.format("(% .6e%+.6ei)", re, im); }
}
public static void main(String[] args) {
double m = 1.0, b = 0.4, k = 4.0;
// A, B, C, D
DMatrixRMaj A = new DMatrixRMaj(new double[][]{
{0.0, 1.0},
{-k/m, -b/m}
});
DMatrixRMaj B = new DMatrixRMaj(new double[][]{
{0.0},
{1.0/m}
});
DMatrixRMaj Cmat = new DMatrixRMaj(new double[][]{
{1.0, 0.0}
});
double D = 0.0;
double[] w = new double[]{0.01, 0.1, 1.0, 10.0};
for (double wi : w) {
// We evaluate G(jw) both ways.
// State-space: G = C (sI - A)^{-1} B + D, with s = j w.
// For a 2x2 system, do analytic inverse of (sI - A) with complex arithmetic:
// sI - A = [[s, -1], [k, s + b]]
C s = new C(0.0, wi);
C a11 = s; // s - 0
C a12 = new C(-1.0, 0.0);
C a21 = new C(k/m, 0.0); // -A(1,0) = k/m
C a22 = new C(b/m, wi); // s - (-b/m) = s + b/m = (b/m) + j w
// determinant = a11*a22 - a12*a21
C det = a11.mul(a22).sub(a12.mul(a21));
// inverse = (1/det) * [[a22, -a12], [-a21, a11]]
// Multiply by B = [0; 1/m], then by C = [1, 0]
C inv11 = a22.div(det);
C inv12 = (new C(1.0, 0.0)).div(det); // -a12 = 1
// Only need first row times B:
// (inv11*0 + inv12*(1/m)) = inv12*(1/m)
C Gss = inv12.mul(new C(1.0/m, 0.0)).add(new C(D, 0.0));
// Transfer function polynomial: 1 / (m s^2 + b s + k)
// s = j w, s^2 = -w^2
C s2 = s.mul(s);
C denom = (new C(m,0.0)).mul(s2).add((new C(b,0.0)).mul(s)).add(new C(k,0.0));
C Gtf = (new C(1.0,0.0)).div(denom);
System.out.println("w=" + wi + " G_ss=" + Gss + " G_tf=" + Gtf + " diff=" + Gss.sub(Gtf).abs());
}
// Time simulation should be done via an ODE integrator (e.g., Apache Commons Math),
// but the key lesson point is already shown: both frequency responses coincide.
System.out.println("For time simulation in Java, use an ODE solver library and integrate xdot = A x + B u.");
}
}
Notes:
- In production, use a mature ODE solver (e.g., Apache Commons Math) and a mature linear algebra package (EJML).
- The frequency-response equivalence is the cleanest cross-language demonstration of the two perspectives.
8.4 MATLAB (Control System Toolbox)
% Parameters
m = 1.0; b = 0.4; k = 4.0;
A = [0 1; -k/m -b/m];
B = [0; 1/m];
C = [1 0];
D = 0;
sys_ss = ss(A,B,C,D);
% Transfer function from state-space
sys_tf = tf(sys_ss);
disp('G(s) from ss:'); disp(sys_tf);
% Polynomial form transfer function
sys_tf_poly = tf(1, [m b k]);
% Compare frequency response numerically
w = logspace(-2,2,10);
[mag1, ph1] = bode(sys_ss, w); % state-space route
[mag2, ph2] = bode(sys_tf_poly, w); % TF route
maxMagDiff = max(abs(squeeze(mag1) - squeeze(mag2)));
maxPhDiff = max(abs(squeeze(ph1) - squeeze(ph2)));
fprintf('Max mag diff: %g, Max phase diff (deg): %g\n', maxMagDiff, maxPhDiff);
% Step response comparison (forced, IC=0)
t = linspace(0,20,2000);
[y_ss, t_ss] = step(sys_ss, t);
[y_tf, t_tf] = step(sys_tf_poly, t);
fprintf('Max |y_ss - y_tf|: %g\n', max(abs(y_ss - y_tf)));
% Demonstrate role of initial conditions (state-space only)
x0 = [1; 0]; % initial displacement
u = ones(size(t)); % step input
[y_forced, t_forced, x_forced] = lsim(sys_ss, u, t, x0);
disp('With x0 != 0, output includes natural response term not contained in G(s) alone.');
8.5 Simulink (programmatic model construction)
A common misconception is that a transfer function block is “stateless.” In fact, Simulink realizes it internally using states. The code below builds two models: one using a State-Space block, one using a Transfer Fcn block, then compares their step responses (IC set to zero).
% Build two Simulink models: one SS, one TF, compare outputs
m = 1.0; b = 0.4; k = 4.0;
A = [0 1; -k/m -b/m];
B = [0; 1/m];
C = [1 0];
D = 0;
% Model 1: State-Space block
mdl1 = 'ss_model_cmp';
new_system(mdl1); open_system(mdl1);
add_block('simulink/Sources/Step', [mdl1 '/Step'], 'Time','0','Before','0','After','1');
add_block('simulink/Continuous/State-Space', [mdl1 '/SS']);
set_param([mdl1 '/SS'], 'A', mat2str(A), 'B', mat2str(B), 'C', mat2str(C), 'D', mat2str(D));
add_block('simulink/Sinks/To Workspace', [mdl1 '/Yss'], 'VariableName','y_ss','SaveFormat','Array');
add_line(mdl1, 'Step/1', 'SS/1');
add_line(mdl1, 'SS/1', 'Yss/1');
set_param(mdl1, 'StopTime','20');
% Model 2: Transfer Fcn block
mdl2 = 'tf_model_cmp';
new_system(mdl2); open_system(mdl2);
add_block('simulink/Sources/Step', [mdl2 '/Step'], 'Time','0','Before','0','After','1');
add_block('simulink/Continuous/Transfer Fcn', [mdl2 '/TF']);
set_param([mdl2 '/TF'], 'Numerator', mat2str(1), 'Denominator', mat2str([m b k]));
add_block('simulink/Sinks/To Workspace', [mdl2 '/Ytf'], 'VariableName','y_tf','SaveFormat','Array');
add_line(mdl2, 'Step/1', 'TF/1');
add_line(mdl2, 'TF/1', 'Ytf/1');
set_param(mdl2, 'StopTime','20');
% Simulate both
sim(mdl1);
sim(mdl2);
% Compare results in MATLAB
t_ss = y_ss(:,1); out_ss = y_ss(:,2);
t_tf = y_tf(:,1); out_tf = y_tf(:,2);
fprintf('Max |y_ss - y_tf| (aligned by interpolation): %g\n', max(abs(out_ss - interp1(t_tf, out_tf, t_ss))));
8.6 Wolfram Mathematica (Control Systems functions)
(* Parameters *)
m = 1; b = 0.4; k = 4;
A = { {0, 1}, {-k/m, -b/m} };
B = { {0}, {1/m} };
C = { {1, 0} };
D = { {0} };
ss = StateSpaceModel[{A, B, C, D}, SamplingPeriod -> None];
tfFromSS = TransferFunctionModel[ss];
(* Polynomial TF *)
tfPoly = TransferFunctionModel[{ { {1} }, { {m, b, k} } }, s];
tfFromSS
tfPoly
(* Compare frequency response at s = I w *)
wList = {0.01, 0.1, 1, 10};
Table[
Module[{w = wv, sVal = I*wv, Gss, Gtf},
Gss = (C . Inverse[sVal IdentityMatrix[2] - A] . B + D)[[1,1]];
Gtf = 1/(m sVal^2 + b sVal + k);
{w, Gss, Gtf, Abs[Gss - Gtf]}
],
{wv, wList}
]
(* Step response comparison (IC=0) *)
ySS = OutputResponse[ss, UnitStep[t], {t, 0, 20}];
yTF = OutputResponse[tfPoly, UnitStep[t], {t, 0, 20}];
(* Demonstrate nonzero initial state in state-space *)
x0 = {1, 0};
yIC = OutputResponse[ss, UnitStep[t], {t, 0, 20}, InitialState -> x0];
Mathematica makes the “hidden state” issue explicit: even transfer function models are realized internally for time-domain responses; state-space simply exposes the internal structure and initial state directly.
9. Problems and Solutions
Problem 1 (Forced vs Natural Response): For the state-space model \( \dot{x}(t)=Ax(t)+Bu(t) \), \( y(t)=Cx(t)+Du(t) \), show that the Laplace-domain output satisfies \( Y(s)=G(s)U(s)+C(sI-A)^{-1}x(0) \), and identify \( G(s) \).
Solution:
Taking Laplace transforms: \( sX(s)-x(0)=AX(s)+BU(s) \), so \( (sI-A)X(s)=x(0)+BU(s) \), hence \( X(s)=(sI-A)^{-1}x(0)+(sI-A)^{-1}BU(s) \). Then
\[ Y(s)=CX(s)+DU(s)=C(sI-A)^{-1}x(0)+\big(C(sI-A)^{-1}B+D\big)U(s). \]
Therefore \( G(s)=C(sI-A)^{-1}B+D \). The term \( C(sI-A)^{-1}x(0) \) is the natural-response contribution that is not part of the transfer function.
Problem 2 (Similarity Invariance): Let \( x=Tz \) with invertible \( T \). Show that the transformed realization \( \bar{A}=T^{-1}AT \), \( \bar{B}=T^{-1}B \), \( \bar{C}=CT \), \( \bar{D}=D \) yields the same transfer function.
Solution:
Note \( sI-\bar{A}=T^{-1}(sI-A)T \), hence \( (sI-\bar{A})^{-1}=T^{-1}(sI-A)^{-1}T \). Then:
\[ \bar{G}(s)=\bar{C}(sI-\bar{A})^{-1}\bar{B}+\bar{D} =(CT)\big(T^{-1}(sI-A)^{-1}T\big)(T^{-1}B)+D = \\ C(sI-A)^{-1}B+D=G(s). \]
Problem 3 (Mass-Spring-Damper Transfer Function): For \( m\ddot{q}(t)+b\dot{q}(t)+kq(t)=u(t) \), \( y(t)=q(t) \), compute \( G(s)=Y(s)/U(s) \) under zero initial conditions.
Solution:
Taking Laplace transforms with zero initial conditions gives \( (ms^2+bs+k)Q(s)=U(s) \) and \( Y(s)=Q(s) \). Hence
\[ G(s)=\frac{Y(s)}{U(s)}=\frac{1}{ms^2+bs+k}. \]
Problem 4 (Direct Feedthrough and Properness): Consider a state-space model with \( D \neq 0 \). Explain why \( D \) corresponds to instantaneous input-output dependence, and show that if \( D=0 \) then \( \lim_{|s|\to\infty}G(s)=0 \).
Solution:
From \( y(t)=Cx(t)+Du(t) \), if \( D\neq 0 \) then changes in \( u(t) \) immediately affect \( y(t) \) without passing through the state dynamics. In Laplace form, \( G(s)=C(sI-A)^{-1}B+D \). As \( |s|\to\infty \), \( (sI-A)^{-1}=\frac{1}{s}(I-\frac{A}{s})^{-1} \), so \( (sI-A)^{-1}=O(\frac{1}{s}) \), implying:
\[ \lim_{|s|\to\infty} C(sI-A)^{-1}B = 0. \]
Therefore \( \lim_{|s|\to\infty}G(s)=D \). In particular, if \( D=0 \) then \( \lim_{|s|\to\infty}G(s)=0 \), i.e., the transfer function is strictly proper.
Problem 5 (MIMO Interpretation): Let \( u \in \mathbb{R}^m \) and \( y \in \mathbb{R}^p \). Show that the transfer matrix is \( G(s)=C(sI-A)^{-1}B+D \) and briefly interpret the meaning of an entry \( G_{ij}(s) \).
Solution:
The derivation in Problem 1 applies componentwise, yielding \( Y(s)=G(s)U(s)+C(sI-A)^{-1}x(0) \). Under \( x(0)=0 \), \( Y(s)=G(s)U(s) \). The entry \( G_{ij}(s) \) is the transfer function from the \( j \)-th input channel to the \( i \)-th output channel with all other inputs set to zero (superposition).
10. Summary
Transfer functions compactly describe forced input-output behavior (typically with zero initial conditions) and are highly effective for classical SISO frequency-domain reasoning. State-space models explicitly represent internal dynamics, naturally accommodate initial conditions, extend cleanly to MIMO systems, and permit coordinate changes without altering the input-output map. The rigorous bridge is: \( G(s)=C(sI-A)^{-1}B+D \), and the complete output includes an additional initial-condition term \( C(sI-A)^{-1}x(0) \).
11. References
- Kalman, R.E. (1960). On the general theory of control systems. Proceedings of the First International Congress on Automatic Control, 481–492.
- Kalman, R.E., & Bertram, J.E. (1960). Control system analysis and design via the “second method” of Lyapunov. Transactions of the ASME, Journal of Basic Engineering, 82, 371–400.
- Zadeh, L.A., & Desoer, C.A. (1963). Linear system theory: The state space approach. McGraw-Hill Series (foundational theoretical development; widely cited).
- Rosenbrock, H.H. (1968). The geometry of linear multivariable systems. Proceedings of the IEE, 115(9), 1325–1334.
- Gilbert, E.G. (1963). Controllability and observability in multivariable control systems. Journal of the Society for Industrial and Applied Mathematics, Series A: Control, 1(2), 128–151.
- Silverman, L.M. (1969). Inversion of multivariable linear systems. IEEE Transactions on Automatic Control, 14(3), 270–276.
- Wonham, W.M. (1967). On pole assignment in multi-input controllable linear systems. IEEE Transactions on Automatic Control, 12(6), 660–665.
- Youla, D.C., Jabr, H.A., & Bongiorno, J.J. (1976). Modern Wiener–Hopf design of optimal controllers—Part I. IEEE Transactions on Automatic Control, 21(1), 3–13.