Mercurial > hg > ltpda
diff m-toolbox/classes/+utils/@math/pfallpsyms.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/pfallpsyms.m Wed Nov 23 19:22:13 2011 +0100 @@ -0,0 +1,191 @@ +% +% DESCRIPTION: +% +% All pass filtering in order to stabilize transfer function poles and +% zeros. It inputs a partial fraction expanded continuous model and +% outputs a pole-zero minimum phase system +% +% CALL: +% +% [nr,np,nd,resp] = pfallpsyms(r,p,d,f) +% +% INPUTS: +% +% r: are residues +% p: are poles +% d: is direct term +% f: is the frequancies vector in (Hz) +% fs: is the sampling frequency in (Hz) +% +% OUTPUTS: +% +% resp: is the minimum phase frequency response +% np: are the new stable poles +% nz: are the new stable zeros +% +% NOTE: +% +% This function make use of symbolic math toolbox functions +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% VERSION: '$Id: pfallpsyms.m,v 1.3 2008/11/10 15:40:11 luigi Exp $'; +% +% HISTORY: 12-09-2008 L Ferraioli +% Creation +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +function [nr,np,nd,nmresp] = pfallpsyms(r,p,d,f) + +% Reshaping +[a,b] = size(r); +if a<b + r = r.'; % reshape as a column vector +end + +[a,b] = size(p); +if a<b + p = p.'; % reshape as a column vector +end + +[a,b] = size(f); +if a<b + f = f.'; % reshape as a column vector +end + +[a,b] = size(d); +if a ~= b + disp(' Function can handle only single constant direct terms. Only first term will be considered! ') + d = d(1); +end + +if isempty(d) + d = 0; +end + +% digits(100) +% Defining inputs as symbolic variable +r = sym(r,'f'); +p = sym(p,'f'); +d = sym(d,'f'); +f = sym(f,'f'); +syms z + +% Function gain coefficient +if double(d) == 0 + k = sum(r); +else + k = d; +end + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +f = sym(f,'f'); +syms z +p = sym(p,'f'); + +% stabilize poles +sp = p; +unst = abs(double(sp)) > 1; +sp(unst) = 1./conj(sp(unst)); +skp = prod(1./conj(p(unst))); + +[Na,Nb] = size(r); + +for nn = 1:Nb + + % digits(100) + % Defining inputs as symbolic variable + rt = sym(r(:,nn),'f'); +% p = sym(p,'f'); + dt = sym(d(1,nn),'f'); +% f = sym(f,'f'); +% fs = sym(fs,'f'); +% syms z + + % Function gain coefficient + if double(d) == 0 + k = sum(r); + else + k = d; + end + + Np = length(p); + + % Defining the symbolic transfer function + vter = rt./(z-p); + vter = [vter; dt]; + Mter = diag(vter); + H = trace(Mter); + + % Factorizing the transfer function + HH = factor(H); + + % Extracting numerator and denominator + [N,D] = numden(HH); + + % Symbolci calculation of function zeros + cN = coeffs(expand(N),z); + n = length(cN); + cN2 = -1.*cN(2:end)./cN(1); + A = sym(diag(ones(1,n-2),-1)); + A(1,:) = cN2; + zrs = eig(A); +% if double(d) == 0 +% zrs = [zrs; sym(0,'f')]; +% end + + if isempty(skp) + skp = sym(1,'f'); + end + if isempty(k) + k = sym(1,'f'); + end + + % Calculating new gain + % sk = real(k*skz*skp); + sk = real(k*skp); + + HHHn = sym(1,'f'); + + for ii = 1:length(zrs) + HHHn = HHHn.*(z-zrs(ii)); + end + for jj = 1:Np + tsp = sp; + tsp(jj) = []; + tHHHd = sym(1,'f'); + for kk = 1:Np-1 + tHHHd = tHHHd.*(z-tsp(kk)); + end + HHHd(jj,1) = tHHHd; + + end + + for jj = 1:Np + sr(jj,1) = subs(sk*HHHn/(z*HHHd(jj,1)),z,sp(jj)); + end + + np = double(sp); + for kk = 1:Np + if imag(np(kk)) == 0 + sr(kk) = real(sr(kk)); + end + end + + nr(:,nn) = double(sr); + nd(:,nn) = double(dt); + + % Model evaluation + pfparams.type = 'cont'; + pfparams.freq = f; + pfparams.res = nr(:,nn); + pfparams.pol = np; + pfparams.dterm = nd(:,nn); + pfr = utils.math.pfresp(pfparams); + resp = pfr.resp; + + ratio = mean(abs(mresp(:,nn))./abs(resp)); + resp = resp.*ratio; + nr(:,nn) = nr(:,nn).*ratio; + nd(:,nn) = nd(:,nn).*ratio; + nmresp(:,nn) = resp; + +end