line source
+ − % RESP returns the complex response of a transfer function as an Analysis Object.
+ − %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ − %
+ − % DESCRIPTION: RESP returns the complex response of a transfer function as
+ − % an Analysis Object.
+ − %
+ − % CALL: a = resp(obj, f); % compute response for vector f
+ − % a = resp(obj, f1, f2, nf); % compute response from f1 to f2 in nf
+ − % steps.
+ − % a = resp(obj, pl); % compute response from parameter list.
+ − % a = resp(obj); % compute response
+ − %
+ − % <a href="matlab:utils.helper.displayMethodInfo('ltpda_tf', 'resp')">Parameters Description</a>
+ − %
+ − % VERSION: $Id: resp.m,v 1.14 2011/04/18 16:50:51 ingo Exp $
+ − %
+ − %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ −
+ − function varargout = resp(varargin)
+ −
+ − %%% Check if this is a call for parameters
+ − if utils.helper.isinfocall(varargin{:})
+ − varargout{1} = getInfo(varargin{3});
+ − return
+ − end
+ −
+ − %%% Input objects checks
+ − if nargin < 1
+ − error('### incorrect number of inputs.')
+ − end
+ −
+ − objs = {};
+ − rest = {};
+ − plin = [];
+ − invars = {};
+ − % Check input shape
+ − % only one input -> keep shape
+ − % more than one input -> convert to list.
+ − classMatch = zeros(nargin, 1);
+ − for ii = 1:nargin
+ − if isa(varargin{ii}, 'ltpda_tf')
+ − classMatch(ii) = 1;
+ − end
+ − end
+ −
+ − for ii = 1:nargin
+ − if classMatch(ii) == 1
+ − if sum(classMatch) == 1
+ − objs = num2cell(varargin{ii});
+ − invars = [invars repmat({inputname(ii)}, 1, numel(varargin{ii}))];
+ − else
+ − objs = [objs reshape(num2cell(varargin{ii}), 1, [])];
+ − invars = [invars repmat({inputname(ii)}, 1, numel(varargin{ii}))];
+ − end
+ − else
+ − if isa(varargin{ii}, 'plist')
+ − plin = [plin varargin{ii}];
+ − else
+ − rest = [rest {varargin{ii}}];
+ − end
+ − end
+ − end
+ −
+ − % Combine the input plists
+ − plin = combine(plin, plist());
+ −
+ − % Initialize output
+ − bank = plin.combine(getDefaultPlist('Range')).find('bank');
+ − switch lower(bank)
+ − case 'none'
+ − bs = ao.initObjectWithSize(size(objs,1), size(objs,2));
+ − otherwise
+ − bs = [];
+ − end
+ −
+ − % Loop over transfer functions
+ − for pp=1:numel(objs)
+ −
+ − % process this transfer function
+ − obj = objs{pp};
+ − % Now look at the model
+ − name = obj.name;
+ −
+ − if (plin.isparam('f')) || ...
+ − (numel(rest) == 1 && isnumeric(rest{1}) && isvector(rest{1})) || ...
+ − (numel(rest) == 1 && isa(rest{1}, 'ao') && isa(rest{1}.data, 'fsdata')) || ...
+ − (numel(rest) == 1 && isa(rest{1}, 'ao') && isa(rest{1}.data, 'xydata'))
+ − %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ − %%%%%%%%%% Response with a f vector %%%%%%%%%%
+ − %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ − %%% r = obj.resp(plist-object('f'))
+ − %%% r = obj.resp(ao-object(fsdata))
+ − %%% r = obj.resp(ao-object(xydata))
+ −
+ − if numel(rest) == 1
+ − pl = combine(plist('f', rest{1}), getDefaultPlist('List'));
+ − else
+ − pl = combine(plin, getDefaultPlist('List'));
+ − end
+ −
+ − %%% Get f-vector
+ − f = pl.find('f');
+ −
+ − %%% Get the f-vector from the AO
+ − if isa(f, 'ao')
+ − f = f.data.x;
+ − elseif isnumeric(f) && isvector(f)
+ − %%% nothing to do
+ − else
+ − error('### The f-vector must be a vector or an AO, but it is from the class [%s]', class(f));
+ − end
+ −
+ − elseif (plin.isparam('f1')) || ...
+ − (plin.isparam('f2')) || ...
+ − (numel(rest) == 0) || ...
+ − (numel(rest) == 2 && isnumeric(rest{1}) && isnumeric(rest{2})) || ...
+ − (numel(rest) == 3 && isnumeric(rest{1}) && isnumeric(rest{2}) && isnumeric(rest{3}))
+ − %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ − %%%%%%%%%% Response with f1, f2 and nf %%%%%%%%%%
+ − %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ − %%% r = obj.resp(plist-object('f1', 'f2'))
+ − %%% r = obj.resp(plist-object('f1'))
+ − %%% r = obj.resp(plist-object('f2'))
+ − %%% r = obj.resp()
+ − %%% r = obj.resp(f1, f2)
+ − %%% r = obj.resp(f1, f2, nf)
+ −
+ − if numel(rest) == 0 && plin.nparams == 0
+ − pl = getDefaultPlist('Range');
+ −
+ − elseif numel(rest) == 2
+ − pl = combine(plist('f1', rest{1}, 'f2', rest{2}), getDefaultPlist('Range'));
+ −
+ − elseif numel(rest) == 3
+ − pl = combine(plist('f1', rest{1}, 'f2', rest{2}, 'nf', rest{3}), getDefaultPlist('Range'));
+ −
+ − else
+ − pl = combine(plin, getDefaultPlist('Range'));
+ − end
+ −
+ − f1 = pl.find('f1');
+ − f2 = pl.find('f2');
+ − nf = pl.find('nf');
+ − scale = pl.find('scale');
+ −
+ − % Get the default values if 'f1' or 'f2' are not existing
+ − if isa(obj, 'miir') || isa(obj, 'mfir')
+ − % Special case for iir- and fir filters.
+ − if isempty(f1), f1 = obj.fs/1000; end
+ − if isempty(f2), f2 = obj.fs/2-1/nf; end
+ − if isempty(f1), f1 = 0; end
+ − if isempty(f2), f2 = 0.5; end
+ −
+ − else
+ − if isempty(f1), f1 = getlowerFreq(obj)/10; end
+ − if isempty(f2), f2 = getupperFreq(obj)*10; end
+ − end
+ −
+ − switch lower(scale)
+ − case 'lin'
+ − f = linspace(f1, f2, nf);
+ − case 'log'
+ − f = logspace(log10(f1), log10(f2), nf);
+ − end
+ −
+ − else
+ − error('### Unknown or incorrect number of inputs.');
+ − end
+ −
+ − %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ − %%%%%%%%%% deal with rows %%%%%%%%%%
+ − %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ − reshape_f = false;
+ − if size(f,1) > 1
+ − f = f.';
+ − reshape_f = true;
+ − end
+ −
+ − %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ − %%%%%%%%%% compute the response %%%%%%%%%%
+ − %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ −
+ − r = respCore(obj, f);
+ −
+ − %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ − %%%%%%%%%% Build output AO %%%%%%%%%%
+ − %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ − if reshape_f
+ − f = f.';
+ − r = r.';
+ − end
+ −
+ − % create new output fsdata
+ − fsd = fsdata(f, r);
+ −
+ − % set yunits = ounits./iunits
+ − fsd.setXunits('Hz');
+ − fsd.setYunits(obj.ounits./obj.iunits);
+ −
+ − % set fs, if the object is a discrete filter
+ − if isa(obj, 'ltpda_filter')
+ − fsd.setFs(obj.fs);
+ − end
+ −
+ − % make output analysis object
+ − b = ao(fsd);
+ −
+ − switch lower(bank)
+ − case 'none'
+ − % Add history
+ − b.addHistory(getInfo('None'), pl, invars, obj.hist);
+ − % set name
+ − if isempty(name)
+ − b.setName(sprintf('resp(%s)', invars{pp}));
+ − else
+ − b.setName(sprintf('resp(%s)', name));
+ − end
+ − % Add to outputs
+ − bs(pp) = b;
+ −
+ − case 'serial'
+ − if isempty(bs)
+ − bs = b;
+ − oname = obj.name;
+ − else
+ − bs = bs .* b;
+ − oname = [oname '.*' obj.name];
+ − end
+ −
+ − case 'parallel'
+ − if isempty(bs)
+ − bs = b;
+ − oname = obj.name;
+ − else
+ − bs = bs + b;
+ − oname = [oname '+' obj.name];
+ − end
+ − otherwise
+ − error('Unknown option for parameter ''bank'': %s', bank);
+ − end
+ −
+ − end
+ −
+ − if strcmpi(bank, 'parallel') || strcmpi(bank, 'serial')
+ − inhists = [];
+ − for ii = 1:numel(objs)
+ − inhists = [inhists objs{ii}.hist];
+ − end
+ − % Add history
+ − bs.addHistory(getInfo('None'), pl, [], inhists);
+ − % set name
+ − bs.setName(sprintf('resp(%s)', oname));
+ − end
+ −
+ − % Outputs
+ − if nargout == 0
+ − iplot(bs)
+ − elseif nargout == numel(bs)
+ − % List of outputs
+ − for ii = 1:numel(bs)
+ − varargout{ii} = bs(ii);
+ − end
+ − else
+ − % Single output
+ − varargout{1} = bs;
+ − end
+ −
+ − end
+ −
+ −
+ − %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ − % Local Functions %
+ − %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ −
+ − %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ − %
+ − % FUNCTION: getInfo
+ − %
+ − % DESCRIPTION: Get Info Object
+ − %
+ − % HISTORY: 11-07-07 M Hewitson
+ − % Creation.
+ − %
+ − %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ −
+ − function ii = getInfo(varargin)
+ − if nargin == 1 && strcmpi(varargin{1}, 'None')
+ − sets = {};
+ − pls = [];
+ − elseif nargin == 1&& ~isempty(varargin{1}) && ischar(varargin{1})
+ − sets{1} = varargin{1};
+ − pls = getDefaultPlist(sets{1});
+ − else
+ − sets = {'List', 'Range'};
+ − pls = [];
+ − for kk=1:numel(sets)
+ − pls = [pls getDefaultPlist(sets{kk})];
+ − end
+ − end
+ − % Build info object
+ − 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);
+ − ii.setModifier(false);
+ − ii.setArgsmin(1);
+ − end
+ −
+ − %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ − %
+ − % FUNCTION: getDefaultPlist
+ − %
+ − % DESCRIPTION: Get Default Plist
+ − %
+ − % HISTORY: 11-07-07 M Hewitson
+ − % Creation.
+ − %
+ − %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ −
+ − function plout = getDefaultPlist(set)
+ − persistent pl;
+ − persistent lastset;
+ − if exist('pl', 'var')==0 || isempty(pl) || ~strcmp(lastset, set)
+ − pl = buildplist(set);
+ − lastset = set;
+ − end
+ − plout = pl;
+ − end
+ −
+ − function plo = buildplist(set)
+ − switch lower(set)
+ − case 'list'
+ −
+ − plo = plist();
+ −
+ − p = param({'f',['A vector of frequencies to evaluate at or an AO \n',...
+ − 'whereby the x-axis is taken for the frequency values.']}, paramValue.EMPTY_DOUBLE);
+ − plo.append(p);
+ −
+ − case 'range'
+ − plo = plist();
+ −
+ − p = param({'f1','Start frequency.'}, paramValue.EMPTY_DOUBLE);
+ − plo.append(p);
+ −
+ − p = param({'f2','Stop frequency.'}, paramValue.EMPTY_DOUBLE);
+ − plo.append(p);
+ −
+ − p = param({'nf','Number of evaluation frequencies.'}, paramValue.DOUBLE_VALUE(1000));
+ − plo.append(p);
+ −
+ − p = param({'scale',['Spacing of frequencies:<ul>', ...
+ − '<li>''lin'' - Linear scale.</li>', ...
+ − '<li>''log'' - Logarithmic scale.</li></ul>']}, {2, {'lin', 'log'} paramValue.SINGLE});
+ − plo.append(p);
+ −
+ − otherwise
+ − error('### Unknown set [%s]', set);
+ − end
+ −
+ − p = param({'bank',['How to handle a vector of input filters<br/>(only iir and fir filters):<ul>',...
+ − '<li>''None'' - process each filter individually.</li>',...
+ − '<li>''Serial'' - return the response of a serial filter bank.</li>',...
+ − '<li>''Parallel'' - return the response of a parallel filter bank.</li></ul>']}, {1, {'none', 'serial', 'parallel'}, paramValue.SINGLE});
+ − plo.append(p);
+ −
+ − end
+ −