Mercurial > hg > ltpda
diff m-toolbox/classes/+utils/@math/pfresp.m @ 0:f0afece42f48
Import.
author | Daniele Nicolodi <nicolodi@science.unitn.it> |
---|---|
date | Wed, 23 Nov 2011 19:22:13 +0100 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/m-toolbox/classes/+utils/@math/pfresp.m Wed Nov 23 19:22:13 2011 +0100 @@ -0,0 +1,153 @@ +% PFRESP returns frequency response of a partial fraction TF. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% DESCRIPTION: +% +% Returns frequency response of a partial fraction expanded function +% (continuous or discrete). +% +% Continuous case +% The expected model is: +% +% r1 rN +% f(s) = ------ + ... + ------ + d1 + d2*s + ... + dK*s^{K-1} +% s - p1 s - p1 +% +% Discrete case +% The expected model is: +% +% z*r1 z*rN +% f(z) = ------ + ... + ------ + d1 + d2*z^{-1} + ... + dK*z^{-(K-1)} +% z - p1 z - p1 +% +% NOTE: The function cannot handle poles multiplicity higher than 1 in +% z domain. Multiple poles in s-domain are accepted. +% +% CALL: pfr = pfresp(pfparams) +% +% INPUT: +% +% pfparams is a struct containing input parameters +% pfparams.type = 'cont' Assumes a continuous model +% pfparams.type = 'disc' Assumes a discrete model +% pfparams.freq set the frequencies vector in Hz +% pfparams.res - set the vector of residues +% pfparams.pol - set the vector of poles +% pfparams.pmul - set the vectr flag with poles multiplicity (this option +% is used only for continuous models) +% pfparams.dterm - set the vector of direct terms +% pfparams.fs - set the sampling frequency (Necessary for the discrete +% case) +% +% OUTPUT: +% +% pfr is a struct containing output data and parameters +% pfr.type = 'cont' if the model is continuous +% pfr.type = 'disc' if the model is discrete +% pfr.freq - frequencies vector +% pfr.nfreq - normalized frequencies vector (Discrete case) +% pfr.angfreq - angular frequencies vector +% pfr.resp - frequency response data +% +% +% VERSION: $Id: pfresp.m,v 1.5 2011/02/03 15:09:01 luigi Exp $ +% +% HISTORY: 12-09-2008 L Ferraioli +% Creation +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +function pfr = pfresp(pfparams) + + %%% switching between continuous and discrete + + switch pfparams.type + case 'cont' + % collecting input parameters + f = pfparams.freq; + % willing to work with row + if size(f,1)>size(f,2) + f = f.'; + end + r = pfparams.res; + p = pfparams.pol; + pmul = pfparams.pmul; + d = pfparams.dterm; + % willing to work with row + if ~isempty(d) && size(d,1)>size(d,2) + d = d.'; + end + + N = length(p); + +% substituted by faster code 03-Feb-2011 +% Nf = length(f); +% rsp = zeros(Nf,1); +% indx = (0:length(d)-1).'; +% for ii = 1:Nf +% for jj = 1:N +% m = pmul(jj); +% rsptemp = r(jj)/(1i*2*pi*f(ii)-p(jj))^m; +% rsp(ii) = rsp(ii) + rsptemp; +% end +% % Direct terms response +% rsp(ii) = rsp(ii) + sum((((1i*2*pi*f(ii))*ones(length(d),1)).^indx).*d); +% end + +% new code for a faster response calculation 03-Feb-2011 + rsp = zeros(size(f)); + for jj = 1:N + m = pmul(jj); + rsptemp = r(jj)./(1i*2*pi.*f-p(jj)).^m; + rsp = rsp + rsptemp; + end + % get direct term response + if ~isempty(d) + Z = ones(numel(d),numel(f)); + ss = 2.*pi.*1i.*f; + for jj=2:size(Z,1) + Z(jj,:) = ss.^(jj-1); + end + rdtemp = d*Z; + rsp = rsp + sum(rdtemp,1); + end + + % Output + pfr.type = 'cont'; + pfr.freq = f; + pfr.angfreq = 2*pi*f; + pfr.resp = rsp; + + case 'disc' + % collecting input parameters + f = pfparams.freq; + fs = pfparams.fs; + r = pfparams.res; + p = pfparams.pol; + d = pfparams.dterm; + + Nf = length(f); + N = length(p); + + % Defining normalized frequencies + fn = f./fs; + + rsp = zeros(Nf,1); + indx = 0:length(d)-1; + for ii = 1:Nf + for jj = 1:N + rsptemp = exp(1i*2*pi*fn(ii))*r(jj)/(exp(1i*2*pi*fn(ii))-p(jj)); + rsp(ii) = rsp(ii) + rsptemp; + end + % Direct terms response + rsp(ii) = rsp(ii) + sum(((exp((1i*2*pi*f(ii))*ones(length(d),1))).^(-1.*indx)).*d); + end + + % Output + pfr.type = 'disc'; + pfr.freq = f; + pfr.nfreq = fn; + pfr.angfreq = 2*pi*f; + pfr.resp = rsp; + end +end \ No newline at end of file