Mercurial > hg > ltpda
comparison m-toolbox/classes/@ssm/resp.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 % RESP gives the timewise impulse response of a statespace model. | |
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
3 % | |
4 % DESCRIPTION: RESP gives the timewise impulse response of a statespace | |
5 % model. | |
6 % | |
7 % CALL: mat_out = resp(sys, plist_inputs) | |
8 % | |
9 % INPUTS: | |
10 % - sys, (array of) ssm object | |
11 % | |
12 % plist with parameters 'inputs', 'states' and 'outputs' to indicate which | |
13 % inputs, states and outputs variables are taken in account. This requires | |
14 % proper variable naming. If a variable called appears more that once it | |
15 % will be used once only. | |
16 % | |
17 % OUTPUTS: | |
18 % - mat_out contains the timewise response (one for each input) | |
19 % | |
20 % <a href="matlab:utils.helper.displayMethodInfo('ssm', 'resp')">Parameters Description</a> | |
21 % | |
22 % VERSION: $Id: resp.m,v 1.27 2011/04/17 21:28:06 adrien Exp $ | |
23 % | |
24 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
25 | |
26 function varargout = resp(varargin) | |
27 %% starting initial checks | |
28 | |
29 % use the caller is method flag | |
30 callerIsMethod = utils.helper.callerIsMethod; | |
31 | |
32 % Check if this is a call for parameters | |
33 if utils.helper.isinfocall(varargin{:}) | |
34 varargout{1} = getInfo(varargin{3}); | |
35 return | |
36 end | |
37 | |
38 utils.helper.msg(utils.const.msg.MNAME, ['running ', mfilename]); | |
39 | |
40 % checking number of inputs work data | |
41 in_names = cell(size(varargin)); | |
42 for oo = 1:nargin,in_names{oo} = inputname(oo);end | |
43 | |
44 [sys, ssm_invars, rest] = utils.helper.collect_objects(varargin(:), 'ssm', in_names); | |
45 [pl, ssm_invars2, rest] = utils.helper.collect_objects(rest(:), 'plist', in_names); | |
46 if ~isempty(rest) | |
47 pl = combine(pl, plist(rest{:})); | |
48 end | |
49 pl = combine(pl, getDefaultPlist()); | |
50 | |
51 | |
52 %% begin function body | |
53 if numel(sys)>1 | |
54 error('ssm/resp only works with a single statespace model.') | |
55 end | |
56 | |
57 if ~sys.isnumerical | |
58 error('The input system should be numeric.') | |
59 end | |
60 | |
61 %% modifying input ssm | |
62 if sys.timestep == 0 | |
63 sys = copy(sys, true); | |
64 sys.modifyTimeStep('newtimestep', 0.1); | |
65 warning('Warning : time-continuous ssm was discretized with a time-step of 0.1s per default') %#ok<WNTAG> | |
66 end | |
67 | |
68 %% getting duration of the response | |
69 tmax = find(pl, 'tmax'); | |
70 if sys.isStable && (tmax == -1) | |
71 pl_s = settlingTime(sys, pl); | |
72 timeMax = min(find(pl_s, 'SETTLING_TIME'), 1e5); | |
73 timeMax = nextPow2( 12* timeMax); | |
74 else | |
75 timeMax = nextPow2( tmax./sys.timestep); | |
76 end | |
77 | |
78 %% deriving and initializing matrices | |
79 if find(pl, 'reorganize') | |
80 sys = copy(sys, true); | |
81 sys = reorganize(sys, pl, 'set', 'for resp', 'internal', 'internal'); | |
82 end | |
83 | |
84 A = sys.amats{1,1}; | |
85 B = sys.bmats{1,1}; | |
86 C = sys.cmats{2,1}; | |
87 Cstates = sys.cmats{1,1}; | |
88 D = sys.dmats{2,1}; | |
89 Ts = sys.timestep; | |
90 | |
91 Ninputs = size(B,2); | |
92 Noutputs = size(C,1); | |
93 Nss = size(A,1); | |
94 NssOut = size(Cstates,1); | |
95 | |
96 %% collecting data before saving in loop | |
97 aos = ao.initObjectWithSize(Noutputs+NssOut, Ninputs); | |
98 inhist = sys.hist; | |
99 | |
100 inputType = find(pl, 'response'); | |
101 | |
102 for ii=1:Ninputs | |
103 | |
104 %% depending on user option, compute response for one input only | |
105 if strcmpi( inputType, 'IMPULSE') | |
106 stateVect = zeros(Nss,2^timeMax); | |
107 stateVect(:,1) = B(:,ii)/sys.timestep; | |
108 a = A; | |
109 for k=1:timeMax | |
110 p = k-1; | |
111 stateVect(:,1:2^k) = [stateVect(:,1:2^p) a*stateVect(:,1:2^p)]; | |
112 a = a*a; | |
113 end | |
114 outputVect = C*stateVect; | |
115 outputVect(:,1) = outputVect(:,1) + D(:,ii); | |
116 stateVect = Cstates*stateVect; | |
117 respName = 'Impulse'; | |
118 | |
119 elseif strcmpi( inputType, 'STEP') | |
120 stateVect = zeros(Nss,2^timeMax); | |
121 stateVect(:,1) = B(:,ii); | |
122 stateBasis = B(:,ii); | |
123 outputVect = zeros(Noutputs,2^timeMax); | |
124 outputVect(:,1) = D(:,ii); | |
125 a_powP = A; | |
126 for k=1:timeMax | |
127 p = k-1; | |
128 outputVect(:,1:2^k) = [ outputVect(:,1:2^p) outputVect(:,1:2^p) ]; | |
129 lastStates = stateVect(:,1:2^p); | |
130 stateVect(:,(2^p+1):2^k) = a_powP*lastStates + diag(stateBasis)*ones(Nss, 2^p) ; | |
131 % update iterative matrices | |
132 stateBasis = a_powP*stateBasis + stateBasis; | |
133 a_powP = a_powP*a_powP; | |
134 end | |
135 outputVect = C*stateVect + outputVect; | |
136 outputVect = [ zeros(Noutputs,1) outputVect]; %#ok<AGROW> | |
137 stateVect = Cstates*stateVect; | |
138 respName = 'Step'; | |
139 | |
140 else | |
141 error(['Option ''response'' does not accept the value' inputType]); | |
142 end | |
143 | |
144 %% storing response in aos for one input only | |
145 | |
146 for oo=1:NssOut; | |
147 aos(oo,ii).setData(tsdata( stateVect(oo,:), 1/Ts)); | |
148 aos(oo,ii).setName([sys.inputs(1).ports(ii).name '->' sys.outputs(1).ports(oo).name]); | |
149 aos(oo,ii).setXunits('s'); | |
150 aos(oo,ii).setYunits(sys.outputs(1).ports(oo).units); | |
151 aos(oo,ii).setDescription([respName ' response from input ' , sys.inputs(1).ports(ii).name , 'to output ', sys.outputs(1).ports(oo).name]); | |
152 aos(oo,ii).setT0(sys.timestep); | |
153 end | |
154 for oo=1:Noutputs; | |
155 aos(NssOut+oo,ii).setData(tsdata( outputVect(oo,:), 1/Ts)); | |
156 aos(NssOut+oo,ii).setName([sys.inputs(1).ports(ii).name '->' sys.outputs(2).ports(oo).name]); | |
157 aos(NssOut+oo,ii).setXunits('s'); | |
158 aos(NssOut+oo,ii).setYunits(sys.outputs(2).ports(oo).units); | |
159 aos(NssOut+oo,ii).setDescription([respName ' response from input ' , sys.inputs(1).ports(ii).name , 'to output ', sys.outputs(2).ports(oo).name]); | |
160 aos(NssOut+oo,ii).setT0(sys.timestep); | |
161 end | |
162 end | |
163 | |
164 %% construct output matrix object | |
165 out = matrix(aos); | |
166 if callerIsMethod | |
167 % do nothing | |
168 else | |
169 myinfo = getInfo('None'); | |
170 out.addHistory(myinfo, pl , ssm_invars(1), inhist ); | |
171 end | |
172 | |
173 %% Set output depending on nargout | |
174 if nargout == 1; | |
175 varargout = {out}; | |
176 elseif nargout == 2; | |
177 varargout = {out plist_out}; | |
178 elseif nargout == 0; | |
179 iplot(aos); | |
180 else | |
181 error('Wrong number of outputs') | |
182 end | |
183 end | |
184 | |
185 %-------------------------------------------------------------------------- | |
186 % Get Info Object | |
187 %-------------------------------------------------------------------------- | |
188 function oo = getInfo(varargin) | |
189 | |
190 if nargin == 1 && strcmpi(varargin{1}, 'None') | |
191 sets = {}; | |
192 pl = []; | |
193 else | |
194 sets = {'Default'}; | |
195 pl = getDefaultPlist; | |
196 end | |
197 % Build info object | |
198 oo = minfo(mfilename, 'ssm', 'ltpda', utils.const.categories.sigproc, '$Id: resp.m,v 1.27 2011/04/17 21:28:06 adrien Exp $', sets, pl); | |
199 end | |
200 | |
201 %-------------------------------------------------------------------------- | |
202 % Get Default Plist | |
203 %-------------------------------------------------------------------------- | |
204 | |
205 function pl = getDefaultPlist() | |
206 pl = ssm.getInfo('reorganize', 'for resp').plists; | |
207 pl.remove('set'); | |
208 | |
209 p = param({'response', 'Specify the type of response wanted'},{1, {'impulse', 'step'}, paramValue.SINGLE} ); | |
210 pl.append(p); | |
211 | |
212 p = param({'tmax', 'Specify the duration of response wanted [s] (automatically set if not specified by user, and system is stable)'},-1 ); | |
213 pl.append(p); | |
214 | |
215 p = param({'reorganize', 'When set to 0, this means the ssm does not need be modified to match the requested i/o. Faster but dangerous!'}, paramValue.TRUE_FALSE); | |
216 pl.append(p); | |
217 | |
218 | |
219 end |