Chapter 4: State Variables and State-Space Models
Lesson 1: Definition of State, Input, and Output
This lesson formalizes the foundational triad of modern control modeling: \( \text{state} \), \( \text{input} \), and \( \text{output} \). We treat a dynamical system as a causal operator with memory, define “state” as the minimal information required to predict future behavior under future inputs, and connect the definition to existence/uniqueness of trajectories (from linear ODE theory). We also implement the definitions through small simulations in Python, C++, Java, MATLAB/Simulink, and Wolfram Mathematica without relying on the full \((A,B,C,D)\) LTI form (introduced in Lesson 2).
1. Conceptual Overview: Why “State” Exists
Classical control frequently models systems via an input–output map (e.g., a transfer function), emphasizing how \( u \) influences \( y \). Modern control adds an explicit representation of the system’s internal “memory,” captured by the \( x \) variables, enabling multi-variable modeling, internal constraints, and systematic design.
Intuitively: \( u(t) \) represents external excitations we can command (or disturbances we model as exogenous), \( y(t) \) represents what we observe/measure, and \( x(t) \) represents the internal configuration that, together with future inputs, determines future outputs.
flowchart LR
U["Input u(t)"] --> S["System dynamics (internal evolution)"]
S --> Y["Output y(t)"]
S -. "internal memory" .-> X["State x(t)"]
X -. "affects future response" .-> S
The key modeling question is: What information must we keep from the past so that predicting the future no longer requires the entire past history? The answer is the \( \text{state} \).
2. Signals and the System as a Causal Operator
Fix a time set \( \mathcal{T} \subseteq \mathbb{R} \) (typically an interval). An input is a time function taking values in an admissible set, and similarly for output.
\[ u:\mathcal{T} \rightarrow \mathcal{U} \subseteq \mathbb{R}^{m}, \qquad y:\mathcal{T} \rightarrow \mathcal{Y} \subseteq \mathbb{R}^{p}. \]
A (causal) dynamical system can be described as an input–output operator:
\[ \mathcal{S}:\; (u,\; \text{initial information}) \;\rightarrow\; y, \qquad y = \mathcal{S}[u;\, \eta]. \]
Causality means that for any time \(t\in\mathcal{T}\), the value \(y(t)\) depends only on input values \(u(\tau)\) for \(\tau\) not later than \(t\), and on the initial information \(\eta\). Modern control replaces the vague \(\eta\) with a concrete vector \(x(t_0)\) called the state at some initial time \(t_0\).
The modeling goal of state-space is to select a variable \(x(t)\in\mathcal{X}\subseteq\mathbb{R}^{n}\) such that: knowing \(x(t_0)\) and the future input \(u(\tau)\) for \(\tau \ge t_0\) is sufficient to determine future output \(y(\tau)\).
3. Formal Definitions
3.1 Input
An input is any exogenous signal that can influence the system evolution. In engineering modeling, we often treat commanded actuation as input, and may also treat disturbances and references as inputs (as separate channels) when building a complete dynamical model.
3.2 Output
An output is any signal derived from the system that is available for measurement, monitoring, or performance evaluation. Not all internal variables are necessarily outputs; in modern control, outputs are often a low-dimensional function of the internal configuration.
3.3 State
The definition of state is the most subtle and the most important. We present a definition that is both mathematically precise and operationally meaningful.
Fix a time \(t_0\). Let \(\mathcal{U}_{[t_0,\infty)}\) denote the set of admissible future inputs on \([t_0,\infty)\). A variable \(x(t_0)\in\mathcal{X}\) is called a state at time \(t_0\) if it satisfies the following property:
\[ \textbf{State (sufficiency) property:}\quad \forall u_f \in \mathcal{U}_{[t_0,\infty)}\;\; \exists!\; y_{[t_0,\infty)} \;\text{determined by}\; (x(t_0),u_f). \]
Interpreting the statement: once \(x(t_0)\) is known, the entire past prior to \(t_0\) is irrelevant for predicting the future, provided the future input \(u_f\) is specified.
In practical terms, \(x(t_0)\) is a finite-dimensional summary of the system memory. In many physical systems, \(x(t)\) corresponds to energy-storage variables (but the physical interpretation is deferred to Lesson 4).
3.4 A rigorous “equivalence of pasts” definition
One can define state without presupposing differential equations, using only the input–output behavior. Consider two admissible past input histories \(u^{(1)}\) and \(u^{(2)}\) defined on \((-\infty,t_0]\). They are said to be equivalent at time \(t_0\) if they generate indistinguishable future outputs under any identical future input continuation.
\[ u^{(1)} \sim_{t_0} u^{(2)} \;\;\Longleftrightarrow\;\; \forall u_f \in \mathcal{U}_{[t_0,\infty)}:\; \mathcal{S}[u^{(1)} \oplus u_f]\big|_{[t_0,\infty)} = \mathcal{S}[u^{(2)} \oplus u_f]\big|_{[t_0,\infty)}. \]
The equivalence class \([u]_{t_0}\) can be taken as the “canonical state” at time \(t_0\). This definition emphasizes that state is the mathematical object that removes dependence on the entire past.
4. State Evolution and the Markov Property
A broad and standard modeling assumption is that state evolves according to a first-order law. For continuous time, we write the state equation and output equation in their most general form:
\[ \dot{x}(t) = f\!\big(t, x(t), u(t)\big), \qquad y(t) = g\!\big(t, x(t), u(t)\big), \qquad x(t_0)=x_0. \]
The term “state” is justified because this representation enforces a precise Markov property: the future depends on the past only through the current state.
4.1 Proposition (State sufficiency from uniqueness)
Assume \(f\) is continuous in \(t\) and locally Lipschitz in \(x\) (uniformly in \(u\) over admissible inputs), and assume admissible inputs \(u(t)\) are piecewise continuous. Then, for a fixed initial time \(t_0\), initial state \(x_0\), and future input \(u_f\) on \([t_0,\infty)\), there exists a unique trajectory \(x(t)\) for \(t \ge t_0\). Consequently, \(y(t)\) is uniquely determined for \(t \ge t_0\).
Proof (sketch, aligned with existence/uniqueness ideas from linear ODE theory):
Consider the integral form of the state equation on \([t_0,T]\):
\[ x(t) = x_0 + \int_{t_0}^{t} f\!\big(\tau, x(\tau), u_f(\tau)\big)\, d\tau. \]
Under the stated regularity assumptions (continuity in time and local Lipschitz in state), standard Picard–Lindelöf arguments imply existence and uniqueness of \(x(\cdot)\) on \([t_0,T]\), with extension to larger intervals when solutions remain bounded. Since \(y(t)=g(t,x(t),u_f(t))\), uniqueness of \(x\) implies uniqueness of \(y\). Therefore, knowing \(x(t_0)=x_0\) and \(u_f\) suffices to determine future behavior, which is precisely the state property.
4.2 Discrete-time counterpart (for completeness)
In discrete time (index \(k\in\mathbb{Z}_{\ge 0}\)), a parallel definition is:
\[ x[k+1] = f\!\big(k, x[k], u[k]\big), \qquad y[k] = g\!\big(k, x[k], u[k]\big). \]
Again, the state \(x[k]\) is the complete memory of the past relevant to future evolution under future inputs.
5. Minimality: When Is a State “Too Large”?
The definition of state does not enforce uniqueness: many different state choices can satisfy the sufficiency property. Some choices are redundant (containing extra variables that are unnecessary for prediction). At this stage, we only formalize what “redundant” means at the definition level:
\[ \text{A state representation is non-minimal if } \exists\;\text{a mapping}\;\pi:\mathbb{R}^{n} \rightarrow \mathbb{R}^{r}, \; r < n, \\ \text{ such that }\pi(x(t_0))\text{ still satisfies the state property.} \]
In later chapters (controllability/observability and minimal realization theory), we will develop precise criteria and constructive methods to find minimal internal descriptions. For now, the key takeaway is: state is any sufficient memory; minimal state is the smallest sufficient memory.
6. Practical Workflow: Identifying State, Input, and Output
When building a model, you must decide: (i) what is exogenous (inputs), (ii) what is measured (outputs), and (iii) what internal variables summarize memory (states). The workflow below is definition-driven and does not rely on the \((A,B,C,D)\) form yet.
graph TD A["Start: specify modeling objective"] --> B["Choose exogenous channels: what you can command or treat as disturbances (u)"] B --> C["Choose measured/performance signals (y)"] C --> D["Propose internal variables summarizing memory (x)"] D --> E["Check state property: do x(t0) and future u determine future y?"] E -->|"No: missing memory"| F["Augment x with additional internal variables"] E -->|"Yes: sufficient"| G["Simplify: remove redundant variables if possible"] F --> E G --> H["Finalize definitions of x, u, y"]
In Lesson 2, this workflow becomes concrete for linear time-invariant (LTI) systems via the standard state-space matrices.
7. Implementations: Simulating a Simple State/Input/Output Model
We implement a minimal continuous-time example that matches the definition-level framework:
\[ \dot{x}(t) = -x(t) + u(t), \qquad y(t) = x(t), \qquad x(0)=x_0. \]
Here \( u(t) \) is the input, \( y(t) \) is the output, and \( x(t) \) is the state because \(x(t_0)\) summarizes the past needed to predict the future under future inputs.
7.1 Python (SciPy; plus control-oriented note)
import numpy as np
from scipy.integrate import solve_ivp
# System: xdot = -x + u(t), y = x
def u(t):
# Example input: unit step
return 1.0 if t >= 0.0 else 0.0
def f(t, x):
return -x[0] + u(t)
t0, tf = 0.0, 5.0
x0 = np.array([0.2])
sol = solve_ivp(lambda t, x: [f(t, x)], (t0, tf), x0, dense_output=True, max_step=0.01)
t = np.linspace(t0, tf, 501)
x = sol.sol(t)[0]
y = x.copy()
print("x(tf) =", x[-1])
print("y(tf) =", y[-1])
# Note (control-oriented libraries):
# - scipy.signal and the 'control' package can represent state-space models directly,
# but the explicit (A,B,C,D) representation is introduced in Lesson 2.
7.2 C++ (Boost.odeint + Eigen)
#include <iostream>
#include <vector>
#include <boost/numeric/odeint.hpp>
using namespace boost::numeric::odeint;
// State dimension 1: xdot = -x + u(t)
typedef std::vector<double> state_type;
double u(double t) {
return (t >= 0.0) ? 1.0 : 0.0;
}
struct dynamics {
void operator()(const state_type &x, state_type &dxdt, double t) const {
dxdt[0] = -x[0] + u(t);
}
};
int main() {
state_type x(1);
x[0] = 0.2; // x(0)
double t0 = 0.0, tf = 5.0, dt = 0.01;
runge_kutta4<state_type> stepper;
for (double t = t0; t <= tf; t += dt) {
stepper.do_step(dynamics(), x, t, dt);
}
double y = x[0]; // y = x
std::cout << "x(tf) = " << x[0] << std::endl;
std::cout << "y(tf) = " << y << std::endl;
return 0;
}
7.3 Java (Apache Commons Math ODE)
import org.apache.commons.math3.ode.FirstOrderDifferentialEquations;
import org.apache.commons.math3.ode.FirstOrderIntegrator;
import org.apache.commons.math3.ode.nonstiff.DormandPrince54Integrator;
public class StateInputOutputDemo {
static double u(double t) {
return (t >= 0.0) ? 1.0 : 0.0;
}
static class Dynamics implements FirstOrderDifferentialEquations {
@Override
public int getDimension() { return 1; }
@Override
public void computeDerivatives(double t, double[] x, double[] dxdt) {
dxdt[0] = -x[0] + u(t);
}
}
public static void main(String[] args) {
double t0 = 0.0, tf = 5.0;
double[] x = new double[] { 0.2 }; // x(0)
FirstOrderIntegrator integrator =
new DormandPrince54Integrator(1.0e-8, 1.0e-2, 1.0e-10, 1.0e-10);
integrator.integrate(new Dynamics(), t0, x, tf, x);
double y = x[0]; // y = x
System.out.println("x(tf) = " + x[0]);
System.out.println("y(tf) = " + y);
}
}
7.4 MATLAB (ODE45) and Simulink conceptual build
% System: xdot = -x + u(t), y = x
u = @(t) double(t >= 0); % unit step
f = @(t, x) -x + u(t);
tspan = [0 5];
x0 = 0.2;
[t, x] = ode45(f, tspan, x0);
y = x;
fprintf('x(tf) = %.6f\n', x(end));
fprintf('y(tf) = %.6f\n', y(end));
% Simulink (block-level description, no image):
% - Use an Integrator block for x
% - Feed back x through a Gain block of -1
% - Sum (-x) + u using a Sum block
% - Output y is taken as x
7.5 Wolfram Mathematica (NDSolve)
(* System: x'(t) = -x(t) + u(t), y(t) = x(t) *)
u[t_] := UnitStep[t];
sol = NDSolve[
{
x'[t] == -x[t] + u[t],
x[0] == 0.2
},
x,
{t, 0, 5}
];
xTF = x[5] /. sol[[1]];
yTF = xTF;
Print["x(tf) = ", N[xTF]];
Print["y(tf) = ", N[yTF]];
Each implementation respects the definition-level separation: \(u(t)\) is exogenous, \(x(t)\) is the internal memory governed by dynamics, and \(y(t)\) is the measured quantity derived from \(x(t)\).
8. Problems and Solutions
Problem 1 (Memoryless mapping): Consider the system \( y(t) = k\,u(t) \) with constant \(k\). Identify the input, output, and a valid choice of state. Is a nontrivial state necessary?
Solution: The input is \( u(t) \) and the output is \( y(t) \). The mapping is memoryless: \(y(t)\) depends only on \(u(t)\) at the same time. A valid state space has dimension \(n=0\) (no state required). If one insists on a state variable, one may define \(x(t)\equiv 0\) for all \(t\), which is redundant but valid, because future outputs are determined solely by future inputs:
\[ y(t) = k\,u(t)\quad\Rightarrow\quad (x(t_0),u_f)\mapsto y_{[t_0,\infty)}\ \text{with}\ x(t_0)\ \text{irrelevant}. \]
Problem 2 (Integrator as a state system): Let \( y(t) = \int_{0}^{t} u(\tau)\,d\tau \) with \(y(0)=0\). Propose a state variable and show it satisfies the state sufficiency property.
Solution: Define the state as \(x(t)\triangleq y(t)\). Then
\[ x(t) = \int_{0}^{t} u(\tau)\,d\tau \quad\Rightarrow\quad \dot{x}(t) = u(t), \qquad y(t)=x(t). \]
Given \(x(t_0)\) and the future input \(u(\tau)\) for \(\tau \ge t_0\), we obtain for any \(t \ge t_0\):
\[ x(t) = x(t_0) + \int_{t_0}^{t} u(\tau)\,d\tau, \qquad y(t)=x(t), \]
hence future output is uniquely determined by \((x(t_0),u_f)\). Therefore \(x\) is a valid state.
Problem 3 (State sufficiency from uniqueness): Suppose a system admits a representation \( \dot{x}(t)=f(t,x(t),u(t)) \), \( y(t)=g(t,x(t),u(t)) \), \(x(t_0)=x_0\), and assume \(f\) is locally Lipschitz in \(x\). Prove that if two trajectories satisfy the same initial state and the same future input on \([t_0,T]\), then they yield identical outputs on \([t_0,T]\).
Solution: Let \(x_1(\cdot)\) and \(x_2(\cdot)\) be two solutions under the same input \(u(\cdot)\) and same initial condition \(x_1(t_0)=x_2(t_0)=x_0\). By uniqueness (Picard–Lindelöf), we have \(x_1(t)=x_2(t)\) for all \(t\in[t_0,T]\). Then outputs coincide pointwise because \(y_i(t)=g(t,x_i(t),u(t))\):
\[ x_1(t)=x_2(t)\ \forall t \in [t_0,T] \quad\Rightarrow\quad y_1(t)=g(t,x_1(t),u(t))=g(t,x_2(t),u(t))=y_2(t). \]
Problem 4 (A system that requires infinite-dimensional state): Consider the pure delay system \(y(t)=u(t-1)\) for \(t \ge 1\). Explain why no finite-dimensional vector \(x(t)\in\mathbb{R}^{n}\) can serve as an exact state for all admissible inputs.
Solution: To predict \(y(t)\) for \(t\in[t_0,t_0+1]\), one must know the input values \(u(\tau)\) for \(\tau\in[t_0-1,t_0]\). Two different past input functions can share the same value \(u(t_0)\) (and any finite collection of features) while differing on the interval \([t_0-1,t_0]\), producing different future outputs. Therefore, the “memory” required is the entire past segment of length 1. An exact state must encode a function segment (infinite-dimensional), e.g., \(x_{t_0}(\theta)=u(t_0+\theta)\) for \(\theta\in[-1,0]\).
Problem 5 (Discrete-time accumulator): Let \(x[k+1]=x[k]+u[k]\), \(y[k]=x[k]\), with \(x[0]=x_0\). Show explicitly that \(x[k_0]\) is sufficient to compute \(y[k]\) for all \(k \ge k_0\) given future inputs.
Solution: For any \(k \ge k_0\), repeated substitution yields:
\[ x[k] = x[k_0] + \sum_{i=k_0}^{k-1} u[i], \qquad y[k]=x[k]. \]
Thus the future output sequence \(\{y[k]\}_{k\ge k_0}\) is uniquely determined by the pair \(\big(x[k_0],\{u[i]\}_{i\ge k_0}\big)\), which is exactly the discrete-time state property.
9. Summary
We defined \(u\) as exogenous signals that drive the system, \(y\) as measured/performance signals, and \(x\) as a sufficient internal memory such that \((x(t_0),u_{[t_0,\infty)})\) uniquely determines future behavior. We formalized state via the sufficiency (Markov) property and via equivalence classes of past inputs. Finally, we implemented the definitions through direct simulation of a state equation in multiple languages without using the \((A,B,C,D)\) LTI form, which is introduced next.
10. References
- Kalman, R.E. (1960). On the general theory of control systems. Proceedings of the First International Conference on Automatic Control, 481–492.
- 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., & Bucy, R.S. (1961). New results in linear filtering and prediction theory. Journal of Basic Engineering, 83(1), 95–108.
- Kalman, R.E. (1963). Mathematical description of linear dynamical systems. Journal of the Society for Industrial and Applied Mathematics, Series A: Control, 1(2), 152–192.
- Ho, B.L., & Kalman, R.E. (1966). Effective construction of linear state-variable models from input/output functions. Regelungstechnik, 14, 545–548.
- Wonham, W.M. (1967). On pole assignment in multi-input controllable linear systems. IEEE Transactions on Automatic Control, 12(6), 660–665.
- Zadeh, L.A., & Desoer, C.A. (1963). Linear system theory: the state space approach (early foundational perspectives). Proceedings / journal-era foundational publications around state-space methodology.
- Brockett, R.W. (1972). System theory on group manifolds and coset spaces. SIAM Journal on Control, 10(2), 265–284.
- Sontag, E.D. (1979). On the observability of polynomial systems. SIAM Journal on Control and Optimization, 17(1), 139–151.
- Willems, J.C. (1986). From time series to linear system—Part I: finite-dimensional linear time invariant systems. Automatica, 22(5), 561–580.
Note: some foundational results on state equivalence and realization appear across conference proceedings and journal articles in the 1960s–1980s; the items above emphasize the theoretical lineage most directly tied to state-space formalism.