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