Chapter 10: Persistent Excitation and Parameter Convergence
Lesson 1: Definition of Persistent Excitation (PE)
This lesson develops the mathematical definition of persistent excitation, its excitation-Gramian interpretation, equivalent directional-energy conditions, coordinate invariance, continuous- and discrete-time forms, and numerical diagnostics. The focus is deliberately on what PE means and how it is tested; its role in proving parameter convergence is reserved for Lesson 2.
1. Why Stability Alone Does Not Describe Information
Earlier chapters established that adaptive laws can keep tracking errors and parameter estimates bounded, and under suitable assumptions can make the tracking error approach zero. These stability statements do not by themselves guarantee that the measured signals contain enough independent information to distinguish every unknown parameter. Persistent excitation is the standard quantitative condition used to express this information requirement.
Consider a linearly parameterized signal relation \( y(t)=\theta^{\mathsf T}\phi(t) \), where \( \theta\in\mathbb{R}^{n} \) is unknown and \( \phi(t)\in\mathbb{R}^{n} \) is a known regressor. For a candidate parameter displacement \( z\in\mathbb{R}^{n} \), the scalar \( z^{\mathsf T}\phi(t) \) measures how strongly the data react to motion in parameter-space direction \( z \). If this scalar vanishes throughout a time interval, the data on that interval cannot distinguish parameters that differ along that direction.
flowchart TD
A["Known regressor signal phi(t)"] --> B["Choose a window of length T"]
B --> C["Accumulate G = integral of phi phi^T"]
C --> D["Compute eigenvalues of G"]
D --> E{"Smallest eigenvalue \nuniformly positive?"}
E -->|yes| F["Every parameter direction receives energy"]
E -->|no| H["At least one direction is weak or invisible"]
F --> I["Signal is persistently exciting"]
H --> J["PE condition is not established"]
2. Continuous-Time Definition
Let \( \phi:[t_0,\infty)\to\mathbb{R}^{n} \) be piecewise continuous. Define its finite-window excitation Gramian by
\[ G_{\phi}(\tau,T) =\int_{\tau}^{\tau+T}\phi(t)\phi^{\mathsf T}(t)\,dt . \]
The regressor \( \phi(t) \) is persistently exciting of order \(n\) when there exist constants \( T>0 \), \( \alpha>0 \), and \( \beta\ge\alpha \) such that, for every \( \tau\ge t_0 \),
\[ \alpha I_n \preceq \int_{\tau}^{\tau+T}\phi(t)\phi^{\mathsf T}(t)\,dt \preceq \beta I_n . \]
Here \( A\preceq B \) means that \( B-A \) is positive semidefinite. The window length \( T \) is fixed and the same lower bound \( \alpha \) must hold for every window, regardless of where that window begins. This uniformity is what makes excitation persistent, rather than a one-time burst of informative motion.
Many texts state only the lower inequality and separately assume that \( \phi(t) \) is bounded. Indeed, if \( \|\phi(t)\|\le M \), then
\[ G_{\phi}(\tau,T) \preceq \int_{\tau}^{\tau+T}M^2 I_n\,dt =TM^2 I_n, \]
so the upper bound follows with \( \beta=TM^2 \). The essential PE requirement is therefore the uniform positive-definite lower bound.
3. Directional-Energy Interpretation
The matrix inequality becomes transparent when tested against an arbitrary vector \( z\in\mathbb{R}^{n} \). Since
\[ z^{\mathsf T}G_{\phi}(\tau,T)z =\int_{\tau}^{\tau+T} z^{\mathsf T}\phi(t)\phi^{\mathsf T}(t)z\,dt =\int_{\tau}^{\tau+T} \bigl(z^{\mathsf T}\phi(t)\bigr)^2\,dt, \]
the PE inequality is equivalent to
\[ \alpha\|z\|^2 \le \int_{\tau}^{\tau+T} \bigl(z^{\mathsf T}\phi(t)\bigr)^2\,dt \le \beta\|z\|^2, \qquad \forall z\in\mathbb{R}^{n},\quad \forall \tau\ge t_0. \]
Thus every nonzero direction in parameter space must be visible with a uniformly positive amount of squared projection energy in every window. PE does not require each component of the regressor to be nonzero at every instant. Components may cross zero repeatedly; what matters is the integrated geometry over the full window.
flowchart TD
Z["Select any nonzero direction z"] --> P["Project regressor: q(t) = z^T phi(t)"]
P --> S["Accumulate squared projection over one window"]
S --> L["Lower bound: energy at least alpha times norm(z)^2"]
L --> A["No fixed parameter direction can remain invisible"]
3.1 Rayleigh-Quotient Equivalence
For a symmetric matrix, the minimum and maximum eigenvalues satisfy
\[ \lambda_{\min}(G) =\min_{\|z\|=1}z^{\mathsf T}Gz, \qquad \lambda_{\max}(G) =\max_{\|z\|=1}z^{\mathsf T}Gz. \]
Therefore, the continuous-time PE definition is equivalently
\[ \inf_{\tau\ge t_0} \lambda_{\min}\bigl(G_{\phi}(\tau,T)\bigr) \ge\alpha>0, \qquad \sup_{\tau\ge t_0} \lambda_{\max}\bigl(G_{\phi}(\tau,T)\bigr) \le\beta. \]
This eigenvalue form is the basis of the numerical tests later in the lesson.
4. Fundamental Properties and Short Proofs
4.1 Positive Definiteness of Every Excitation Window
If \( \phi \) is PE, then every window Gramian is nonsingular. To see this, suppose that \( G_{\phi}(\tau,T)z=0 \) for some nonzero \( z \). Then
\[ 0=z^{\mathsf T}G_{\phi}(\tau,T)z \ge\alpha\|z\|^2>0, \]
which is impossible. Hence \( \operatorname{rank}G_{\phi}(\tau,T)=n \) for all admissible window start times.
4.2 Full Rank at One Window Is Not Enough
A signal can produce a positive-definite Gramian over one early interval and later decay to zero. Such a signal is informative only temporarily. PE requires one common lower bound for all future windows:
\[ \inf_{\tau\ge t_0} \lambda_{\min}\bigl(G_{\phi}(\tau,T)\bigr)>0. \]
Consequently, checking a single Gramian or a finite data record can support a PE diagnosis on the observed horizon, but cannot by itself prove the infinite-horizon definition.
4.3 Trace and Total-Energy Bounds
Taking traces of the PE inequality gives
\[ n\alpha \le \operatorname{tr}G_{\phi}(\tau,T) =\int_{\tau}^{\tau+T}\|\phi(t)\|^2\,dt \le n\beta. \]
A PE regressor therefore has nonvanishing total energy in every window. The converse is false for vector regressors: large total energy may be concentrated in only one direction, leaving the Gramian singular.
4.4 Invariance Under Nonsingular Coordinate Changes
Let \( \psi(t)=M\phi(t) \), where \( M\in\mathbb{R}^{n\times n} \) is constant and nonsingular. Then
\[ G_{\psi}(\tau,T) =M G_{\phi}(\tau,T)M^{\mathsf T}. \]
If \( \phi \) is PE, then for every \( z \),
\[ z^{\mathsf T}G_{\psi}z =(M^{\mathsf T}z)^{\mathsf T}G_{\phi}(M^{\mathsf T}z) \ge \alpha\|M^{\mathsf T}z\|^2 \ge \alpha\sigma_{\min}^2(M)\|z\|^2. \]
Similarly, \( z^{\mathsf T}G_{\psi}z\le \beta\sigma_{\max}^2(M)\|z\|^2 \). Hence \( \psi \) is PE with valid constants
\[ \alpha_{\psi}=\alpha\sigma_{\min}^2(M), \qquad \beta_{\psi}=\beta\sigma_{\max}^2(M). \]
PE is therefore a geometric property independent of a nonsingular choice of parameter coordinates, although its numerical bounds change.
4.5 Scaling
For a nonzero scalar \( c \), if \( \psi(t)=c\phi(t) \), then
\[ G_{\psi}(\tau,T)=c^2G_{\phi}(\tau,T). \]
Thus PE is preserved and the bounds become \( c^2\alpha \) and \( c^2\beta \).
5. Canonical Examples
5.1 Scalar Constant Signal
For \( n=1 \) and \( \phi(t)=c\neq0 \),
\[ G_{\phi}(\tau,T)=\int_{\tau}^{\tau+T}c^2\,dt=c^2T. \]
The scalar signal is PE for any selected \( T>0 \), with \( \alpha=\beta=c^2T \). This example emphasizes that PE does not necessarily mean oscillatory. In one dimension, a nonzero constant already excites the only available direction.
5.2 Constant Vector Signal
Let \( n>1 \) and \( \phi(t)=v\neq0 \). Then
\[ G_{\phi}(\tau,T)=Tvv^{\mathsf T}. \]
This matrix has rank one, so it cannot dominate \( \alpha I_n \) for any positive \( \alpha \). A constant vector is therefore not PE of order \( n \) when \( n>1 \).
5.3 Rotating Two-Dimensional Regressor
Consider \( \phi(t)=[\sin t\;\;\cos t]^{\mathsf T} \) and choose \( T=2\pi \). Direct integration gives
\[ \begin{aligned} G_{\phi}(\tau,2\pi) &=\int_{\tau}^{\tau+2\pi} \begin{bmatrix} \sin^2t & \sin t\cos t\\ \sin t\cos t & \cos^2t \end{bmatrix}dt\\ &= \begin{bmatrix} \pi & 0\\ 0 & \pi \end{bmatrix} =\pi I_2. \end{aligned} \]
The result is independent of \( \tau \); therefore the regressor is PE with \( \alpha=\beta=\pi \).
5.4 Energetic but Rank-Deficient Regressor
Consider \( \phi(t)=[\sin t\;\;2\sin t]^{\mathsf T} \). It can be written as \( \phi(t)=v\sin t \) with \( v=[1\;\;2]^{\mathsf T} \). Hence
\[ G_{\phi}(\tau,T) =vv^{\mathsf T}\int_{\tau}^{\tau+T}\sin^2t\,dt, \]
whose rank is at most one for every window. The signal may have substantial total energy, but it never changes direction in regressor space and is not PE of order two.
6. Discrete-Time Persistent Excitation
For a sequence \( \phi_k\in\mathbb{R}^{n} \), define the finite-sum excitation Gramian
\[ G_{\phi}[i,N] =\sum_{k=i}^{i+N-1}\phi_k\phi_k^{\mathsf T}. \]
The sequence is PE of order \( n \) if there exist an integer \( N\ge1 \) and constants \( \alpha>0 \), \( \beta\ge\alpha \) such that
\[ \alpha I_n \preceq \sum_{k=i}^{i+N-1}\phi_k\phi_k^{\mathsf T} \preceq \beta I_n, \qquad \forall i\ge i_0. \]
Equivalently, for every \( z\in\mathbb{R}^{n} \),
\[ \alpha\|z\|^2 \le \sum_{k=i}^{i+N-1}(z^{\mathsf T}\phi_k)^2 \le \beta\|z\|^2. \]
A simple two-dimensional example is the repeating sequence \( e_1,e_2,e_1,e_2,\ldots \), where \( e_1=[1\;0]^{\mathsf T} \) and \( e_2=[0\;1]^{\mathsf T} \). Every two-sample window contains one copy of each basis vector, so
\[ G_{\phi}[i,2]=e_1e_1^{\mathsf T}+e_2e_2^{\mathsf T}=I_2. \]
Thus the sequence is PE with \( N=2 \) and \( \alpha=\beta=1 \).
7. Numerical PE Diagnostics
Suppose sampled data are available at \( t_k=t_0+k\Delta t \). For each candidate window, approximate the Gramian with a quadrature rule:
\[ \widehat G_j \approx \sum_{k=j}^{j+N-1}w_k\, \phi(t_k)\phi^{\mathsf T}(t_k), \qquad N\Delta t\approx T, \]
where \( w_k \) are rectangle- or trapezoidal-rule weights. Then compute
\[ \widehat\alpha =\min_j\lambda_{\min}(\widehat G_j), \qquad \widehat\beta =\max_j\lambda_{\max}(\widehat G_j). \]
A comfortably positive \( \widehat\alpha \) indicates uniform directional energy over the tested data horizon and chosen window length. The following qualifications are essential:
- A finite record cannot establish the universal condition for all future windows.
- The conclusion depends on the selected window length and sampling rate.
- Very small eigenvalues may reflect genuine weak excitation, numerical roundoff, poor scaling, or insufficient temporal resolution.
- A condition number \( \kappa(\widehat G_j)=\lambda_{\max}/\lambda_{\min} \) can reveal strongly anisotropic excitation even when the matrix is technically positive definite.
For implementation, it is good practice to symmetrize the computed matrix as \( (\widehat G_j+\widehat G_j^{\mathsf T})/2 \) before using a symmetric eigensolver.
8. Python Implementation
This implementation uses NumPy to form sliding-window Gramians and symmetric eigenvalues. The rotating regressor should produce a minimum eigenvalue near \( \pi \), whereas the fixed-direction regressor should produce a value near zero.
Chapter10_Lesson1.py
"""Chapter 10, Lesson 1: numerical tests for persistent excitation."""
from __future__ import annotations
import numpy as np
import matplotlib.pyplot as plt
def regressor_pe(t: np.ndarray) -> np.ndarray:
"""A two-dimensional candidate with rotating direction."""
return np.column_stack((np.sin(t), np.cos(t)))
def regressor_non_pe(t: np.ndarray) -> np.ndarray:
"""A bounded signal confined to one fixed direction."""
return np.column_stack((np.sin(t), 2.0 * np.sin(t)))
def window_gramian(phi: np.ndarray, time: np.ndarray, start: int, stop: int) -> np.ndarray:
"""Compute integral phi(t) phi(t)^T dt over one sampled window."""
segment = phi[start : stop + 1]
ts = time[start : stop + 1]
outer_products = np.einsum("ni,nj->nij", segment, segment)
return np.trapezoid(outer_products, ts, axis=0)
def sliding_pe_test(
phi: np.ndarray,
time: np.ndarray,
window_length: float,
) -> tuple[np.ndarray, np.ndarray, np.ndarray]:
"""Return window times and the minimum/maximum Gramian eigenvalues."""
dt = float(time[1] - time[0])
samples = max(2, int(round(window_length / dt)))
starts = range(0, len(time) - samples)
window_times: list[float] = []
lambda_min: list[float] = []
lambda_max: list[float] = []
for start in starts:
stop = start + samples
gramian = window_gramian(phi, time, start, stop)
eigenvalues = np.linalg.eigvalsh(gramian)
window_times.append(time[start])
lambda_min.append(eigenvalues[0])
lambda_max.append(eigenvalues[-1])
return (
np.asarray(window_times),
np.asarray(lambda_min),
np.asarray(lambda_max),
)
def report(name: str, lambda_min: np.ndarray, lambda_max: np.ndarray) -> None:
alpha_est = float(np.min(lambda_min))
beta_est = float(np.max(lambda_max))
tolerance = 1.0e-8
print(f"{name}: estimated alpha = {alpha_est:.8f}, beta = {beta_est:.8f}")
print(f"{name}: numerically PE on tested horizon = {alpha_est > tolerance}")
def main() -> None:
dt = 0.01
time = np.arange(0.0, 20.0 + dt, dt)
window_length = 2.0 * np.pi
phi_pe = regressor_pe(time)
phi_non_pe = regressor_non_pe(time)
tw_pe, lmin_pe, lmax_pe = sliding_pe_test(phi_pe, time, window_length)
tw_np, lmin_np, lmax_np = sliding_pe_test(phi_non_pe, time, window_length)
report("Rotating regressor", lmin_pe, lmax_pe)
report("Fixed-direction regressor", lmin_np, lmax_np)
plt.figure()
plt.plot(tw_pe, lmin_pe, label="PE: minimum eigenvalue")
plt.plot(tw_np, lmin_np, label="Non-PE: minimum eigenvalue")
plt.xlabel("Window start time")
plt.ylabel("Minimum eigenvalue of excitation Gramian")
plt.title("Sliding-window numerical PE diagnostic")
plt.grid(True)
plt.legend()
plt.tight_layout()
plt.show()
if __name__ == "__main__":
main()
9. C++ Implementation
The C++ version uses only the standard library. Because the examples are two-dimensional, the eigenvalues of a symmetric \( 2\times2 \) Gramian are evaluated analytically.
Chapter10_Lesson1.cpp
#include <algorithm>
#include <array>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <limits>
#include <string>
#include <utility>
#include <vector>
struct EigenvalueBounds {
double minimum;
double maximum;
};
using Vector2 = std::array<double, 2>;
std::vector<Vector2> buildRegressor(const std::vector<double>& time, bool persistentlyExciting) {
std::vector<Vector2> phi;
phi.reserve(time.size());
for (double t : time) {
if (persistentlyExciting) {
phi.push_back({std::sin(t), std::cos(t)});
} else {
phi.push_back({std::sin(t), 2.0 * std::sin(t)});
}
}
return phi;
}
EigenvalueBounds eigenvaluesSymmetric2x2(double a, double b, double d) {
const double trace = a + d;
const double discriminant = std::sqrt((a - d) * (a - d) + 4.0 * b * b);
return {(trace - discriminant) / 2.0, (trace + discriminant) / 2.0};
}
EigenvalueBounds windowGramianEigenvalues(
const std::vector<Vector2>& phi,
const std::vector<double>& time,
std::size_t start,
std::size_t stop) {
double g11 = 0.0;
double g12 = 0.0;
double g22 = 0.0;
for (std::size_t k = start; k < stop; ++k) {
const double dt = time[k + 1] - time[k];
const auto& p0 = phi[k];
const auto& p1 = phi[k + 1];
g11 += 0.5 * dt * (p0[0] * p0[0] + p1[0] * p1[0]);
g12 += 0.5 * dt * (p0[0] * p0[1] + p1[0] * p1[1]);
g22 += 0.5 * dt * (p0[1] * p0[1] + p1[1] * p1[1]);
}
return eigenvaluesSymmetric2x2(g11, g12, g22);
}
void runTest(
const std::string& name,
const std::vector<Vector2>& phi,
const std::vector<double>& time,
std::size_t windowSamples) {
double alphaEstimate = std::numeric_limits<double>::infinity();
double betaEstimate = 0.0;
for (std::size_t start = 0; start + windowSamples < time.size(); ++start) {
const std::size_t stop = start + windowSamples;
const EigenvalueBounds eig = windowGramianEigenvalues(phi, time, start, stop);
alphaEstimate = std::min(alphaEstimate, eig.minimum);
betaEstimate = std::max(betaEstimate, eig.maximum);
}
constexpr double tolerance = 1.0e-8;
std::cout << name << ": estimated alpha = " << std::setprecision(10)
<< alphaEstimate << ", beta = " << betaEstimate << '\n';
std::cout << name << ": numerically PE on tested horizon = "
<< std::boolalpha << (alphaEstimate > tolerance) << "\n\n";
}
int main() {
constexpr double pi = 3.14159265358979323846;
constexpr double dt = 0.01;
constexpr double finalTime = 20.0;
const std::size_t count = static_cast<std::size_t>(std::round(finalTime / dt)) + 1;
std::vector<double> time(count);
for (std::size_t k = 0; k < count; ++k) {
time[k] = static_cast<double>(k) * dt;
}
const std::size_t windowSamples = static_cast<std::size_t>(std::round(2.0 * pi / dt));
const auto phiPE = buildRegressor(time, true);
const auto phiNonPE = buildRegressor(time, false);
runTest("Rotating regressor", phiPE, time, windowSamples);
runTest("Fixed-direction regressor", phiNonPE, time, windowSamples);
return 0;
}
10. Java Implementation
The Java program mirrors the C++ calculation and requires no external numerical package for this two-dimensional demonstration.
Chapter10_Lesson1.java
import java.util.Locale;
public final class Chapter10_Lesson1 {
private static final double PI = Math.PI;
private static double[][] buildRegressor(double[] time, boolean persistentlyExciting) {
double[][] phi = new double[time.length][2];
for (int k = 0; k < time.length; k++) {
double s = Math.sin(time[k]);
if (persistentlyExciting) {
phi[k][0] = s;
phi[k][1] = Math.cos(time[k]);
} else {
phi[k][0] = s;
phi[k][1] = 2.0 * s;
}
}
return phi;
}
private static double[] eigenvaluesSymmetric2x2(double a, double b, double d) {
double trace = a + d;
double discriminant = Math.sqrt((a - d) * (a - d) + 4.0 * b * b);
return new double[] {(trace - discriminant) / 2.0, (trace + discriminant) / 2.0};
}
private static double[] windowEigenvalues(
double[][] phi, double[] time, int start, int stop) {
double g11 = 0.0;
double g12 = 0.0;
double g22 = 0.0;
for (int k = start; k < stop; k++) {
double dt = time[k + 1] - time[k];
double[] p0 = phi[k];
double[] p1 = phi[k + 1];
g11 += 0.5 * dt * (p0[0] * p0[0] + p1[0] * p1[0]);
g12 += 0.5 * dt * (p0[0] * p0[1] + p1[0] * p1[1]);
g22 += 0.5 * dt * (p0[1] * p0[1] + p1[1] * p1[1]);
}
return eigenvaluesSymmetric2x2(g11, g12, g22);
}
private static void runTest(
String name, double[][] phi, double[] time, int windowSamples) {
double alphaEstimate = Double.POSITIVE_INFINITY;
double betaEstimate = 0.0;
for (int start = 0; start + windowSamples < time.length; start++) {
int stop = start + windowSamples;
double[] eig = windowEigenvalues(phi, time, start, stop);
alphaEstimate = Math.min(alphaEstimate, eig[0]);
betaEstimate = Math.max(betaEstimate, eig[1]);
}
boolean numericallyPE = alphaEstimate > 1.0e-8;
System.out.printf(Locale.US,
"%s: estimated alpha = %.10f, beta = %.10f%n",
name, alphaEstimate, betaEstimate);
System.out.printf("%s: numerically PE on tested horizon = %s%n%n",
name, numericallyPE);
}
public static void main(String[] args) {
double dt = 0.01;
double finalTime = 20.0;
int count = (int) Math.round(finalTime / dt) + 1;
double[] time = new double[count];
for (int k = 0; k < count; k++) {
time[k] = k * dt;
}
int windowSamples = (int) Math.round(2.0 * PI / dt);
double[][] phiPE = buildRegressor(time, true);
double[][] phiNonPE = buildRegressor(time, false);
runTest("Rotating regressor", phiPE, time, windowSamples);
runTest("Fixed-direction regressor", phiNonPE, time, windowSamples);
}
}
11. MATLAB and Simulink Implementation
The MATLAB script computes the same sliding-window eigenvalue
diagnostic. Setting createSimulinkModel to
true generates a Simulink model named
Chapter10_Lesson1_PE_Model.slx with sine and cosine
sources, a regressor mux, and a workspace sink. This avoids distributing
a version-specific binary model while still providing a reproducible
Simulink construction.
Chapter10_Lesson1.m
%% Chapter10_Lesson1.m
% Numerical persistent-excitation diagnostics and optional Simulink model.
clear; close all; clc;
Ts = 0.01;
t = (0:Ts:20).';
Twindow = 2*pi;
windowSamples = round(Twindow/Ts);
phiPE = [sin(t), cos(t)];
phiNonPE = [sin(t), 2*sin(t)];
[twPE, lambdaMinPE, lambdaMaxPE] = slidingPETest(phiPE, t, windowSamples);
[twNP, lambdaMinNP, lambdaMaxNP] = slidingPETest(phiNonPE, t, windowSamples);
reportPE('Rotating regressor', lambdaMinPE, lambdaMaxPE);
reportPE('Fixed-direction regressor', lambdaMinNP, lambdaMaxNP);
figure;
plot(twPE, lambdaMinPE, 'LineWidth', 1.2); hold on;
plot(twNP, lambdaMinNP, 'LineWidth', 1.2);
grid on;
xlabel('Window start time');
ylabel('Minimum eigenvalue of excitation Gramian');
title('Sliding-window numerical PE diagnostic');
legend('PE candidate', 'Non-PE candidate', 'Location', 'best');
% Set this flag to true to generate Chapter10_Lesson1_PE_Model.slx.
createSimulinkModel = false;
if createSimulinkModel
buildPESimulinkModel('Chapter10_Lesson1_PE_Model');
end
function [tw, lambdaMin, lambdaMax] = slidingPETest(phi, t, windowSamples)
numberOfWindows = length(t) - windowSamples;
tw = zeros(numberOfWindows, 1);
lambdaMin = zeros(numberOfWindows, 1);
lambdaMax = zeros(numberOfWindows, 1);
for startIndex = 1:numberOfWindows
stopIndex = startIndex + windowSamples;
segment = phi(startIndex:stopIndex, :);
ts = t(startIndex:stopIndex);
G = zeros(size(phi, 2));
for i = 1:size(phi, 2)
for j = 1:size(phi, 2)
G(i, j) = trapz(ts, segment(:, i).*segment(:, j));
end
end
eigenvalues = eig((G + G.')/2);
tw(startIndex) = t(startIndex);
lambdaMin(startIndex) = min(eigenvalues);
lambdaMax(startIndex) = max(eigenvalues);
end
end
function reportPE(name, lambdaMin, lambdaMax)
alphaEstimate = min(lambdaMin);
betaEstimate = max(lambdaMax);
fprintf('%s: estimated alpha = %.10f, beta = %.10f\n', ...
name, alphaEstimate, betaEstimate);
fprintf('%s: numerically PE on tested horizon = %d\n\n', ...
name, alphaEstimate > 1.0e-8);
end
function buildPESimulinkModel(modelName)
modelName = string(modelName);
if ~license('test', 'Simulink')
error('Simulink is not available in this MATLAB installation.');
end
if bdIsLoaded(modelName)
close_system(modelName, 0);
end
if isfile(modelName + ".slx")
delete(modelName + ".slx");
end
new_system(modelName);
open_system(modelName);
add_block('simulink/Sources/Sine Wave', modelName + "/sin(t)", ...
'Position', [40 40 110 70], 'Amplitude', '1', 'Frequency', '1');
add_block('simulink/Sources/Sine Wave', modelName + "/cos(t)", ...
'Position', [40 110 110 140], 'Amplitude', '1', 'Frequency', '1', ...
'Phase', 'pi/2');
add_block('simulink/Signal Routing/Mux', modelName + "/Regressor Mux", ...
'Inputs', '2', 'Position', [170 55 175 125]);
add_block('simulink/Sinks/To Workspace', modelName + "/phiPE", ...
'VariableName', 'phiPE_sim', 'SaveFormat', 'Structure With Time', ...
'Position', [240 75 340 105]);
add_line(modelName, 'sin(t)/1', 'Regressor Mux/1');
add_line(modelName, 'cos(t)/1', 'Regressor Mux/2');
add_line(modelName, 'Regressor Mux/1', 'phiPE/1');
set_param(modelName, 'StopTime', '20');
save_system(modelName);
fprintf('Created %s.slx. Run it and apply slidingPETest to phiPE_sim.\n', modelName);
end
12. Wolfram Mathematica Implementation
The notebook expression uses symbolic regressor definitions,
NIntegrate, and Eigenvalues to estimate the
minimum excitation eigenvalue over a grid of window start times.
Chapter10_Lesson1.nb
Notebook[{
Cell["Chapter 10, Lesson 1: Persistent Excitation", "Title"],
Cell["Sliding-window excitation-Gramian test", "Section"],
Cell[BoxData[
RowBox[{"ClearAll", "[", "\"Global`*\"", "]"}]], "Input"],
Cell[BoxData[
RowBox[{"dt", "=", "0.01", ";", " ", "tFinal", "=", "20.0", ";", " ",
"Twindow", "=", RowBox[{"2", " ", "Pi"}], ";"}]], "Input"],
Cell[BoxData[
RowBox[{"phiPE", "[", "t_", "]", ":=", RowBox[{"{", RowBox[{RowBox[{"Sin", "[", "t", "]"}], ",", RowBox[{"Cos", "[", "t", "]"}]}], "}"}]}]], "Input"],
Cell[BoxData[
RowBox[{"phiNonPE", "[", "t_", "]", ":=", RowBox[{"{", RowBox[{RowBox[{"Sin", "[", "t", "]"}], ",", RowBox[{"2", " ", RowBox[{"Sin", "[", "t", "]"}]}]}], "}"}]}]], "Input"],
Cell[BoxData[
RowBox[{"gramian", "[", RowBox[{"phi_", ",", "tau_"}], "]", ":=",
RowBox[{"NIntegrate", "[",
RowBox[{RowBox[{"Outer", "[", RowBox[{"Times", ",", RowBox[{"phi", "[", "s", "]"}], ",", RowBox[{"phi", "[", "s", "]"}]}], "]"}], ",",
RowBox[{"{", RowBox[{"s", ",", "tau", ",", RowBox[{"tau", "+", "Twindow"}]}], "}"}]}], "]"}]}]], "Input"],
Cell[BoxData[
RowBox[{"minimumEigenvalue", "[", RowBox[{"phi_", ",", "tau_"}], "]", ":=",
RowBox[{"Min", "[", RowBox[{"Eigenvalues", "[", RowBox[{"gramian", "[", RowBox[{"phi", ",", "tau"}], "]"}], "]"}], "]"}]}]], "Input"],
Cell[BoxData[
RowBox[{"tauGrid", "=", RowBox[{"Range", "[", RowBox[{"0", ",", RowBox[{"tFinal", "-", "Twindow"}], ",", "0.1"}], "]"}], ";"}]], "Input"],
Cell[BoxData[
RowBox[{"peValues", "=", RowBox[{RowBox[{"minimumEigenvalue", "[", RowBox[{"phiPE", ",", "#"}], "]"}], "&"}], "/@", "tauGrid"}]], "Input"],
Cell[BoxData[
RowBox[{"nonPEValues", "=", RowBox[{RowBox[{"minimumEigenvalue", "[", RowBox[{"phiNonPE", ",", "#"}], "]"}], "&"}], "/@", "tauGrid"}]], "Input"],
Cell[BoxData[
RowBox[{"Print", "[", RowBox[{"\"PE alpha estimate: \"", ",", RowBox[{"Min", "[", "peValues", "]"}]}], "]"}]], "Input"],
Cell[BoxData[
RowBox[{"Print", "[", RowBox[{"\"Non-PE alpha estimate: \"", ",", RowBox[{"Min", "[", "nonPEValues", "]"}]}], "]"}]], "Input"],
Cell[BoxData[
RowBox[{"ListLinePlot", "[",
RowBox[{RowBox[{"{", RowBox[{RowBox[{"Transpose", "[", RowBox[{"{", RowBox[{"tauGrid", ",", "peValues"}], "}"}], "]"}], ",", RowBox[{"Transpose", "[", RowBox[{"{", RowBox[{"tauGrid", ",", "nonPEValues"}], "}"}], "]"}]}], "}"}], ",",
RowBox[{"PlotLegends", "->", RowBox[{"{", RowBox[{"\"PE candidate\"", ",", "\"Non-PE candidate\""}], "}"}]}], ",",
RowBox[{"AxesLabel", "->", RowBox[{"{", RowBox[{"\"window start\"", ",", "\"minimum eigenvalue\""}], "}"}]}], ",",
RowBox[{"PlotRange", "->", "All"}]}], "]"}]], "Input"]
}, WindowTitle -> "Chapter10_Lesson1"]
13. Problems and Solutions
Problem 1 (Exact PE Bounds): Let \( \phi(t)=[a\sin(\omega t)\;\;b\cos(\omega t)]^{\mathsf T} \), where \( a\neq0 \), \( b\neq0 \), and \( \omega\neq0 \). Find valid PE constants using one complete period.
Solution: Select \( T=2\pi/|\omega| \). Over one complete period,
\[ \int_{\tau}^{\tau+T}\sin^2(\omega t)\,dt =\int_{\tau}^{\tau+T}\cos^2(\omega t)\,dt =\frac{T}{2}, \]
and the cross term integrates to zero. Therefore,
\[ G_{\phi}(\tau,T) =\frac{T}{2} \begin{bmatrix} a^2 & 0\\ 0 & b^2 \end{bmatrix}. \]
Valid constants are
\[ \alpha=\frac{T}{2}\min\{a^2,b^2\}, \qquad \beta=\frac{T}{2}\max\{a^2,b^2\}. \]
Problem 2 (Total Energy Is Insufficient): Show that \( \phi(t)=v s(t) \), with fixed \( v\in\mathbb{R}^{n} \) and \( n>1 \), cannot be PE of order \( n \), even if \( \int_{\tau}^{\tau+T}s^2(t)dt \) is uniformly bounded below.
Solution: The Gramian is
\[ G_{\phi}(\tau,T) =vv^{\mathsf T}\int_{\tau}^{\tau+T}s^2(t)\,dt. \]
Since \( vv^{\mathsf T} \) has rank one, the Gramian has at least \( n-1 \) zero eigenvalues. Choose any nonzero \( z \) orthogonal to \( v \). Then
\[ \int_{\tau}^{\tau+T}(z^{\mathsf T}\phi(t))^2dt =\int_{\tau}^{\tau+T}(z^{\mathsf T}v)^2s^2(t)dt=0, \]
contradicting the positive lower bound required by PE. Thus temporal energy alone cannot replace directional richness.
Problem 3 (Coordinate Transformation): Suppose \( \phi \) is PE with constants \( T,\alpha,\beta \), and define \( \psi=M\phi \) for a constant nonsingular matrix \( M \). Prove that \( \psi \) is PE and give valid bounds.
Solution: Since
\[ G_{\psi}=M G_{\phi}M^{\mathsf T}, \]
for arbitrary \( z \),
\[ \begin{aligned} z^{\mathsf T}G_{\psi}z &=(M^{\mathsf T}z)^{\mathsf T}G_{\phi}(M^{\mathsf T}z)\\ &\ge\alpha\|M^{\mathsf T}z\|^2 \ge\alpha\sigma_{\min}^2(M)\|z\|^2, \end{aligned} \]
and similarly,
\[ z^{\mathsf T}G_{\psi}z \le\beta\sigma_{\max}^2(M)\|z\|^2. \]
Hence valid transformed bounds are \( \alpha_{\psi}=\alpha\sigma_{\min}^2(M) \) and \( \beta_{\psi}=\beta\sigma_{\max}^2(M) \).
Problem 4 (Discrete-Time Basis Sequence): Let \( \phi_{2m}=e_1 \) and \( \phi_{2m+1}=e_2 \) in \( \mathbb{R}^{2} \). Verify PE and determine the smallest useful window length.
Solution: A one-sample window contains only one basis vector and produces a rank-one Gramian, so \( N=1 \) is insufficient. Every two-sample window contains both basis vectors:
\[ \sum_{k=i}^{i+1}\phi_k\phi_k^{\mathsf T} =e_1e_1^{\mathsf T}+e_2e_2^{\mathsf T}=I_2. \]
Thus \( N=2 \) is the smallest useful window and valid bounds are \( \alpha=\beta=1 \).
Problem 5 (Interpreting a Numerical Test): A finite simulation gives \( \widehat\alpha=2.5\times10^{-5} \) over all tested windows. Can one conclude that the analytical regressor is PE?
Solution: No definitive infinite-horizon conclusion is possible from finite data alone. The positive estimate shows that the sampled Gramians were positive definite on the tested horizon, using the chosen window length, integration method, and sampling rate. The small magnitude also calls for scaling and conditioning checks. A rigorous PE proof must establish one positive lower bound for every admissible future window, usually by analytic structure such as periodicity, exact integration, or a theorem connecting the generating system to the regressor.
14. Summary
Persistent excitation is a uniform finite-window information condition. A regressor is PE when its excitation Gramian remains bounded above and, critically, uniformly positive definite in every window of one fixed length. The equivalent directional statement requires a positive amount of squared projection energy in every nonzero parameter direction. PE is stronger than nonzero signal energy, stronger than full rank in a single interval, invariant under nonsingular coordinate changes, and has direct continuous- and discrete-time forms. Numerical sliding-window eigenvalue tests are useful diagnostics, but analytical arguments are required for a true infinite-horizon proof. Lesson 2 uses this definition to study why PE is a central sufficient condition for parameter convergence.
15. References
- Morgan, A.P., & Narendra, K.S. (1977). On the uniform asymptotic stability of certain linear nonautonomous differential equations. SIAM Journal on Control and Optimization, 15(1), 5–24.
- Anderson, B.D.O. (1977). Exponential stability of linear equations arising in adaptive identification. IEEE Transactions on Automatic Control, 22(1), 83–88.
- Anderson, B.D.O. (1985). Adaptive systems, lack of persistency of excitation and bursting phenomena. Automatica, 21(3), 247–258.
- Green, M., & Moore, J.B. (1986). Persistence of excitation in linear systems. Systems & Control Letters, 7(5), 351–360.
- Boyd, S., & Sastry, S.S. (1986). Necessary and sufficient conditions for parameter convergence in adaptive control. Automatica, 22(6), 629–639.
- Narendra, K.S., & Annaswamy, A.M. (1987). Persistent excitation in adaptive systems. International Journal of Control, 45(1), 127–160.
Help keep these engineering tutorials free and growing
If these lessons, examples, and project pages help you, a small donation supports the continued creation and improvement of free control, robotics, software, and engineering education resources.
Created and maintained by Abolfazl Mohammadijoo.