comparison m-toolbox/classes/@ltpda_tf/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 returns the complex response of a transfer function as an Analysis Object.
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 %
4 % DESCRIPTION: RESP returns the complex response of a transfer function as
5 % an Analysis Object.
6 %
7 % CALL: a = resp(obj, f); % compute response for vector f
8 % a = resp(obj, f1, f2, nf); % compute response from f1 to f2 in nf
9 % steps.
10 % a = resp(obj, pl); % compute response from parameter list.
11 % a = resp(obj); % compute response
12 %
13 % <a href="matlab:utils.helper.displayMethodInfo('ltpda_tf', 'resp')">Parameters Description</a>
14 %
15 % VERSION: $Id: resp.m,v 1.14 2011/04/18 16:50:51 ingo Exp $
16 %
17 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
18
19 function varargout = resp(varargin)
20
21 %%% Check if this is a call for parameters
22 if utils.helper.isinfocall(varargin{:})
23 varargout{1} = getInfo(varargin{3});
24 return
25 end
26
27 %%% Input objects checks
28 if nargin < 1
29 error('### incorrect number of inputs.')
30 end
31
32 objs = {};
33 rest = {};
34 plin = [];
35 invars = {};
36 % Check input shape
37 % only one input -> keep shape
38 % more than one input -> convert to list.
39 classMatch = zeros(nargin, 1);
40 for ii = 1:nargin
41 if isa(varargin{ii}, 'ltpda_tf')
42 classMatch(ii) = 1;
43 end
44 end
45
46 for ii = 1:nargin
47 if classMatch(ii) == 1
48 if sum(classMatch) == 1
49 objs = num2cell(varargin{ii});
50 invars = [invars repmat({inputname(ii)}, 1, numel(varargin{ii}))];
51 else
52 objs = [objs reshape(num2cell(varargin{ii}), 1, [])];
53 invars = [invars repmat({inputname(ii)}, 1, numel(varargin{ii}))];
54 end
55 else
56 if isa(varargin{ii}, 'plist')
57 plin = [plin varargin{ii}];
58 else
59 rest = [rest {varargin{ii}}];
60 end
61 end
62 end
63
64 % Combine the input plists
65 plin = combine(plin, plist());
66
67 % Initialize output
68 bank = plin.combine(getDefaultPlist('Range')).find('bank');
69 switch lower(bank)
70 case 'none'
71 bs = ao.initObjectWithSize(size(objs,1), size(objs,2));
72 otherwise
73 bs = [];
74 end
75
76 % Loop over transfer functions
77 for pp=1:numel(objs)
78
79 % process this transfer function
80 obj = objs{pp};
81 % Now look at the model
82 name = obj.name;
83
84 if (plin.isparam('f')) || ...
85 (numel(rest) == 1 && isnumeric(rest{1}) && isvector(rest{1})) || ...
86 (numel(rest) == 1 && isa(rest{1}, 'ao') && isa(rest{1}.data, 'fsdata')) || ...
87 (numel(rest) == 1 && isa(rest{1}, 'ao') && isa(rest{1}.data, 'xydata'))
88 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
89 %%%%%%%%%% Response with a f vector %%%%%%%%%%
90 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
91 %%% r = obj.resp(plist-object('f'))
92 %%% r = obj.resp(ao-object(fsdata))
93 %%% r = obj.resp(ao-object(xydata))
94
95 if numel(rest) == 1
96 pl = combine(plist('f', rest{1}), getDefaultPlist('List'));
97 else
98 pl = combine(plin, getDefaultPlist('List'));
99 end
100
101 %%% Get f-vector
102 f = pl.find('f');
103
104 %%% Get the f-vector from the AO
105 if isa(f, 'ao')
106 f = f.data.x;
107 elseif isnumeric(f) && isvector(f)
108 %%% nothing to do
109 else
110 error('### The f-vector must be a vector or an AO, but it is from the class [%s]', class(f));
111 end
112
113 elseif (plin.isparam('f1')) || ...
114 (plin.isparam('f2')) || ...
115 (numel(rest) == 0) || ...
116 (numel(rest) == 2 && isnumeric(rest{1}) && isnumeric(rest{2})) || ...
117 (numel(rest) == 3 && isnumeric(rest{1}) && isnumeric(rest{2}) && isnumeric(rest{3}))
118 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
119 %%%%%%%%%% Response with f1, f2 and nf %%%%%%%%%%
120 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
121 %%% r = obj.resp(plist-object('f1', 'f2'))
122 %%% r = obj.resp(plist-object('f1'))
123 %%% r = obj.resp(plist-object('f2'))
124 %%% r = obj.resp()
125 %%% r = obj.resp(f1, f2)
126 %%% r = obj.resp(f1, f2, nf)
127
128 if numel(rest) == 0 && plin.nparams == 0
129 pl = getDefaultPlist('Range');
130
131 elseif numel(rest) == 2
132 pl = combine(plist('f1', rest{1}, 'f2', rest{2}), getDefaultPlist('Range'));
133
134 elseif numel(rest) == 3
135 pl = combine(plist('f1', rest{1}, 'f2', rest{2}, 'nf', rest{3}), getDefaultPlist('Range'));
136
137 else
138 pl = combine(plin, getDefaultPlist('Range'));
139 end
140
141 f1 = pl.find('f1');
142 f2 = pl.find('f2');
143 nf = pl.find('nf');
144 scale = pl.find('scale');
145
146 % Get the default values if 'f1' or 'f2' are not existing
147 if isa(obj, 'miir') || isa(obj, 'mfir')
148 % Special case for iir- and fir filters.
149 if isempty(f1), f1 = obj.fs/1000; end
150 if isempty(f2), f2 = obj.fs/2-1/nf; end
151 if isempty(f1), f1 = 0; end
152 if isempty(f2), f2 = 0.5; end
153
154 else
155 if isempty(f1), f1 = getlowerFreq(obj)/10; end
156 if isempty(f2), f2 = getupperFreq(obj)*10; end
157 end
158
159 switch lower(scale)
160 case 'lin'
161 f = linspace(f1, f2, nf);
162 case 'log'
163 f = logspace(log10(f1), log10(f2), nf);
164 end
165
166 else
167 error('### Unknown or incorrect number of inputs.');
168 end
169
170 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
171 %%%%%%%%%% deal with rows %%%%%%%%%%
172 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
173 reshape_f = false;
174 if size(f,1) > 1
175 f = f.';
176 reshape_f = true;
177 end
178
179 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
180 %%%%%%%%%% compute the response %%%%%%%%%%
181 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
182
183 r = respCore(obj, f);
184
185 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
186 %%%%%%%%%% Build output AO %%%%%%%%%%
187 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
188 if reshape_f
189 f = f.';
190 r = r.';
191 end
192
193 % create new output fsdata
194 fsd = fsdata(f, r);
195
196 % set yunits = ounits./iunits
197 fsd.setXunits('Hz');
198 fsd.setYunits(obj.ounits./obj.iunits);
199
200 % set fs, if the object is a discrete filter
201 if isa(obj, 'ltpda_filter')
202 fsd.setFs(obj.fs);
203 end
204
205 % make output analysis object
206 b = ao(fsd);
207
208 switch lower(bank)
209 case 'none'
210 % Add history
211 b.addHistory(getInfo('None'), pl, invars, obj.hist);
212 % set name
213 if isempty(name)
214 b.setName(sprintf('resp(%s)', invars{pp}));
215 else
216 b.setName(sprintf('resp(%s)', name));
217 end
218 % Add to outputs
219 bs(pp) = b;
220
221 case 'serial'
222 if isempty(bs)
223 bs = b;
224 oname = obj.name;
225 else
226 bs = bs .* b;
227 oname = [oname '.*' obj.name];
228 end
229
230 case 'parallel'
231 if isempty(bs)
232 bs = b;
233 oname = obj.name;
234 else
235 bs = bs + b;
236 oname = [oname '+' obj.name];
237 end
238 otherwise
239 error('Unknown option for parameter ''bank'': %s', bank);
240 end
241
242 end
243
244 if strcmpi(bank, 'parallel') || strcmpi(bank, 'serial')
245 inhists = [];
246 for ii = 1:numel(objs)
247 inhists = [inhists objs{ii}.hist];
248 end
249 % Add history
250 bs.addHistory(getInfo('None'), pl, [], inhists);
251 % set name
252 bs.setName(sprintf('resp(%s)', oname));
253 end
254
255 % Outputs
256 if nargout == 0
257 iplot(bs)
258 elseif nargout == numel(bs)
259 % List of outputs
260 for ii = 1:numel(bs)
261 varargout{ii} = bs(ii);
262 end
263 else
264 % Single output
265 varargout{1} = bs;
266 end
267
268 end
269
270
271 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
272 % Local Functions %
273 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
274
275 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
276 %
277 % FUNCTION: getInfo
278 %
279 % DESCRIPTION: Get Info Object
280 %
281 % HISTORY: 11-07-07 M Hewitson
282 % Creation.
283 %
284 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
285
286 function ii = getInfo(varargin)
287 if nargin == 1 && strcmpi(varargin{1}, 'None')
288 sets = {};
289 pls = [];
290 elseif nargin == 1&& ~isempty(varargin{1}) && ischar(varargin{1})
291 sets{1} = varargin{1};
292 pls = getDefaultPlist(sets{1});
293 else
294 sets = {'List', 'Range'};
295 pls = [];
296 for kk=1:numel(sets)
297 pls = [pls getDefaultPlist(sets{kk})];
298 end
299 end
300 % Build info object
301 ii = minfo(mfilename, 'ltpda_tf', 'ltpda', utils.const.categories.sigproc, '$Id: resp.m,v 1.14 2011/04/18 16:50:51 ingo Exp $', sets, pls);
302 ii.setModifier(false);
303 ii.setArgsmin(1);
304 end
305
306 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
307 %
308 % FUNCTION: getDefaultPlist
309 %
310 % DESCRIPTION: Get Default Plist
311 %
312 % HISTORY: 11-07-07 M Hewitson
313 % Creation.
314 %
315 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
316
317 function plout = getDefaultPlist(set)
318 persistent pl;
319 persistent lastset;
320 if exist('pl', 'var')==0 || isempty(pl) || ~strcmp(lastset, set)
321 pl = buildplist(set);
322 lastset = set;
323 end
324 plout = pl;
325 end
326
327 function plo = buildplist(set)
328 switch lower(set)
329 case 'list'
330
331 plo = plist();
332
333 p = param({'f',['A vector of frequencies to evaluate at or an AO \n',...
334 'whereby the x-axis is taken for the frequency values.']}, paramValue.EMPTY_DOUBLE);
335 plo.append(p);
336
337 case 'range'
338 plo = plist();
339
340 p = param({'f1','Start frequency.'}, paramValue.EMPTY_DOUBLE);
341 plo.append(p);
342
343 p = param({'f2','Stop frequency.'}, paramValue.EMPTY_DOUBLE);
344 plo.append(p);
345
346 p = param({'nf','Number of evaluation frequencies.'}, paramValue.DOUBLE_VALUE(1000));
347 plo.append(p);
348
349 p = param({'scale',['Spacing of frequencies:<ul>', ...
350 '<li>''lin'' - Linear scale.</li>', ...
351 '<li>''log'' - Logarithmic scale.</li></ul>']}, {2, {'lin', 'log'} paramValue.SINGLE});
352 plo.append(p);
353
354 otherwise
355 error('### Unknown set [%s]', set);
356 end
357
358 p = param({'bank',['How to handle a vector of input filters<br/>(only iir and fir filters):<ul>',...
359 '<li>''None'' - process each filter individually.</li>',...
360 '<li>''Serial'' - return the response of a serial filter bank.</li>',...
361 '<li>''Parallel'' - return the response of a parallel filter bank.</li></ul>']}, {1, {'none', 'serial', 'parallel'}, paramValue.SINGLE});
362 plo.append(p);
363
364 end
365