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