Chapter 11: Controllability Tests and Criteria
Lesson 1: Kalman Controllability Matrix and Rank Condition
This lesson develops the first algebraic test for controllability of finite-dimensional continuous-time LTI systems. Starting from the state equation solution already introduced in earlier chapters, we prove that the ability to steer the state is completely determined by the rank of a finite matrix built from \( A \) and \( B \).
1. Motivation and Learning Goal
Consider the continuous-time linear time-invariant state equation
\[ \dot{\mathbf{x} }(t)=\mathbf{A}\mathbf{x}(t)+\mathbf{B}\mathbf{u}(t), \quad \mathbf{x}(t)\in\mathbb{R}^n,\quad \mathbf{u}(t)\in\mathbb{R}^m. \]
From Chapter 10, controllability means that the input can drive the state from any initial state to any final state in finite time. Since translations of the state equation reduce general steering from \( \mathbf{x}_0 \) to \( \mathbf{x}_f \) into steering the origin to a suitable target, it is enough to study reachability from \( \mathbf{x}(0)=\mathbf{0} \).
The central question of this lesson is: Can the pair \( (\mathbf{A},\mathbf{B}) \) create enough independent state directions to span \( \mathbb{R}^n \)?
flowchart TD
A["Input directions: columns of B"] --> B["Dynamics propagate directions"]
B --> C["B, A B, A^2 B, ..., A^(n-1) B"]
C --> D["Form Kalman matrix C_K"]
D --> E["rank(C_K) = n ?"]
E -->|yes| F["All states are reachable"]
E -->|no| G["Only a subspace is reachable"]
2. From Input Directions to Dynamically Generated Directions
The columns of \( \mathbf{B} \) are the directions in which the input directly injects motion. However, the system matrix \( \mathbf{A} \) can rotate, couple, amplify, or mix those directly actuated directions into additional directions. Thus the directions relevant to controllability are
\[ \operatorname{im}(\mathbf{B}),\quad \operatorname{im}(\mathbf{A}\mathbf{B}),\quad \operatorname{im}(\mathbf{A}^2\mathbf{B}),\quad \dots . \]
Since \( \mathbf{A} \) is an \( n\times n \) matrix, powers higher than \( n-1 \) do not add fundamentally new independent directions. This follows from the Cayley-Hamilton theorem. If
\[ p_\mathbf{A}(\lambda)=\lambda^n+a_{n-1}\lambda^{n-1}+ \cdots+a_1\lambda+a_0, \]
then \( p_\mathbf{A}(\mathbf{A})=\mathbf{0} \), so
\[ \mathbf{A}^n=-a_{n-1}\mathbf{A}^{n-1}-\cdots-a_1\mathbf{A}-a_0\mathbf{I}. \]
Multiplying by \( \mathbf{B} \) shows that \( \mathbf{A}^n\mathbf{B} \) is a linear combination of \( \mathbf{B},\mathbf{A}\mathbf{B},\dots, \mathbf{A}^{n-1}\mathbf{B} \). The same argument applies to all higher powers.
3. The Kalman Controllability Matrix
The Kalman controllability matrix of the pair \( (\mathbf{A},\mathbf{B}) \) is the block matrix
\[ \mathcal{C}_K = \begin{bmatrix} \mathbf{B} & \mathbf{A}\mathbf{B} & \mathbf{A}^2\mathbf{B} & \cdots & \mathbf{A}^{n-1}\mathbf{B} \end{bmatrix}\in\mathbb{R}^{n\times nm}. \]
Its column space is the reachable subspace generated by the actuator directions and their dynamic propagation:
\[ \mathcal{R}(\mathbf{A},\mathbf{B})= \operatorname{span}\left\{\operatorname{im}(\mathbf{B}), \operatorname{im}(\mathbf{A}\mathbf{B}),\dots, \operatorname{im}(\mathbf{A}^{n-1}\mathbf{B})\right\} =\operatorname{im}(\mathcal{C}_K). \]
The maximum possible rank is \( n \). Therefore the natural algebraic test is whether these columns span the whole state space.
4. Kalman's Rank Condition
Theorem (Kalman rank condition). The finite-dimensional continuous-time LTI system \( \dot{\mathbf{x} }=\mathbf{A}\mathbf{x}+ \mathbf{B}\mathbf{u} \) is controllable if and only if
\[ \operatorname{rank}(\mathcal{C}_K)=n. \]
Equivalently, the system is not controllable if and only if
\[ \operatorname{rank}(\mathcal{C}_K)<n. \]
This condition is purely algebraic. It does not require solving an optimization problem or selecting a particular input signal.
4.1 Proof using the state-transition solution
With \( \mathbf{x}(0)=\mathbf{0} \), the solution at time \( T \) is
\[ \mathbf{x}(T)=\int_0^T e^{\mathbf{A}(T-\tau)}\mathbf{B} \mathbf{u}(\tau)\,d\tau. \]
For every scalar \( s \), Cayley-Hamilton implies that \( e^{\mathbf{A}s}\mathbf{B} \) belongs to the span of \( \mathbf{B},\mathbf{A}\mathbf{B},\dots, \mathbf{A}^{n-1}\mathbf{B} \). Hence every reachable state belongs to \( \operatorname{im}(\mathcal{C}_K) \). Therefore, if \( \operatorname{rank}(\mathcal{C}_K)<n \), the reachable set cannot be all of \( \mathbb{R}^n \).
Conversely, suppose \( \operatorname{rank}(\mathcal{C}_K)=n \). Assume that some nonzero vector \( \mathbf{q} \) is orthogonal to all states reachable at time \( T \). Then for all admissible inputs,
\[ \mathbf{q}^T\int_0^T e^{\mathbf{A}(T-\tau)}\mathbf{B} \mathbf{u}(\tau)\,d\tau=0. \]
Since the input is arbitrary, this implies
\[ \mathbf{q}^T e^{\mathbf{A}s}\mathbf{B}=\mathbf{0}, \quad 0\le s\le T. \]
Differentiating with respect to \( s \) at \( s=0 \) gives
\[ \mathbf{q}^T\mathbf{A}^k\mathbf{B}=\mathbf{0}, \quad k=0,1,\dots,n-1. \]
Thus \( \mathbf{q}^T\mathcal{C}_K=\mathbf{0} \). Since \( \mathcal{C}_K \) has full row rank, the only such vector is \( \mathbf{q}=\mathbf{0} \), a contradiction. Therefore the reachable set has no nonzero orthogonal complement and must equal \( \mathbb{R}^n \).
5. Algorithmic Test and Numerical Rank
The theoretical test is exact, but computer arithmetic is finite precision. A practical procedure uses singular values \( \sigma_1\ge\sigma_2\ge\cdots \) of \( \mathcal{C}_K \) and counts how many are significantly nonzero:
\[ \operatorname{rank}_\varepsilon(\mathcal{C}_K)= \#\left\{i:\sigma_i>\varepsilon\sigma_1\right\}. \]
If the smallest nonzero singular value is extremely small, the system can be mathematically controllable but numerically fragile. In physical terms, one state direction may be reachable only through very weak dynamic coupling.
flowchart TD
A["Given A (n by n), B (n by m)"] --> B["Compute blocks: B, A B, ..., A^(n-1) B"]
B --> C["Stack blocks into C_K"]
C --> D["Compute rank by elimination or SVD"]
D --> E["rank = n?"]
E -->|yes| F["Pair (A,B) is controllable"]
E -->|no| G["Reachable subspace has lower dimension"]
G --> H["Find basis from independent columns of C_K"]
6. MIMO Interpretation and Coordinate Invariance
For \( m>1 \), each block \( \mathbf{A}^k\mathbf{B} \) has \( m \) columns. The rank test does not require each input to control each state independently. It only requires the collection of all direct and propagated input directions to span the state space.
The test is invariant under a nonsingular change of state coordinates. Let \( \mathbf{x}=\mathbf{T}\mathbf{z} \), where \( \mathbf{T} \) is invertible. Then
\[ \dot{\mathbf{z} }= \underbrace{\mathbf{T}^{-1}\mathbf{A}\mathbf{T} }_{\bar{\mathbf{A} } } \mathbf{z}+ \underbrace{\mathbf{T}^{-1}\mathbf{B} }_{\bar{\mathbf{B} } } \mathbf{u}. \]
The transformed controllability matrix satisfies
\[ \bar{\mathcal{C} }_K= \begin{bmatrix} \bar{\mathbf{B} } & \bar{\mathbf{A} }\bar{\mathbf{B} } & \cdots & \bar{\mathbf{A} }^{n-1}\bar{\mathbf{B} } \end{bmatrix} =\mathbf{T}^{-1}\mathcal{C}_K. \]
Since multiplication by an invertible matrix does not change rank,
\[ \operatorname{rank}(\bar{\mathcal{C} }_K) =\operatorname{rank}(\mathcal{C}_K). \]
Thus controllability is a property of the physical state-space pair, not an artifact of the chosen coordinates.
7. Worked Examples
7.1 A controllable third-order SISO system
Consider
\[ \mathbf{A}= \begin{bmatrix} 0&1&0\\ 0&0&1\\ -6&-11&-6 \end{bmatrix}, \quad \mathbf{B}= \begin{bmatrix} 0\\0\\1 \end{bmatrix}. \]
Then
\[ \mathcal{C}_K= \begin{bmatrix} \mathbf{B}&\mathbf{A}\mathbf{B}&\mathbf{A}^2\mathbf{B} \end{bmatrix} = \begin{bmatrix} 0&0&1\\ 0&1&-6\\ 1&-6&25 \end{bmatrix}. \]
Its determinant is
\[ \det(\mathcal{C}_K)=-1\ne 0. \]
Hence \( \operatorname{rank}(\mathcal{C}_K)=3 \), and the system is controllable.
7.2 An uncontrollable system
Now consider
\[ \mathbf{A}= \begin{bmatrix} 2&0&0\\ 0&0&1\\ 0&-4&-1 \end{bmatrix}, \quad \mathbf{B}= \begin{bmatrix} 0\\0\\1 \end{bmatrix}. \]
Because the first state is dynamically separated from the actuated second-third subsystem, all columns of \( \mathcal{C}_K \) have first component zero:
\[ \mathcal{C}_K= \begin{bmatrix} 0&0&0\\ 0&1&-1\\ 1&-1&-3 \end{bmatrix}, \quad \operatorname{rank}(\mathcal{C}_K)=2. \]
The first state direction cannot be reached from the input. The system is therefore not controllable.
8. Python Implementation
File: Chapter11_Lesson1.py
# Chapter11_Lesson1.py
# Kalman controllability matrix and rank condition for continuous-time LTI systems.
# Requirements: numpy. Optional: scipy is not required.
import numpy as np
def controllability_matrix(A: np.ndarray, B: np.ndarray) -> np.ndarray:
"""Return C_K = [B, AB, A^2 B, ..., A^(n-1)B]."""
A = np.asarray(A, dtype=float)
B = np.asarray(B, dtype=float)
if A.ndim != 2 or A.shape[0] != A.shape[1]:
raise ValueError("A must be an n by n square matrix.")
if B.ndim != 2 or B.shape[0] != A.shape[0]:
raise ValueError("B must be an n by m matrix with the same row count as A.")
n = A.shape[0]
blocks = []
Ak = np.eye(n)
for _ in range(n):
blocks.append(Ak @ B)
Ak = A @ Ak
return np.hstack(blocks)
def numerical_rank(M: np.ndarray, rtol: float = None) -> tuple[int, np.ndarray, float]:
"""Compute SVD-based numerical rank and return rank, singular values, tolerance."""
s = np.linalg.svd(M, compute_uv=False)
if rtol is None:
rtol = max(M.shape) * np.finfo(float).eps
tol = rtol * (s[0] if s.size else 0.0)
rank = int(np.sum(s > tol))
return rank, s, tol
def is_controllable(A: np.ndarray, B: np.ndarray, rtol: float = None) -> bool:
Ck = controllability_matrix(A, B)
rank, _, _ = numerical_rank(Ck, rtol=rtol)
return rank == A.shape[0]
def reachable_subspace_basis(A: np.ndarray, B: np.ndarray, rtol: float = None) -> np.ndarray:
"""Return an orthonormal basis for the reachable subspace using SVD."""
Ck = controllability_matrix(A, B)
U, s, _ = np.linalg.svd(Ck, full_matrices=False)
if rtol is None:
rtol = max(Ck.shape) * np.finfo(float).eps
tol = rtol * (s[0] if s.size else 0.0)
r = int(np.sum(s > tol))
return U[:, :r]
def demo() -> None:
# Example 1: third-order companion-like system with one input.
A1 = np.array([[0.0, 1.0, 0.0],
[0.0, 0.0, 1.0],
[-6.0, -11.0, -6.0]])
B1 = np.array([[0.0],
[0.0],
[1.0]])
C1 = controllability_matrix(A1, B1)
rank1, s1, tol1 = numerical_rank(C1)
print("Example 1: controllable SISO system")
print("C_K =\n", C1)
print("singular values =", s1)
print("rank =", rank1, "tol =", tol1)
print("controllable =", rank1 == A1.shape[0])
print()
# Example 2: a system with an unactuated first state.
A2 = np.array([[2.0, 0.0, 0.0],
[0.0, 0.0, 1.0],
[0.0, -4.0, -1.0]])
B2 = np.array([[0.0],
[0.0],
[1.0]])
C2 = controllability_matrix(A2, B2)
rank2, s2, tol2 = numerical_rank(C2)
print("Example 2: uncontrollable system")
print("C_K =\n", C2)
print("singular values =", s2)
print("rank =", rank2, "tol =", tol2)
print("controllable =", rank2 == A2.shape[0])
print("reachable basis =\n", reachable_subspace_basis(A2, B2))
if __name__ == "__main__":
demo()
The function controllability_matrix constructs
\( \mathcal{C}_K \) block by block. The SVD-based rank
computation is preferred over determinant testing because determinants
are poorly scaled for numerical decisions.
9. C++ Implementation
File: Chapter11_Lesson1.cpp
// Chapter11_Lesson1.cpp
// Kalman controllability matrix and rank condition using only the C++ standard library.
#include <cmath>
#include <iomanip>
#include <iostream>
#include <stdexcept>
#include <vector>
using Matrix = std::vector<std::vector<double>>;
Matrix zeros(int r, int c) {
return Matrix(r, std::vector<double>(c, 0.0));
}
Matrix identity(int n) {
Matrix I = zeros(n, n);
for (int i = 0; i < n; ++i) I[i][i] = 1.0;
return I;
}
Matrix multiply(const Matrix& A, const Matrix& B) {
int r = static_cast<int>(A.size());
int k = static_cast<int>(A[0].size());
int c = static_cast<int>(B[0].size());
if (static_cast<int>(B.size()) != k) {
throw std::invalid_argument("Inner dimensions do not match.");
}
Matrix C = zeros(r, c);
for (int i = 0; i < r; ++i) {
for (int j = 0; j < c; ++j) {
for (int p = 0; p < k; ++p) {
C[i][j] += A[i][p] * B[p][j];
}
}
}
return C;
}
Matrix hstack(const std::vector<Matrix>& blocks) {
int rows = static_cast<int>(blocks[0].size());
int totalCols = 0;
for (const auto& M : blocks) totalCols += static_cast<int>(M[0].size());
Matrix H = zeros(rows, totalCols);
int offset = 0;
for (const auto& M : blocks) {
int cols = static_cast<int>(M[0].size());
for (int i = 0; i < rows; ++i)
for (int j = 0; j < cols; ++j)
H[i][offset + j] = M[i][j];
offset += cols;
}
return H;
}
Matrix controllabilityMatrix(const Matrix& A, const Matrix& B) {
int n = static_cast<int>(A.size());
if (n == 0 || static_cast<int>(A[0].size()) != n) {
throw std::invalid_argument("A must be square.");
}
if (static_cast<int>(B.size()) != n) {
throw std::invalid_argument("B must have the same number of rows as A.");
}
std::vector<Matrix> blocks;
Matrix Ak = identity(n);
for (int k = 0; k < n; ++k) {
blocks.push_back(multiply(Ak, B));
Ak = multiply(A, Ak);
}
return hstack(blocks);
}
int rankGaussian(Matrix M, double tol = 1e-10) {
int rows = static_cast<int>(M.size());
int cols = static_cast<int>(M[0].size());
int rank = 0;
for (int col = 0; col < cols && rank < rows; ++col) {
int pivot = rank;
for (int i = rank + 1; i < rows; ++i) {
if (std::fabs(M[i][col]) > std::fabs(M[pivot][col])) pivot = i;
}
if (std::fabs(M[pivot][col]) <= tol) continue;
std::swap(M[rank], M[pivot]);
double piv = M[rank][col];
for (int j = col; j < cols; ++j) M[rank][j] /= piv;
for (int i = 0; i < rows; ++i) {
if (i == rank) continue;
double factor = M[i][col];
for (int j = col; j < cols; ++j) M[i][j] -= factor * M[rank][j];
}
++rank;
}
return rank;
}
void printMatrix(const Matrix& M) {
for (const auto& row : M) {
for (double v : row) {
std::cout << std::setw(12) << std::setprecision(6) << v << " ";
}
std::cout << "\n";
}
}
int main() {
Matrix A = { {0.0, 1.0, 0.0},
{0.0, 0.0, 1.0},
{-6.0, -11.0, -6.0} };
Matrix B = { {0.0},
{0.0},
{1.0} };
Matrix Ck = controllabilityMatrix(A, B);
int r = rankGaussian(Ck);
std::cout << "Kalman controllability matrix C_K:\n";
printMatrix(Ck);
std::cout << "rank(C_K) = " << r << "\n";
std::cout << "controllable = " << (r == static_cast<int>(A.size()) ? "true" : "false") << "\n";
return 0;
}
This version uses from-scratch matrix multiplication and Gaussian elimination with partial pivoting. For production numerical work, replace the simple matrix type with Eigen, Armadillo, or LAPACK-backed routines.
10. Java Implementation
File: Chapter11_Lesson1.java
// Chapter11_Lesson1.java
// Kalman controllability matrix and rank condition using plain Java arrays.
public class Chapter11_Lesson1 {
static double[][] zeros(int r, int c) {
return new double[r][c];
}
static double[][] identity(int n) {
double[][] I = zeros(n, n);
for (int i = 0; i < n; i++) I[i][i] = 1.0;
return I;
}
static double[][] multiply(double[][] A, double[][] B) {
int r = A.length;
int k = A[0].length;
int c = B[0].length;
if (B.length != k) throw new IllegalArgumentException("Inner dimensions do not match.");
double[][] C = zeros(r, c);
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
for (int p = 0; p < k; p++) {
C[i][j] += A[i][p] * B[p][j];
}
}
}
return C;
}
static double[][] hstack(double[][][] blocks) {
int rows = blocks[0].length;
int totalCols = 0;
for (double[][] block : blocks) totalCols += block[0].length;
double[][] H = zeros(rows, totalCols);
int offset = 0;
for (double[][] block : blocks) {
int cols = block[0].length;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
H[i][offset + j] = block[i][j];
}
}
offset += cols;
}
return H;
}
static double[][] controllabilityMatrix(double[][] A, double[][] B) {
int n = A.length;
if (A[0].length != n) throw new IllegalArgumentException("A must be square.");
if (B.length != n) throw new IllegalArgumentException("B must have the same row count as A.");
double[][][] blocks = new double[n][][];
double[][] Ak = identity(n);
for (int k = 0; k < n; k++) {
blocks[k] = multiply(Ak, B);
Ak = multiply(A, Ak);
}
return hstack(blocks);
}
static int rankGaussian(double[][] input, double tol) {
int rows = input.length;
int cols = input[0].length;
double[][] M = new double[rows][cols];
for (int i = 0; i < rows; i++) {
System.arraycopy(input[i], 0, M[i], 0, cols);
}
int rank = 0;
for (int col = 0; col < cols && rank < rows; col++) {
int pivot = rank;
for (int i = rank + 1; i < rows; i++) {
if (Math.abs(M[i][col]) > Math.abs(M[pivot][col])) pivot = i;
}
if (Math.abs(M[pivot][col]) <= tol) continue;
double[] temp = M[rank];
M[rank] = M[pivot];
M[pivot] = temp;
double piv = M[rank][col];
for (int j = col; j < cols; j++) M[rank][j] /= piv;
for (int i = 0; i < rows; i++) {
if (i == rank) continue;
double factor = M[i][col];
for (int j = col; j < cols; j++) {
M[i][j] -= factor * M[rank][j];
}
}
rank++;
}
return rank;
}
static void printMatrix(double[][] M) {
for (double[] row : M) {
for (double v : row) {
System.out.printf("%12.6f ", v);
}
System.out.println();
}
}
public static void main(String[] args) {
double[][] A = {
{0.0, 1.0, 0.0},
{0.0, 0.0, 1.0},
{-6.0, -11.0, -6.0}
};
double[][] B = {
{0.0},
{0.0},
{1.0}
};
double[][] Ck = controllabilityMatrix(A, B);
int rank = rankGaussian(Ck, 1e-10);
System.out.println("Kalman controllability matrix C_K:");
printMatrix(Ck);
System.out.println("rank(C_K) = " + rank);
System.out.println("controllable = " + (rank == A.length));
}
}
The Java implementation mirrors the C++ logic. In scientific Java projects, libraries such as EJML, Apache Commons Math, or ojAlgo can provide more robust linear algebra routines.
11. MATLAB / Simulink Implementation
File: Chapter11_Lesson1.m
% Chapter11_Lesson1.m
% Kalman controllability matrix and rank condition in MATLAB.
% The script uses a from-scratch implementation and also shows the Control System Toolbox call.
clear; clc;
A = [0 1 0;
0 0 1;
-6 -11 -6];
B = [0;
0;
1];
Ck = kalmanControllabilityMatrix(A, B);
r = rank(Ck);
disp('Kalman controllability matrix C_K =');
disp(Ck);
fprintf('rank(C_K) = %d\n', r);
fprintf('controllable = %s\n', string(r == size(A, 1)));
% If the Control System Toolbox is available, ctrb(A,B) gives the same matrix.
if exist('ctrb', 'file') == 2
Ck_toolbox = ctrb(A, B);
fprintf('norm(Ck - ctrb(A,B), fro) = %.3e\n', norm(Ck - Ck_toolbox, 'fro'));
end
% Optional Simulink interpretation:
% Build an integrator-chain realization with State-Space block parameters
% A, B, C = eye(size(A)), D = zeros(size(A,1), size(B,2)).
% The rank test checks whether the input port has authority over all internal states.
function Ck = kalmanControllabilityMatrix(A, B)
n = size(A, 1);
if size(A, 2) ~= n
error('A must be square.');
end
if size(B, 1) ~= n
error('B must have the same number of rows as A.');
end
Ck = [];
Ak = eye(n);
for k = 0:n-1
Ck = [Ck, Ak * B]; %#ok<AGROW>
Ak = A * Ak;
end
end
In MATLAB, the Control System Toolbox function
ctrb(A,B) constructs the same matrix. In Simulink, a
State-Space block with matrices
\( A,B,C,D \) represents the same internal dynamics;
the rank test is applied to the model matrices before attempting
state-feedback design.
12. Wolfram Mathematica Implementation
File: Chapter11_Lesson1.nb
(* Chapter11_Lesson1.nb *)
(* Kalman controllability matrix and rank condition in Wolfram Mathematica. *)
ClearAll[controllabilityMatrix, controllableQ];
controllabilityMatrix[A_, B_] := Module[
{n = Length[A], blocks},
blocks = Table[MatrixPower[A, k].B, {k, 0, n - 1}];
ArrayFlatten[{blocks}]
];
controllableQ[A_, B_] := MatrixRank[controllabilityMatrix[A, B]] == Length[A];
A = { {0, 1, 0},
{0, 0, 1},
{-6, -11, -6} };
B = { {0},
{0},
{1} };
Ck = controllabilityMatrix[A, B];
Print["Kalman controllability matrix C_K = "];
Print[MatrixForm[Ck]];
Print["rank(C_K) = ", MatrixRank[Ck]];
Print["controllable = ", controllableQ[A, B]];
(* A second example with an uncontrollable first state. *)
A2 = { {2, 0, 0},
{0, 0, 1},
{0, -4, -1} };
B2 = { {0},
{0},
{1} };
Print["rank(C_K for second example) = ",
MatrixRank[controllabilityMatrix[A2, B2]]
];
Print["reachable subspace basis for second example = "];
Print[MatrixForm[Orthogonalize[Transpose[controllabilityMatrix[A2, B2]]]]];
Mathematica is useful for symbolic controllability calculations because
MatrixRank can be evaluated exactly for integer or rational
matrices, avoiding floating-point rank ambiguity.
13. Problems and Solutions
Problem 1 (Direct rank test): For
\[ \mathbf{A}= \begin{bmatrix} 0&1\\ -2&-3 \end{bmatrix}, \quad \mathbf{B}= \begin{bmatrix} 0\\1 \end{bmatrix}, \]
determine whether the system is controllable.
Solution: The controllability matrix is
\[ \mathcal{C}_K= \begin{bmatrix} \mathbf{B}&\mathbf{A}\mathbf{B} \end{bmatrix} = \begin{bmatrix} 0&1\\ 1&-3 \end{bmatrix}. \]
Its determinant is \( -1 \), so its rank is \( 2 \). Hence the system is controllable.
Problem 2 (Loss of controllability by actuator placement): For
\[ \mathbf{A}= \begin{bmatrix} 1&0\\ 0&2 \end{bmatrix}, \quad \mathbf{B}= \begin{bmatrix} 1\\0 \end{bmatrix}, \]
find the reachable subspace.
Solution: Since
\[ \mathcal{C}_K= \begin{bmatrix} \mathbf{B}&\mathbf{A}\mathbf{B} \end{bmatrix} = \begin{bmatrix} 1&1\\ 0&0 \end{bmatrix}, \]
the rank is \( 1 \). The reachable subspace is
\[ \mathcal{R}(\mathbf{A},\mathbf{B})= \operatorname{span}\left\{\begin{bmatrix}1\\0\end{bmatrix}\right\}. \]
The second state cannot be reached because the input does not enter it directly or indirectly through the dynamics.
Problem 3 (MIMO controllability): Consider
\[ \mathbf{A}= \begin{bmatrix} 0&1&0\\ 0&0&1\\ 0&0&0 \end{bmatrix}, \quad \mathbf{B}= \begin{bmatrix} 0&1\\ 1&0\\ 0&0 \end{bmatrix}. \]
Determine controllability.
Solution: Here
\[ \mathbf{B}= \begin{bmatrix} 0&1\\ 1&0\\ 0&0 \end{bmatrix}, \quad \mathbf{A}\mathbf{B}= \begin{bmatrix} 1&0\\ 0&0\\ 0&0 \end{bmatrix}, \quad \mathbf{A}^2\mathbf{B}= \begin{bmatrix} 0&0\\ 0&0\\ 0&0 \end{bmatrix}. \]
The column space is spanned by the first two coordinate directions only, so \( \operatorname{rank}(\mathcal{C}_K)=2 \). The system is not controllable.
Problem 4 (Coordinate invariance): Show that if \( \mathbf{x}=\mathbf{T}\mathbf{z} \) with invertible \( \mathbf{T} \), then controllability of \( (\mathbf{A},\mathbf{B}) \) is equivalent to controllability of \( (\mathbf{T}^{-1}\mathbf{A}\mathbf{T}, \mathbf{T}^{-1}\mathbf{B}) \).
Solution: The transformed Kalman matrix is
\[ \bar{\mathcal{C} }_K=\mathbf{T}^{-1}\mathcal{C}_K. \]
Since \( \mathbf{T}^{-1} \) is invertible, multiplication by it does not change rank. Thus \( \operatorname{rank}(\bar{\mathcal{C} }_K)=n \) if and only if \( \operatorname{rank}(\mathcal{C}_K)=n \).
Problem 5 (Symbolic parameter condition): Let
\[ \mathbf{A}= \begin{bmatrix} 0&1\\ -a&-b \end{bmatrix}, \quad \mathbf{B}= \begin{bmatrix} 0\\c \end{bmatrix}. \]
Find the condition on \( c \) for controllability.
Solution: The controllability matrix is
\[ \mathcal{C}_K= \begin{bmatrix} 0&c\\ c&-bc \end{bmatrix}. \]
Its determinant is \( -c^2 \). Therefore the system is controllable if and only if
\[ c\ne 0. \]
The parameters \( a \) and \( b \) do not affect this particular rank condition; actuator effectiveness \( c \) is the decisive factor.
14. Summary
The Kalman controllability matrix collects the direct input directions and their dynamic propagation through the state matrix. For an \( n \)-state continuous-time LTI system, only the first \( n \) block directions are needed because of Cayley-Hamilton. The system is controllable exactly when \( \operatorname{rank}(\mathcal{C}_K)=n \). This test is coordinate invariant, valid for SISO and MIMO systems, and computationally straightforward, though numerical rank should be interpreted with care for poorly conditioned systems.
15. References
- Kalman, R.E. (1960). Contributions to the theory of optimal control. Boletín de la Sociedad Matemática Mexicana, 5, 102–119.
- Kalman, R.E., Ho, Y.C., & Narendra, K.S. (1963). Controllability of linear dynamical systems. Contributions to Differential Equations, 1, 189–213.
- 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. (1966). Inversion of multivariable linear systems. IEEE Transactions on Automatic Control, 11(2), 270–276.
- Sontag, E.D. (1983). An algebraic approach to bounded controllability of linear systems. International Journal of Control, 39(1), 181–188.
- Brammer, R.F. (1972). Controllability in linear autonomous systems with positive controllers. SIAM Journal on Control, 10(2), 339–353.
- Wonham, W.M. (1967). On pole assignment in multi-input controllable linear systems. IEEE Transactions on Automatic Control, 12(6), 660–665.