Chapter 9: Stability of Linear Systems in State Space

Lesson 4: Internal Stability vs External (Input-Output) Behavior – Conceptual

This lesson separates two ideas that are often confused in introductory control: stability of the internal state vector and stability of the measured input-output behavior. The distinction is essential in state-space control because a transfer function may hide unstable internal dynamics when the realization is nonminimal.

1. Motivation and Main Question

In classical linear control, stability is often discussed through poles of a transfer function. In state-space control, however, the model contains internal variables \( x(t) \). These internal variables may behave differently from the measured output \( y(t) \). Therefore, we must distinguish internal stability from external or input-output stability.

For a continuous-time LTI state-space model

\[ \dot{x}(t)=Ax(t)+Bu(t), \qquad y(t)=Cx(t)+Du(t), \]

internal stability asks whether every free internal state trajectory decays when \( u(t)=0 \). By contrast, external stability asks whether every bounded input produces a bounded output, usually with zero initial condition.

The key lesson is: a system can have a stable transfer function while its internal state is unstable. This is not a paradox; it happens when an unstable state is hidden from the particular input-output channel.

2. Two Stability Questions in the Same State-Space Model

Internal and external stability answer different mathematical questions. The following diagram summarizes the distinction.

flowchart TD
  M["State-space model: x_dot = A x + B u, y = C x + D u"] --> Q1["Internal question"]
  M --> Q2["External input-output question"]
  Q1 --> I1["Set u = 0"]
  I1 --> I2["Study x(t) = exp(A t) x(0)"]
  I2 --> I3["All modes of A must decay"]
  Q2 --> E1["Set x(0) = 0"]
  E1 --> E2["Study transfer matrix G(s)"]
  E2 --> E3["Only modes visible from u to y appear"]
  I3 --> C1["State stability"]
  E3 --> C2["BIBO / transfer behavior"]
        

In this course, the phrase internal refers to the complete state equation. The phrase external refers to the map \( u \mapsto y \) described by the transfer matrix \( G(s)=C(sI-A)^{-1}B+D \).

3. Internal Stability of Continuous-Time LTI Systems

Internal stability is defined from the homogeneous system

\[ \dot{x}(t)=Ax(t), \qquad x(t)=e^{At}x(0). \]

The origin is asymptotically internally stable if every initial state converges to zero:

\[ \lim_{t\to\infty} e^{At}x(0)=0 \qquad \text{for every } x(0)\in\mathbb{R}^n. \]

For finite-dimensional continuous-time LTI systems, the eigenvalue criterion is

\[ A \text{ is internally asymptotically stable} \quad \Longleftrightarrow \quad \operatorname{Re}\lambda_i(A) < 0, \quad i=1,\dots,n. \]

Equivalently, there exist constants \( M\ge 1 \) and \( \alpha > 0 \) such that

\[ \|e^{At}\| \le M e^{-\alpha t}, \qquad t\ge 0. \]

This inequality is stronger than simply saying the output looks bounded: it requires every coordinate direction in the state space to decay, including coordinates not measured by the sensors.

4. External Input-Output Stability and the Transfer Matrix

With zero initial condition, the output is determined by the convolution of the input with the impulse response:

\[ y(t)=\int_0^t Ce^{A(t-\tau)}B u(\tau)\,d\tau + Du(t). \]

In the Laplace domain, this gives the transfer matrix

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

In SISO notation, if \( G(s)=\frac{N(s)}{D(s)} \) is proper and after all exact common factors are canceled, external BIBO stability requires all poles of the reduced transfer function to lie in the open left-half plane:

\[ p_k \in \mathbb{C}, \quad D_{\text{red} }(p_k)=0 \quad \Longrightarrow \quad \operatorname{Re}(p_k) < 0. \]

The phrase reduced transfer function is important. Transfer functions may cancel internal modes. A canceled mode may still exist inside the state equation even though it does not appear in \( G(s) \).

5. The Fundamental Implication and Its Failure in Reverse

If \( A \) is internally asymptotically stable, then \( e^{At} \) decays exponentially. Consequently, for a bounded input \( \|u(t)\|\le U \),

\[ \|y(t)\| \le \|C\|\int_0^t \|e^{A(t-\tau)}\|\|B\|\|u(\tau)\|\,d\tau +\|D\|\|u(t)\|. \]

Using \( \|e^{At}\|\le Me^{-\alpha t} \), we obtain

\[ \|y(t)\| \le \|C\|\|B\|MU\int_0^t e^{-\alpha(t-\tau)}d\tau + \|D\|U \le \left(\frac{\|C\|\|B\|M}{\alpha}+\|D\|\right)U. \]

Hence internal asymptotic stability implies bounded-input bounded-output stability for finite-dimensional continuous-time LTI systems with finite \( B,C,D \).

\[ \boxed{\text{internal asymptotic stability} \Longrightarrow \text{external BIBO stability} } \]

The converse is false in nonminimal realizations:

\[ \boxed{\text{external BIBO stability} \not\Longrightarrow \text{internal asymptotic stability in general} } \]

The next section constructs a two-state counterexample.

6. Counterexample: Stable Input-Output Map with Unstable Internal Mode

Consider

\[ A=\begin{bmatrix}-1&0\\0&1\end{bmatrix},\qquad B=\begin{bmatrix}1\\0\end{bmatrix},\qquad C=\begin{bmatrix}1&0\end{bmatrix},\qquad D=0. \]

The state equations are

\[ \dot{x}_1=-x_1+u, \qquad \dot{x}_2=x_2, \qquad y=x_1. \]

The eigenvalues of \( A \) are \( -1 \) and \( +1 \). Therefore, the state equation is internally unstable. In fact, for \( u(t)=0 \) and \( x(0)=[0,1]^T \),

\[ x_1(t)=0, \qquad x_2(t)=e^t, \qquad y(t)=0. \]

The output is exactly zero, but an internal state grows without bound. Now compute the transfer function:

\[ G(s)=C(sI-A)^{-1}B =\begin{bmatrix}1&0\end{bmatrix} \begin{bmatrix}\frac{1}{s+1}&0\\0&\frac{1}{s-1}\end{bmatrix} \begin{bmatrix}1\\0\end{bmatrix} =\frac{1}{s+1}. \]

The transfer function pole is only \( -1 \), so the external input-output behavior from \( u \) to \( y \) is stable. The unstable mode \( +1 \) is not excited by the input channel and not measured by the output channel.

flowchart TD
  U["input u"] --> S1["state x1: x1_dot = -x1 + u"]
  S1 --> Y["output y = x1"]
  H["hidden state x2: x2_dot = +x2"] -. "not driven by u" .- U
  H -. "not measured in y" .- Y
  H --> H2["internal unstable growth if x2(0) not zero"]
  S1 --> S2["visible stable pole at -1"]
        

7. Nonminimal Realizations and Hidden Modes

A state-space realization is minimal when it has no redundant internal states relative to the input-output map. In Chapter 6, we emphasized that many different state-space realizations can produce the same transfer function. Lesson 4 of that chapter also introduced the idea that transfer-function factorization can hide internal dynamics.

The counterexample above is nonminimal because one state coordinate \( x_2 \) does not participate in the input-output behavior. The transfer function only sees the \( x_1 \) subsystem. Thus, the external model is a first-order stable system, while the internal model is a second-order system with one unstable mode.

A useful conceptual rule is:

\[ \text{For minimal LTI realizations, internal stability and transfer-function pole stability agree.} \]

Later chapters will formalize this rule using controllability, observability, and Kalman decomposition. For now, the important message is that state-space stability must be checked from \( A \), not only from the transfer function.

8. Practical Diagnostic Procedure

For a finite-dimensional continuous-time LTI model, a robust diagnostic sequence is:

  1. Compute eigenvalues of \( A \). These determine internal zero-input modes.
  2. Compute \( G(s)=C(sI-A)^{-1}B+D \). These determine the zero-initial-state input-output behavior.
  3. Compare eigenvalues of \( A \) with poles of \( G(s) \). Any eigenvalue missing from \( G(s) \) is a hidden internal mode.
  4. If a hidden mode is unstable, do not trust transfer-function stability as a statement about the physical state. The state-space model is internally unstable.

In engineering terms, the transfer function answers: “What does the measured output do when I inject an input?” Internal stability answers: “What can every stored energy coordinate do, even if I do not measure it?”

9. Python Implementation

The Python implementation uses NumPy for eigenvalues and a from-scratch fourth-order Runge-Kutta integrator. In larger projects, useful libraries include scipy.signal for state-space simulation and python-control for transfer functions, poles, zeros, and realization analysis.

Chapter9_Lesson4.py


"""
Chapter9_Lesson4.py

Internal stability versus external input-output behavior for a nonminimal
continuous-time LTI state-space model.

Model:
    x_dot = A x + B u
    y     = C x + D u

A has one stable mode and one unstable hidden mode:
    A = diag(-1, +1), B = [1, 0]^T, C = [1, 0], D = 0

The transfer function from u to y is G(s)=1/(s+1), which is BIBO stable.
However, the internal state x2(t)=exp(t)x2(0) is unstable if x2(0) != 0.
"""

import math
import numpy as np


A = np.array([[-1.0, 0.0],
              [ 0.0, 1.0]])
B = np.array([[1.0],
              [0.0]])
C = np.array([[1.0, 0.0]])
D = np.array([[0.0]])


def f(x: np.ndarray, u: float) -> np.ndarray:
    """State derivative for the 2-state system."""
    return A @ x + B.flatten() * u


def rk4_step(x: np.ndarray, u: float, h: float) -> np.ndarray:
    """One fixed-step RK4 integration step."""
    k1 = f(x, u)
    k2 = f(x + 0.5 * h * k1, u)
    k3 = f(x + 0.5 * h * k2, u)
    k4 = f(x + h * k3, u)
    return x + (h / 6.0) * (k1 + 2.0 * k2 + 2.0 * k3 + k4)


def simulate(x0: np.ndarray, u_fun, t_final: float = 5.0, h: float = 0.01):
    """Simulate x_dot = Ax + Bu and y = Cx + Du."""
    n_steps = int(t_final / h)
    t = np.linspace(0.0, t_final, n_steps + 1)
    x = np.zeros((n_steps + 1, 2))
    y = np.zeros(n_steps + 1)
    u_hist = np.zeros(n_steps + 1)

    x[0, :] = x0
    for k in range(n_steps):
        u = float(u_fun(t[k]))
        u_hist[k] = u
        y[k] = float(C @ x[k, :].reshape(-1, 1) + D * u)
        x[k + 1, :] = rk4_step(x[k, :], u, h)

    u_hist[-1] = float(u_fun(t[-1]))
    y[-1] = float(C @ x[-1, :].reshape(-1, 1) + D * u_hist[-1])
    return t, u_hist, x, y


def classify_internal_stability(A_matrix: np.ndarray) -> str:
    """Classify continuous-time internal stability by eigenvalues of A."""
    eigenvalues = np.linalg.eigvals(A_matrix)
    if np.all(np.real(eigenvalues) < 0.0):
        return "asymptotically internally stable"
    if np.any(np.real(eigenvalues) > 0.0):
        return "internally unstable"
    return "marginal or inconclusive from this simple test"


def main():
    print("A eigenvalues:", np.linalg.eigvals(A))
    print("Internal classification:", classify_internal_stability(A))
    print("External transfer function from u to y: G(s) = 1/(s + 1)")
    print("External pole: -1, so the input-output map is stable for zero initial state.")

    # Case 1: zero input, hidden unstable initial condition.
    # Output remains zero because C does not measure x2.
    t, u_hist, x, y = simulate(np.array([0.0, 1.0]), lambda tau: 0.0)
    print("\nCase 1: u(t)=0, x(0)=[0, 1]^T")
    print("  final state x(T):", x[-1, :])
    print("  final output y(T):", y[-1])
    print("  max |y(t)|:", np.max(np.abs(y)))
    print("  max ||x(t)||:", np.max(np.linalg.norm(x, axis=1)))

    # Case 2: bounded step input, zero initial state.
    # Transfer behavior is the stable first-order response y(t)=1-exp(-t).
    t, u_hist, x, y = simulate(np.array([0.0, 0.0]), lambda tau: 1.0)
    print("\nCase 2: u(t)=1, x(0)=[0, 0]^T")
    print("  final state x(T):", x[-1, :])
    print("  final output y(T):", y[-1])
    print("  expected y(T) approximately:", 1.0 - math.exp(-t[-1]))
    print("  max |u(t)|:", np.max(np.abs(u_hist)))
    print("  max |y(t)|:", np.max(np.abs(y)))

    try:
        import matplotlib.pyplot as plt
        plt.figure()
        plt.plot(t, y, label="output y(t)")
        plt.plot(t, x[:, 0], "--", label="state x1(t)")
        plt.plot(t, x[:, 1], ":", label="hidden state x2(t)")
        plt.xlabel("time")
        plt.ylabel("response")
        plt.title("Externally stable step response with zero initial hidden state")
        plt.grid(True)
        plt.legend()
        plt.show()
    except Exception:
        pass


if __name__ == "__main__":
    main()

      

10. C++ Implementation

The C++ version implements the same two-state model from scratch. For larger control programs, common numerical libraries include Eigen for matrices, Armadillo for linear algebra, and Slycot-style routines through external bindings when advanced realization algorithms are required.

Chapter9_Lesson4.cpp


/*
Chapter9_Lesson4.cpp

Compile:
    g++ -std=c++17 -O2 Chapter9_Lesson4.cpp -o Chapter9_Lesson4

This program simulates:
    A = diag(-1, +1), B = [1, 0]^T, C = [1, 0], D = 0

The input-output transfer function is G(s)=1/(s+1), but the second internal
mode x2_dot = x2 is unstable and hidden from the input-output channel.
*/

#include <cmath>
#include <functional>
#include <iomanip>
#include <iostream>
#include <vector>

struct State {
    double x1;
    double x2;
};

State derivative(const State& x, double u) {
    State dx;
    dx.x1 = -x.x1 + u;
    dx.x2 =  x.x2;
    return dx;
}

State add_scaled(const State& x, const State& k, double scale) {
    return State{x.x1 + scale * k.x1, x.x2 + scale * k.x2};
}

State rk4_step(const State& x, double u, double h) {
    State k1 = derivative(x, u);
    State k2 = derivative(add_scaled(x, k1, 0.5 * h), u);
    State k3 = derivative(add_scaled(x, k2, 0.5 * h), u);
    State k4 = derivative(add_scaled(x, k3, h), u);

    return State{
        x.x1 + (h / 6.0) * (k1.x1 + 2.0 * k2.x1 + 2.0 * k3.x1 + k4.x1),
        x.x2 + (h / 6.0) * (k1.x2 + 2.0 * k2.x2 + 2.0 * k3.x2 + k4.x2)
    };
}

double output(const State& x, double u) {
    (void)u;
    return x.x1;
}

void simulate(const State& x0,
              const std::function<double(double)>& u_fun,
              double t_final,
              double h,
              const std::string& case_name) {
    State x = x0;
    double max_abs_y = 0.0;
    double max_norm_x = std::sqrt(x.x1 * x.x1 + x.x2 * x.x2);
    double y = output(x, u_fun(0.0));

    int n_steps = static_cast<int>(t_final / h);
    for (int k = 0; k < n_steps; ++k) {
        double t = k * h;
        double u = u_fun(t);
        y = output(x, u);
        max_abs_y = std::max(max_abs_y, std::abs(y));
        max_norm_x = std::max(max_norm_x, std::sqrt(x.x1 * x.x1 + x.x2 * x.x2));
        x = rk4_step(x, u, h);
    }

    y = output(x, u_fun(t_final));
    max_abs_y = std::max(max_abs_y, std::abs(y));
    max_norm_x = std::max(max_norm_x, std::sqrt(x.x1 * x.x1 + x.x2 * x.x2));

    std::cout << "\n" << case_name << "\n";
    std::cout << "  final x1 = " << x.x1 << ", final x2 = " << x.x2 << "\n";
    std::cout << "  final y  = " << y << "\n";
    std::cout << "  max |y|  = " << max_abs_y << "\n";
    std::cout << "  max ||x||= " << max_norm_x << "\n";
}

int main() {
    std::cout << std::fixed << std::setprecision(6);
    std::cout << "A eigenvalues are -1 and +1.\n";
    std::cout << "Internal stability: unstable because one eigenvalue has positive real part.\n";
    std::cout << "External transfer function from u to y: G(s) = 1/(s + 1), externally stable.\n";

    simulate(State{0.0, 1.0},
             [](double /*t*/) { return 0.0; },
             5.0,
             0.01,
             "Case 1: zero input, hidden unstable initial condition x(0)=[0,1]^T");

    simulate(State{0.0, 0.0},
             [](double /*t*/) { return 1.0; },
             5.0,
             0.01,
             "Case 2: unit step input, zero initial state");

    return 0;
}

      

11. Java Implementation

The Java version uses only the standard library. For larger systems, libraries such as Apache Commons Math, EJML, or ojAlgo can provide matrix operations, eigenvalue algorithms, and numerical integration utilities.

Chapter9_Lesson4.java


/*
Chapter9_Lesson4.java

Compile and run:
    javac Chapter9_Lesson4.java
    java Chapter9_Lesson4

The program demonstrates that stable input-output behavior does not imply
internal stability when the realization contains a hidden unstable mode.
*/

import java.util.function.DoubleUnaryOperator;

public class Chapter9_Lesson4 {
    static class State {
        double x1;
        double x2;

        State(double x1, double x2) {
            this.x1 = x1;
            this.x2 = x2;
        }
    }

    static State derivative(State x, double u) {
        return new State(-x.x1 + u, x.x2);
    }

    static State addScaled(State x, State k, double scale) {
        return new State(x.x1 + scale * k.x1, x.x2 + scale * k.x2);
    }

    static State rk4Step(State x, double u, double h) {
        State k1 = derivative(x, u);
        State k2 = derivative(addScaled(x, k1, 0.5 * h), u);
        State k3 = derivative(addScaled(x, k2, 0.5 * h), u);
        State k4 = derivative(addScaled(x, k3, h), u);

        double x1Next = x.x1 + (h / 6.0) * (k1.x1 + 2.0 * k2.x1 + 2.0 * k3.x1 + k4.x1);
        double x2Next = x.x2 + (h / 6.0) * (k1.x2 + 2.0 * k2.x2 + 2.0 * k3.x2 + k4.x2);
        return new State(x1Next, x2Next);
    }

    static double output(State x, double u) {
        return x.x1;
    }

    static double norm(State x) {
        return Math.sqrt(x.x1 * x.x1 + x.x2 * x.x2);
    }

    static void simulate(State x0,
                         DoubleUnaryOperator uFun,
                         double tFinal,
                         double h,
                         String caseName) {
        State x = new State(x0.x1, x0.x2);
        double maxAbsY = 0.0;
        double maxNormX = norm(x);
        int nSteps = (int)(tFinal / h);

        for (int k = 0; k < nSteps; k++) {
            double t = k * h;
            double u = uFun.applyAsDouble(t);
            double y = output(x, u);
            maxAbsY = Math.max(maxAbsY, Math.abs(y));
            maxNormX = Math.max(maxNormX, norm(x));
            x = rk4Step(x, u, h);
        }

        double yFinal = output(x, uFun.applyAsDouble(tFinal));
        maxAbsY = Math.max(maxAbsY, Math.abs(yFinal));
        maxNormX = Math.max(maxNormX, norm(x));

        System.out.println("\n" + caseName);
        System.out.printf("  final x1 = %.6f, final x2 = %.6f%n", x.x1, x.x2);
        System.out.printf("  final y  = %.6f%n", yFinal);
        System.out.printf("  max |y|  = %.6f%n", maxAbsY);
        System.out.printf("  max ||x||= %.6f%n", maxNormX);
    }

    public static void main(String[] args) {
        System.out.println("A eigenvalues are -1 and +1.");
        System.out.println("Internal stability: unstable because one eigenvalue has positive real part.");
        System.out.println("External transfer function from u to y: G(s) = 1/(s + 1), externally stable.");

        simulate(new State(0.0, 1.0),
                 t -> 0.0,
                 5.0,
                 0.01,
                 "Case 1: zero input, hidden unstable initial condition x(0)=[0,1]^T");

        simulate(new State(0.0, 0.0),
                 t -> 1.0,
                 5.0,
                 0.01,
                 "Case 2: unit step input, zero initial state");
    }
}

      

12. MATLAB/Simulink Implementation

MATLAB is especially useful here because eig, ss, tf, lsim, and Simulink state-space blocks directly support the distinction between internal eigenvalues and transfer-function poles. The script below runs with base MATLAB for simulation and uses Control System Toolbox if available.

Chapter9_Lesson4.m


% Chapter9_Lesson4.m
% Internal stability versus external input-output behavior.
%
% Requires only base MATLAB for the simulations below.
% Optional Control System Toolbox commands are included when available.

clear; clc;

A = [-1 0; 0 1];
B = [1; 0];
C = [1 0];
D = 0;

fprintf('Eigenvalues of A:\n');
disp(eig(A));
fprintf('A has an unstable internal mode at +1.\n');
fprintf('The input-output transfer function is G(s)=1/(s+1), externally stable.\n');

% Optional Control System Toolbox verification
if exist('ss', 'file') == 2 && exist('tf', 'file') == 2
    sys = ss(A, B, C, D);
    fprintf('\nState-space model converted to transfer function:\n');
    disp(tf(sys));
end

% Case 1: zero input, hidden unstable initial condition
x0_hidden = [0; 1];
ode_zero = @(t, x) A*x + B*0;
[t1, x1] = ode45(ode_zero, [0 5], x0_hidden);
y1 = (C*x1.').';

fprintf('\nCase 1: u(t)=0, x(0)=[0;1]\n');
fprintf('  final state x(T) = [%g, %g]\n', x1(end,1), x1(end,2));
fprintf('  final output y(T) = %g\n', y1(end));
fprintf('  max |y(t)| = %g\n', max(abs(y1)));
fprintf('  max ||x(t)|| = %g\n', max(vecnorm(x1, 2, 2)));

% Case 2: unit step input, zero initial condition
x0_zero = [0; 0];
ode_step = @(t, x) A*x + B*1;
[t2, x2] = ode45(ode_step, [0 5], x0_zero);
y2 = (C*x2.').';

fprintf('\nCase 2: u(t)=1, x(0)=[0;0]\n');
fprintf('  final state x(T) = [%g, %g]\n', x2(end,1), x2(end,2));
fprintf('  final output y(T) = %g\n', y2(end));
fprintf('  expected y(T) approximately = %g\n', 1 - exp(-t2(end)));
fprintf('  max |y(t)| = %g\n', max(abs(y2)));

figure;
plot(t1, x1(:,2), 'LineWidth', 1.5); grid on;
xlabel('time'); ylabel('hidden state x_2(t)');
title('Internal instability: hidden state grows under zero input');

figure;
plot(t2, y2, 'LineWidth', 1.5); grid on;
xlabel('time'); ylabel('output y(t)');
title('Externally stable step response when hidden initial state is zero');

      

In Simulink, the same example can be built with a State-Space block using \( A,B,C,D \) as defined above. To reveal internal instability, route the second state to a scope or use a second output matrix \( C_x=I_2 \) for diagnostic visualization. If only \( y=x_1 \) is displayed, the unstable hidden coordinate \( x_2 \) remains invisible.

13. Wolfram Mathematica Implementation

Mathematica is convenient for symbolic transfer-function calculation: it can compute \( C(sI-A)^{-1}B+D \) exactly and then simulate both the hidden zero-input trajectory and the visible step response.

Chapter9_Lesson4.nb


(* Chapter9_Lesson4.nb *)

ClearAll["Global`*"];

A = { {-1, 0}, {0, 1} };
B = { {1}, {0} };
Cmat = { {1, 0} };
Dmat = { {0} };

Print["Eigenvalues of A: ", Eigenvalues[A]];
Print["Internal stability: unstable because lambda = +1 is present."];
Print["External transfer function: G(s) = 1/(s+1)."];

(* Transfer matrix G(s)=C (s I - A)^(-1) B + D *)
s = Symbol["s"];
G = Simplify[Cmat . Inverse[s IdentityMatrix[2] - A] . B + Dmat];
Print["G(s) = ", G[[1, 1]]];

(* Case 1: zero input with hidden unstable initial condition *)
solHidden = NDSolveValue[
   {x1'[t] == -x1[t], x2'[t] == x2[t], x1[0] == 0, x2[0] == 1},
   {x1, x2},
   {t, 0, 5}
];

yHidden[t_] := solHidden[[1]][t];
Print["Case 1: y(5) = ", yHidden[5], ", x2(5) = ", solHidden[[2]][5]];

(* Case 2: unit step input with zero initial condition *)
solStep = NDSolveValue[
   {z1'[t] == -z1[t] + 1, z2'[t] == z2[t], z1[0] == 0, z2[0] == 0},
   {z1, z2},
   {t, 0, 5}
];

yStep[t_] := solStep[[1]][t];
Print["Case 2: y(5) = ", yStep[5], ", expected 1-Exp[-5] = ", 1 - Exp[-5]];

Plot[Evaluate[{solHidden[[2]][t], yStep[t]}], {t, 0, 5},
 PlotLegends -> {"hidden unstable state x2(t)", "stable output y(t)"},
 AxesLabel -> {"time", "response"},
 PlotLabel -> "Internal instability versus external response"]

      

14. Problems and Solutions

Problem 1 (Internal eigenvalue test): Consider \( A=\begin{bmatrix}-2&0\\0&-3\end{bmatrix} \). Determine whether the homogeneous system \( \dot{x}=Ax \) is internally asymptotically stable.

Solution: The eigenvalues are \( -2 \) and \( -3 \). Both have strictly negative real parts. Therefore,

\[ \operatorname{Re}\lambda_i(A) < 0, \quad i=1,2, \]

and the state satisfies \( x(t)=e^{At}x(0)\to 0 \) for every initial condition. The system is internally asymptotically stable.

Problem 2 (External transfer behavior): For the realization

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

compute the transfer function and decide whether the input-output behavior from \( u \) to \( y \) is stable.

Solution:

\[ G(s)=C(sI-A)^{-1}B =\begin{bmatrix}1&0\end{bmatrix} \begin{bmatrix}\frac{1}{s+4}&0\\0&\frac{1}{s-2}\end{bmatrix} \begin{bmatrix}1\\0\end{bmatrix} =\frac{1}{s+4}. \]

The transfer-function pole is \( -4 \), so the zero-initial-state input-output map is BIBO stable. This conclusion does not imply internal stability because \( A \) still has the unstable eigenvalue \( +2 \).

Problem 3 (Internal instability hidden from output): For the system in Problem 2, set \( u(t)=0 \) and \( x(0)=[0,1]^T \). Find \( x(t) \) and \( y(t) \).

Solution: The two state equations are

\[ \dot{x}_1=-4x_1, \qquad \dot{x}_2=2x_2, \qquad y=x_1. \]

With \( x_1(0)=0 \) and \( x_2(0)=1 \),

\[ x_1(t)=0, \qquad x_2(t)=e^{2t}, \qquad y(t)=0. \]

Therefore the output is identically zero while an internal state grows exponentially. This is the defining warning sign of hidden internal instability.

Problem 4 (Internal stability implies BIBO stability): Suppose \( A \) is Hurwitz and \( \|u(t)\|\le U \). Show that the convolution term in \( y(t) \) is bounded.

Solution: Since \( A \) is Hurwitz, there exist \( M\ge 1 \) and \( \alpha > 0 \) such that \( \|e^{At}\|\le Me^{-\alpha t} \). Hence

\[ \left\|\int_0^t Ce^{A(t-\tau)}Bu(\tau)d\tau\right\| \le \|C\|\|B\|MU\int_0^t e^{-\alpha(t-\tau)}d\tau \le \frac{\|C\|\|B\|M}{\alpha}U. \]

Adding the feedthrough term gives

\[ \|y(t)\|\le \left(\frac{\|C\|\|B\|M}{\alpha}+\|D\|\right)U. \]

Thus bounded inputs produce bounded outputs.

Problem 5 (Diagnostic comparison): A realization has eigenvalues \( \{-5,-1,+0.5\} \), but its reduced transfer function has poles \( \{-5,-1\} \). What can be concluded?

Solution: The reduced transfer function is externally stable because its poles lie in the open left-half plane. However, the state matrix contains an unstable eigenvalue \( +0.5 \). Since that eigenvalue does not appear in the transfer function, it is a hidden internal mode. Therefore, the realization is externally stable but internally unstable.

15. Summary

Internal stability concerns the full state trajectory \( x(t)=e^{At}x(0) \); external stability concerns the input-output map \( u\mapsto y \), usually under zero initial condition. For continuous-time LTI systems, internal asymptotic stability implies BIBO stability, but BIBO stability does not imply internal stability for nonminimal realizations. Therefore, modern control analysis must inspect both eigenvalues of \( A \) and poles of \( G(s) \).

16. References

  1. Kalman, R.E. (1960). On the general theory of control systems. Proceedings of the First International Congress on Automatic Control, Moscow, 481–492.
  2. Kalman, R.E. (1963). Mathematical description of linear dynamical systems. SIAM Journal on Control, 1(2), 152–192.
  3. Gilbert, E.G. (1963). Controllability and observability in multivariable control systems. SIAM Journal on Control, 1(2), 128–151.
  4. Ho, B.L., & Kalman, R.E. (1966). Effective construction of linear state-variable models from input/output functions. Regelungstechnik, 14, 545–548.
  5. Zames, G. (1966). On the input-output stability of time-varying nonlinear feedback systems. Part I: Conditions derived using concepts of loop gain, conicity, and positivity. IEEE Transactions on Automatic Control, 11(2), 228–238.
  6. Willems, J.C. (1972). Dissipative dynamical systems, Part I: General theory. Archive for Rational Mechanics and Analysis, 45(5), 321–351.
  7. Moore, B.C. (1981). Principal component analysis in linear systems: Controllability, observability, and model reduction. IEEE Transactions on Automatic Control, 26(1), 17–32.
  8. Doyle, J.C., Glover, K., Khargonekar, P.P., & Francis, B.A. (1989). State-space solutions to standard H2 and H-infinity control problems. IEEE Transactions on Automatic Control, 34(8), 831–847.