ctrb function returns NaN or inf when dealing with large systems
Show older comments
I’m currently working with continuous-time, large state-space systems — specifically, systems with a number of states on the order of 10^3, and numbers of inputs and outputs on the order of 10^2.
I’m trying to analyze the reachability and observability properties of these systems. To that end, I’ve been using MATLAB’s ctrb function, which, according to the documentation, returns the reachability matrix. However, I’ve encountered a major issue: the resulting matrix (Co) contains a significant number of NaN and Inf entries.
For reference, in one example the matrix Co has dimensions 1,624 x 311,808, resulting in a total of 506,376,192 elements. Of these:
- 466,771,919 entries (92.18%) are NaN, counted with sum(isnan(Co), 'all')
- 37,732 entries (0.0075%) are Inf or -Inf, counted with sum(isinf(Co), 'all')
Has anyone encountered a similar issue when working with large-scale systems?
How did you handle it or work around it?
Any suggestions, tips, or alternative methods would be highly appreciated!
9 Comments
Just a test. It seems that the number of states cannot exceed 348!
Case 1:
n = 348; % number of states
p = - ones(1, n); % 100% stable poles
G = zpk([], p, prod(p)); % transfer function
% sys = canon(G, 'companion') % The "canon" command failed because the controllability matrix is nearly singular.
sys = compreal(G); % convert ot state-space
rk = rank(ctrb(sys.A, sys.B))
Case 2:
n = 349; % number of states
p = - ones(1, n); % 100% stable poles
G = zpk([], p, prod(p)); % transfer function
sys = compreal(G); % convert ot state-space
rk = rank(ctrb(sys.A, sys.B))
Case 3: An unexplainable result?
n = 250; % number of states
sys = rss(n); % generate random continuous-time state-space
Tf = isstable(sys)
rk = rank(ctrb(sys.A, sys.B))
Mathieu NOE
on 7 Apr 2025
Corby
on 7 Apr 2025
Mathieu NOE
on 7 Apr 2025
Sure , a reduced order system cannot be compared or taken as 100% "equivalent" to the full system. Now the engineer must ask himself what does it mean to remove the poorly reachable / observable states ? Is it still physically meaningfull ?
Case 5: The ctrb() function can handle systems with a number of states greater than 1,000.
n = 2000; % number of states
A0 = zeros(n, 1);
A1 = eye(n);
A1(:,n) = [];
A = [A0, A1]; % State matrix
B = zeros(sqrt(numel(A)), 1);
B(end) = 1; % Input matrix
Co = ctrb(A, B); % Controllability matrix
rk = rank(Co) % expect to return rk = n
Hi Corby,
I think the fundamental problem that forming the controllability matrix necessarily means raising the system matrix to a large power, which at some point will overflow if the spectral radius is greater than unity and n is large enough. I think you touched on this issue in this comment, though I don't think that necessarily means the system matrix is poorly conditioned.
For example
rng(100);
n = 250;
sys = rss(n,1,5);
size(sys)
rss should generate a stable system
Tf = isstable(sys)
but it doesn't because
max(real(eig(sys.a)))
So shift the A matrix to ensure stability (do you know your system is stable?)
sys.a = sys.a - eye(n);
max(real(eig(sys.a)))
We see that raising the system matrix to the i'th power breaks down at i = 195
for ii = 1:n
if any(isnan(sys.A^ii),'all') || any(isinf(sys.A^ii),'all')
break
end
end
ii
At i = 194, elements are getting close to realmax
[max(sys.A^(ii-1),[],'all') , min(sys.A^(ii-1),[],'all'), realmax]
The spectral radius of the system matrix is
r = max(abs(eig(sys.A)))
The spectral radius of A^n is r^n, so we might estimate the maximum achievable n as
nlimit = log(realmax)/log(r)
which at least tracks nicely with the result above, though I don't really know how rigorous that really is.
Anyway, that leaves us searching for other ways to test for controllability.
One option is to compute the controllability Gramian
Wc = gram(sys,'c');
which at least is returning a finite result
all(isfinite(Wc),'all')
By definiton the Gramian is symmetric
issymmetric(Wc)
It it positive definite if (A,B) are a controllable pair.
The simple test would be
e = eig(Wc);
all(imag(e)==0)
min(e)
Taken literally, that means the systme is not controllable (would that be miraculous for a randomly generated system?).
try
C = chol(Wc)
catch ME
ME.message
end
Does that mean they system isn't controllable? Or does that mean we are suffering from numerical issues in one of the steps along the way?
Another option might be to tranform the system to modal form. I think a sufficient condition for controllability is that every row of the transformed B matrix has at least one non-zero entry (check that)
sysm = modalreal(sys);
all(any(sysm.b,2))
Of course, here we could have the problem where a value is very close to zero. Here that's not the case.
min(min(abs(sysm.b),[],2))
In any case, there might be options besides checking the controllability matrix. Also, consider looking into other numerical conditioning schemes.
Seems like a hard problem in general.
If you don't mind, what kind of system is being modeled?
More importantly, why is it important to know if the system is controllable? What would that information be used for if it could be accurately ascertained?
Corby
on 8 Apr 2025
Accepted Answer
More Answers (0)
Categories
Find more on Matrix Computations in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!