Contents
MORLAB Demo: Additive Decomposition
This demo script contains the application of the MORLAB additive decomposition routines.
% % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU Affero General Public License as published % by the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU Affero General Public License for more details. % % You should have received a copy of the GNU Affero General Public License % along with this program. If not, see <http://www.gnu.org/licenses/>. % % Copyright (C) 2006-2019 Peter Benner, Steffen W. R. Werner %
Standard System Case
The MORLAB toolbox implements additive decomposition methods for first-order system types, e.g., considering the dynamical system
x'(t) = A*x(t) + B*u(t), y(t) = C*x(t) + D*u(t),
with the matrix A having possible stable and anti-stable eigenvalues. The corresponding transfer function to this system is then given by
G(s) = C*inv(s*I - A)*B + D.
In additive decomposition, the system is transformed in a way such that
G(s) = G_s(s) + G_a(s),
with G_s(s) the transfer function with the stable system part and G_a(s) the transfer function of the anti-stable part.
For demonstration reasons we load a prepared data file containing an unstable standard system:
if exist('OCTAVE_VERSION', 'builtin') orig_warn = warning('off', 'Octave:data-file-in-path'); load morlab_data_std_unstab.mat; warning(orig_warn); else load morlab_data_std_unstab.mat; end
The matrix A has 90 stable and 10 anti-stable eigenvalues. The additive decomposition is performed by calling the appropriate MORLAB routine. Therefor, we are constructing first the system as struct.
sys = struct( ... 'A', A, ... 'B', B, ... 'C', C, ... 'D', D); [sys_dec, info] = ml_ct_ss_adtf(sys);
The struct sys_dec now contains the matrices corresponding to the stable and anti-stable parts and info is a struct with information about the underlying methods.
disp(sys_dec); disp(info);
A: [90x90 double] B: [90x3 double] C: [2x90 double] D: [2x3 double] Au: [10x10 double] Bu: [10x3 double] Cu: [2x10 double] infoSTABSIGNM: [1x1 struct] infoSTABSYLV: [1x1 struct] Ns: 90 Nu: 10 T: [] W: []
We see in the info struct that the method found the 90 stable and 10 anti-stable eigenvalues. The corresponding system matrices are in sys_dec as the stable part denoted as the original system with A, B, C, and D, and the anti-stable part with Au, Bu and Cu.
We saw in the info struct also the fields T and W, in those the underlying transformation matrices can be stored. Therefor, we need to activate the optional parameter StoreProjection.
opts = struct('StoreProjection', 1);
[sys_dec, info] = ml_ct_ss_adtf(sys, opts);
disp(info);
infoSTABSIGNM: [1x1 struct] infoSTABSYLV: [1x1 struct] Ns: 90 Nu: 10 T: [100x100 double] W: [100x100 double]
Now the T and W matrices are stored in info and can be used as state-space transformation such that
blkdiag(sys_dec.A, sys_dec.Au) = info.W * sys.A * info.T [sys_dec.B; sys_dec.Bu] = info.W * sys.B [sys_dec.C, sys_dec.Cu] = sys.C * info.T.
Descriptor System Case
The additive decomposition changes a bit in case of descriptor systems, e.g.,
E*x'(t) = A*x(t) + B*u(t), y(t) = C*x(t) + D*u(t),
with the matrix pencil s*E-A having possible stable, anti-stable and infinite eigenvalues. The corresponding transfer function to this system is then given by
G(s) = C*inv(s*E - A)*B + D.
In additive decomposition, those systems are transformed in a way such that
G(s) = G_s(s) + G_a(s) + P(s),
with G_s(s) the transfer function with the stable system part, G_a(s) the transfer function of the anti-stable part and P(s) the polynomial part.
For demonstration reasons we load a prepared data file containing an unstable descriptor system:
if exist('OCTAVE_VERSION', 'builtin') orig_warn = warning('off', 'Octave:data-file-in-path'); load morlab_data_desc_infunstab.mat; warning(orig_warn); else load morlab_data_desc_infunstab.mat; end
The pencil s*E-A has 80 stable, 10 anti-stable and 10 infinite eigenvalues. As in the standard case, we need to construct the system as struct and call the additive decomposition routine.
sys = struct( ... 'A', A, ... 'B', B, ... 'C', C, ... 'D', D, ... 'E', E); [sys_dec2, info] = ml_ct_dss_adtf(sys); disp(sys_dec2); disp(info);
A: [80x80 double] B: [80x3 double] C: [2x80 double] D: [2x3 double] E: [80x80 double] Ainf: [10x10 double] Einf: [10x10 double] Binf: [10x3 double] Cinf: [2x10 double] Au: [10x10 double] Eu: [10x10 double] Bu: [10x3 double] Cu: [2x10 double] infoINFDISK: [1x1 struct] infoSTABSIGNM: [1x1 struct] Ninf: 10 Ns: 80 Nu: 10 T: [] W: []
We can see in the info struct that the algorithm found the appropriate numbers of eigenvalues and the sys_desc2 is containing now the following groups of matrices: A, B, C, D, E is the stable system part, Au, Bu, Cu, Eu is the anti-stable and Ainf, Binf, Cinf, Einf the polynomial one with Einf being nilpotent.
As in the standard case, we can get the transformation matrices by setting the optional parameter StoreProjection.
opts = struct('StoreProjection', 1);
[sys_dec2, info] = ml_ct_dss_adtf(sys, opts);
disp(info);
infoINFDISK: [1x1 struct] infoSTABSIGNM: [1x1 struct] Ninf: 10 Ns: 80 Nu: 10 T: [100x100 double] W: [100x100 double]
Using the T and W matrices from the info struct as state-space transformation then gives:
blkdiag(sys_dec2.A, sys_dec2.Au, sys_dec2.Ainf) = info.W * sys.A * info.T [sys_dec2.B; sys_dec2.Bu; sysa_dec2.Binf] = info.W * sys.B [sys_dec2.C, sys_dec2.Cu, sys_dec2.Cinf] = sys.C * info.T blkdiag(sys_dec2.E, sys_dec2.Eu, sys_dec2.Einf) = info.W * sys.E * info.T
Remarks
- All additive decomposition routines are more or less equivalent to each other, which means that all usage examples here also apply to the other routines.
- The discrete-time additive decomposition methods work basically the same with respect to discrete-time stability.
See Also