7017
|
1 ## Copyright (C) 1996, 2000, 2004, 2005, 2006, 2007 |
|
2 ## Auburn University. All rights reserved. |
3430
|
3 ## |
|
4 ## This file is part of Octave. |
|
5 ## |
|
6 ## Octave is free software; you can redistribute it and/or modify it |
7016
|
7 ## under the terms of the GNU General Public License as published by |
|
8 ## the Free Software Foundation; either version 3 of the License, or (at |
|
9 ## your option) any later version. |
3430
|
10 ## |
7016
|
11 ## Octave is distributed in the hope that it will be useful, but |
|
12 ## WITHOUT ANY WARRANTY; without even the implied warranty of |
|
13 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
14 ## General Public License for more details. |
3430
|
15 ## |
|
16 ## You should have received a copy of the GNU General Public License |
7016
|
17 ## along with Octave; see the file COPYING. If not, see |
|
18 ## <http://www.gnu.org/licenses/>. |
3430
|
19 |
3439
|
20 ## -*- texinfo -*- |
|
21 ## @deftypefn {Function File} {[@var{retsys}, @var{nc}, @var{no}] =} sysmin (@var{sys}, @var{flg}) |
5016
|
22 ## Returns a minimal (or reduced order) system |
|
23 ## |
|
24 ## @strong{Inputs} |
|
25 ## @table @var |
|
26 ## @item sys |
|
27 ## System data structure |
|
28 ## @item flg |
|
29 ## When equal to 0 (default value), returns minimal system, |
|
30 ## in which state names are lost; when equal to 1, returns system |
|
31 ## with physical states removed that are either uncontrollable or |
|
32 ## unobservable (cannot reduce further without discarding physical |
|
33 ## meaning of states). |
|
34 ## @end table |
|
35 ## @strong{Outputs} |
|
36 ## @table @var |
|
37 ## @item retsys |
|
38 ## Returned system. |
|
39 ## @item nc |
|
40 ## Number of controllable states in the returned system. |
|
41 ## @item no |
|
42 ## Number of observable states in the returned system. |
|
43 ## @item cflg |
|
44 ## @code{is_controllable(retsys)}. |
|
45 ## @item oflg |
|
46 ## @code{is_observable(retsys)}. |
|
47 ## @end table |
3439
|
48 ## @end deftypefn |
3430
|
49 |
|
50 ## Author: A. S. Hodel <a.s.hodel@eng.auburn.edu> |
|
51 |
3439
|
52 function [retsys, nc, no, cflg, oflg] = sysmin (sys, flg) |
3430
|
53 |
7135
|
54 switch (nargin) |
|
55 case 1 |
|
56 flg = 0; |
|
57 case 2 |
|
58 jnk = flg; # dummy operation |
3430
|
59 otherwise, |
6046
|
60 print_usage (); |
3430
|
61 endswitch |
7135
|
62 |
|
63 dflg = is_digital (sys, 2); |
|
64 |
|
65 [n, nz, m, p] = sysdimensions (sys); |
|
66 |
|
67 if (n*nz > 0) |
3430
|
68 # both continuous and discrete states |
7135
|
69 [aa, bb, cc, dd, tsam, n, nz, stnam, innam, outnam, yd] = sys2ss (sys); |
3430
|
70 crng = 1:n; |
|
71 drng = n+(1:nz); |
|
72 |
|
73 # get minimal realization of continuous part |
|
74 Ac = aa(crng,crng); |
|
75 Acd = aa(crng,drng); |
|
76 Adc = aa(drng,crng); |
|
77 Ad = aa(drng,drng); |
|
78 Bc = bb(crng,:); |
|
79 Bd = bb(drng,:); |
|
80 Cc = cc(:,crng); |
|
81 Cd = cc(:,drng); |
|
82 |
|
83 cstnam = stnam(crng); |
|
84 dstnam = stnam(drng); |
7135
|
85 cinnam = __sysconcat__ (innam, stnam(drng)); |
|
86 coutnam = __sysconcat__ (outnam, stnam(drng)); |
|
87 csys = ss (Ac, [Bc, Acd], [Cc; Adc]); |
|
88 csys = syssetsignals (csys, "st", cstnam); |
|
89 csys = syssetsignals (csys, "in", cinnam); |
|
90 csys = syssetsignals (csys, "out", coutnam); |
3430
|
91 |
|
92 # reduce continuous system, recombine with discrete part |
7135
|
93 csys = sysmin (csys, flg); |
|
94 cn = sysdimensions (csys); |
3430
|
95 |
7135
|
96 if (cn == 0) |
3430
|
97 # continuous states are removed; just reduce the discrete part |
7135
|
98 sys = sysprune (sys, 1:p, 1:m, drng); |
|
99 retsys = sysmin (sys, flg); |
3430
|
100 else |
|
101 # extract updated parameters from reduced continuous system |
7135
|
102 [caa, cbb, ccc, cdd, ctsam, cn, cnz, cstnam, cinnam, coutnam] ... |
|
103 = sys2ss (csys); |
|
104 |
3430
|
105 crng = 1:cn; |
|
106 Ac = caa; |
|
107 Bc = cbb(:,1:m); |
|
108 Acd = cbb(:,m+(1:nz)); |
|
109 Cc = ccc(1:p,:); |
|
110 Adc = ccc(p + (1:nz),:); |
|
111 |
|
112 # recombine to reduce discrete part of the system |
7135
|
113 dinnam = __sysconcat__ (innam, cstnam); |
|
114 doutnam = __sysconcat__ (outnam, cstnam); |
|
115 dsys = ss (Ad, [Bd, Adc], [Cd; Acd], [], tsam); |
|
116 dsys = syssetsignals (dsys, "st", dstnam); |
|
117 dsys = syssetsignals (dsys, "in", dinnam); |
|
118 dsys = syssetsignals (dsys, "out", doutnam); |
3430
|
119 |
|
120 # reduce discrete subsystem |
7135
|
121 dsys = sysmin (dsys); |
|
122 [n1, nz] = sysdimensions (dsys); |
|
123 if (nz == 0) |
3430
|
124 # discrete subsystem is not needed |
7135
|
125 retsys = sysprune (csys, 1:p, 1:m); |
3430
|
126 else |
|
127 # combine discrete, continuous subsystems |
7135
|
128 [Ad, dbb, dcc] = sys2ss (dsys); |
|
129 dstnam = sysgetsignals (dsys, "st"); |
3430
|
130 Bd = dbb(:,1:m); |
|
131 Adc = dbb(:,m+(1:cn)); |
|
132 Cd = dcc(1:p,:); |
|
133 Acd = dcc(p+(1:cn),:); |
7135
|
134 stnam = __sysconcat__ (cstnam, dstnam); |
3430
|
135 aa = [Ac, Acd; Adc, Ad]; |
|
136 bb = [Bc; Bd]; |
|
137 cc = [Cc, Cd]; |
7135
|
138 retsys = ss ([Ac, Acd; Adc, Ad], [Bc ; Bd], [Cc, Cd], dd, tsam, |
|
139 cn, nz, stnam, innam, outnam, find(yd == 1)); |
|
140 endif |
3430
|
141 endif |
|
142 else |
7135
|
143 Ts = sysgettsam (sys); |
|
144 switch (flg) |
|
145 case 0 |
3430
|
146 ## reduce to a minimal system |
7135
|
147 [aa, bb, cc, dd] = sys2ss (sys); |
|
148 [cflg, Uc] = is_controllable (aa, bb); |
|
149 if (! cflg) |
3430
|
150 ## reduce to controllable states |
7135
|
151 if (! isempty (Uc)) |
3430
|
152 aa = Uc'*aa*Uc; |
|
153 bb = Uc'*bb; |
|
154 cc = cc*Uc; |
|
155 else |
|
156 aa = bb = cc = []; |
|
157 endif |
|
158 endif |
7135
|
159 if (! isempty (aa)) |
|
160 [oflg, Uo] = is_observable (aa, cc); |
|
161 if (! oflg) |
|
162 if (! isempty (Uo)) |
3430
|
163 aa = Uo'*aa*Uo; |
|
164 bb = Uo'*bb; |
|
165 cc = cc*Uo; |
|
166 else |
|
167 aa = bb = cc = []; |
|
168 endif |
|
169 endif |
|
170 endif |
7135
|
171 switch (dflg) |
|
172 case 0 |
|
173 nc = no = nn = columns (aa); |
3430
|
174 nz = 0; |
7135
|
175 case 1 |
|
176 nc = no = nz = columns (aa); |
3430
|
177 nn = 0; |
|
178 endswitch |
7135
|
179 innam = sysgetsignals (sys, "in"); |
|
180 outnam= sysgetsignals (sys, "out"); |
|
181 retsys = ss (aa, bb, cc, dd, Ts, nn, nz, [], innam, outnam); |
|
182 case 1 |
3430
|
183 ## reduced model with physical states |
7135
|
184 [cflg, Uc] = is_controllable (sys); |
|
185 xc = find (max (abs (Uc')) != 0); |
|
186 [oflg, Uo] = is_observable (sys); |
|
187 xo = find (max (abs (Uo')) != 0); |
|
188 xx = intersection (xc, xo); |
|
189 ## signal no states in reduced model |
|
190 if (isempty (xx)) |
|
191 xx = 0; |
|
192 endif |
|
193 retsys = sysprune (sys, [], [], xx); |
|
194 otherwise |
3430
|
195 error ("invalid value of flg = %d", flg); |
|
196 endswitch |
7135
|
197 if (sysdimensions (retsys, "st") > 0) |
|
198 [cflg, Uc] = is_controllable (retsys); |
|
199 nc = columns (Uc); |
|
200 [oflg, Uo] = is_observable (retsys); |
|
201 no = columns (Uo); |
3430
|
202 else |
|
203 nc = no = 0; |
|
204 endif |
|
205 endif |
7135
|
206 |
3430
|
207 endfunction |