Mercurial > hg > ltpda
comparison m-toolbox/classes/@ssm/ssm2pzmodel.m @ 0:f0afece42f48
Import.
author | Daniele Nicolodi <nicolodi@science.unitn.it> |
---|---|
date | Wed, 23 Nov 2011 19:22:13 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:f0afece42f48 |
---|---|
1 % SSM2PZMODEL converts a time-continuous statespace model object to a pzmodel | |
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
3 % | |
4 % DESCRIPTION: SSM2PZMODEL converts a time-continuous statespace model | |
5 % object to a pzmodel | |
6 % | |
7 % CALL: | |
8 % >> pzms = ssm2pzmodel(ssm, pl); | |
9 % | |
10 % INPUT : | |
11 % | |
12 % ssm - a ssm object | |
13 % pl - a plist with parameters 'inputs', 'states' and | |
14 % 'outputs' to indicate which inputs, states and output | |
15 % variables are taken in account. This requires proper | |
16 % variable naming. If a variable called appears more | |
17 % that once it will be used once only. | |
18 % | |
19 % OUTPUT: | |
20 % | |
21 % pzms - an array of pzmodels objects if the timestep is zero | |
22 % | |
23 % <a href="matlab:utils.helper.displayMethodInfo('ssm', 'ssm2pzmodel')">Parameters Description</a> | |
24 % | |
25 % VERSION: $Id: ssm2pzmodel.m,v 1.21 2011/04/08 08:56:23 hewitson Exp $ | |
26 % | |
27 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
28 | |
29 function varargout = ssm2pzmodel(varargin) | |
30 | |
31 % Check if this is a call for parameters | |
32 if utils.helper.isinfocall(varargin{:}) | |
33 varargout{1} = getInfo(varargin{3}); | |
34 return | |
35 end | |
36 | |
37 %% starting initial checks | |
38 utils.helper.msg(utils.const.msg.MNAME, ['running ', mfilename]); | |
39 | |
40 % Collect input variable names | |
41 in_names = cell(size(varargin)); | |
42 for ii = 1:nargin,in_names{ii} = inputname(ii);end | |
43 | |
44 % Collect all SSMs and plists | |
45 [sys, ssm_invars, rest] = utils.helper.collect_objects(varargin(:), 'ssm', in_names); | |
46 [pl, invars2, rest] = utils.helper.collect_objects(rest(:), 'plist'); | |
47 if ~isempty(rest) | |
48 pl = combine(pl, plist(rest{:})); | |
49 end | |
50 pl = combine(pl, getDefaultPlist); | |
51 | |
52 if numel(sys) ~= 1 | |
53 error('### Input (only) one SSM object.'); | |
54 end | |
55 | |
56 %% begin function body | |
57 | |
58 %% convert to double | |
59 % Convert to double arrays | |
60 [A,B,C,D,Ts,inputvarnames,ssvarnames,outputvarnames, inputunit, ssunit, outputunit] =... | |
61 double(sys, pl); | |
62 | |
63 Ninputs_out = numel(inputvarnames); | |
64 Noutputs_out = numel(outputvarnames); | |
65 | |
66 if Ts > 0 | |
67 error('ssm should be time continuous, use ssm2miir instead') | |
68 end | |
69 %% convert to pzm | |
70 pzm_out = pzmodel.initObjectWithSize(Noutputs_out, Ninputs_out); | |
71 for ii=1:Ninputs_out | |
72 for oo=1:Noutputs_out | |
73 [b,a] = ss2tf(A,B(:,ii),C(oo,:),D(oo, ii)); | |
74 % computing poles and zeros | |
75 pa = roots(a); | |
76 if isempty(pa) | |
77 p = pz.initObjectWithSize(1,0); | |
78 gainP = 1; | |
79 else | |
80 [p, gainP] = roots2poly(pa); | |
81 end | |
82 zb = roots(b); | |
83 if isempty(zb) | |
84 z = pz.initObjectWithSize(1,0); | |
85 gainZ = 1; | |
86 else | |
87 [z, gainZ] = roots2poly(zb); | |
88 end | |
89 % computing gain coefficient | |
90 apos = a(a~=0); | |
91 bpos = b(b~=0); | |
92 if ~isempty(bpos) && ~isempty(apos) | |
93 Gain = bpos(1)/apos(1); | |
94 elseif ~isempty(apos) | |
95 Gain = 1/apos(1); | |
96 elseif ~isempty(bpos) % NB theoretically impossible to reach : SSM can't have more zeros than poles | |
97 Gain = bpos(1); | |
98 else | |
99 Gain = 0; | |
100 end | |
101 Gain = Gain / gainP * gainZ; | |
102 % constructing output pzm | |
103 name = [sys.name,'_',num2str(ii),':',num2str(oo)]; | |
104 pzm_out(oo,ii) = pzmodel(plist(... | |
105 'gain', Gain, 'poles', p, 'zeros', z, 'name', name, ... | |
106 'inunits', inputunit(ii), 'ounits' ,outputunit(oo) )); | |
107 pzm_out(oo,ii).addHistory(ssm.getInfo(mfilename), pl , ssm_invars, sys.hist); | |
108 end | |
109 end | |
110 if nargout == numel(pzm_out) | |
111 for ii = 1:numel(pzm_out) | |
112 varargout{ii} = pzm_out(ii); | |
113 end | |
114 else | |
115 varargout{1} = pzm_out; | |
116 end | |
117 end | |
118 | |
119 | |
120 function varargout = roots2poly(roots) | |
121 poly = pz.initObjectWithSize(1,0); | |
122 i=1; | |
123 gain = 1; | |
124 while i < length(roots)+1 | |
125 if isreal(roots(i)) | |
126 poly = [poly pz(-roots(i)/2/pi)]; %#ok<AGROW> | |
127 gain = gain * abs(roots(i)); | |
128 i = i+1; | |
129 else | |
130 f = norm(roots(i)/2/pi);%*sign(real(roots(i))); | |
131 Q = norm(roots(i))/abs(2*real(roots(i))); | |
132 poly = [poly pz(f,Q)]; %#ok<AGROW> | |
133 gain = gain * abs(roots(i))^2; | |
134 i = i+2; %#ok<FXSET> | |
135 end | |
136 end | |
137 varargout = {poly, gain}; | |
138 end | |
139 | |
140 | |
141 %-------------------------------------------------------------------------- | |
142 % Get Info Object | |
143 %-------------------------------------------------------------------------- | |
144 function ii = getInfo(varargin) | |
145 | |
146 if nargin == 1 && strcmpi(varargin{1}, 'None') | |
147 sets = {}; | |
148 pl = []; | |
149 else | |
150 sets = {'Default'}; | |
151 pl = getDefaultPlist; | |
152 end | |
153 % Build info object | |
154 ii = minfo(mfilename, 'ssm', 'ltpda', utils.const.categories.converter, '$Id: ssm2pzmodel.m,v 1.21 2011/04/08 08:56:23 hewitson Exp $', sets, pl); | |
155 end | |
156 | |
157 %-------------------------------------------------------------------------- | |
158 % Get Default Plist | |
159 %-------------------------------------------------------------------------- | |
160 function pl = getDefaultPlist() | |
161 pl = plist(); | |
162 | |
163 p = param({'inputs', ['Specify the inputs. Give one of:<ul>'... | |
164 '<li>A cell-array of input port names.</li>'... | |
165 '<li>A cell-array of logical arrays specifying which input ports to use for each input block.</li>'... | |
166 '<li>A cell-array of double values specifying which input ports to use for each input block.<li>'... | |
167 '<li>The string ''ALL'' to use all inputs.']}, paramValue.STRING_VALUE('ALL')); | |
168 pl.append(p); | |
169 | |
170 p = param({'states', 'Specify the states. Specify the states as for the ''inputs'' parameter.'}, paramValue.STRING_VALUE('ALL')); | |
171 pl.append(p); | |
172 | |
173 p = param({'outputs', 'Specify the outputs. Specify the outputs as for the ''inputs'' parameter.'}, paramValue.STRING_VALUE('ALL')); | |
174 pl.append(p); | |
175 end | |
176 |