📄 utility_zpk.m
字号:
function strFilterObject=Utility_zpk(strFilterObject,p2,p3,p4)
% Utility_zpk is a subfile of the AnalogFilter GUI collection
%
% James C. Squire, 2002
% Assistant Professor, Virginia Military Institute
% ver 1.0
% Utility_zpk returns finds the zeros, poles, and gain of an analog filter
% The filter, strFilterObject, is a global variable
%global strFilterObject
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Fminsearch Callbacks %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if nargin==4 % called as part of fminsearch for the elliptic filters
switch p4
case 'krat'
m=strFilterObject;
krat=p2;
m = min(1,max(m,0));
if abs(m) > eps & abs(m)+eps < 1
k = ellipke([m,1-m]);
r = k(1)./k(2) - krat;
elseif abs(m) <= eps % m==0
r = -krat;
else % m==1 => r == inf, but can't for non-ieee machines
r = 1e20;
end
strFilterObject = abs(r);
case 'vrat'
u=strFilterObject;
ineps=p2;
mp=p3;
[s,c] = ellipj(u,mp);
strFilterObject = abs(ineps - s/c);
otherwise
error(['Unknown fminsearch callback in ' mfilename])
end
return
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Main Program %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Create local variables
n = strFilterObject.nOrder;
Wc = strFilterObject.fFc * 2* pi;
Gp = strFilterObject.fGp;
Gs = strFilterObject.fGs;
Gain = strFilterObject.fGain;
% Get N-th order normalized prototype
switch lower(strFilterObject.sType)
case 'bessel'
[z,p,k] = NormalBessel(n);
case 'butterworth'
[z,p,k] = NormalButterworth(n);
case 'chebychev i'
[z,p,k] = NormalChebychevI(n,Gp);
case 'chebychev ii'
[z,p,k] = NormalChebychevII(n,Gs);
case 'elliptic'
[z,p,k] = NormalElliptic(n,Gp,Gs);
otherwise
error(['Unknown Type in ' mfilename])
end
% Scale frequency and change to highpass if necessary
switch lower(strFilterObject.sPurpose)
case 'lowpass'
[z,p,k] = denormalizeLP(z,p,k,Wc);
case 'highpass'
[z,p,k] = denormalizeHP(z,p,k,Wc);
otherwise
error(['Unknown Purpose in ' mfilename])
end
% sort, pair, and fix roundoff errors
strFilterObject.vZeros = cplxpair(z);
strFilterObject.vPoles = cplxpair(p);
strFilterObject.fK = k*Gain;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Bessel %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [z,p,k] = NormalBessel(n)
z = [];
switch n
case 1
p = -1;
k = 1;
case 2
p = [-1.10160133059216 + 0.63600982475703*i; -1.10160133059216 - 0.63600982475703*i];
k = 1.61803398874989;
case 3
p = [-1.04740916100894 + 0.99926443628064*i; -1.04740916100894 - 0.99926443628064*i; -1.32267579991044];
k = 2.77179327460633;
case 4
p = [ -1.37006783055144 + 0.41024971749375*i;-1.37006783055144 - 0.41024971749375*i;-0.99520876435027 + 1.25710573945467*i; -0.99520876435027 - 1.25710573945467*i];
k = 5.25819901024417;
case 5
p = [ -0.95767654856268 + 1.47112432073039*i;-0.95767654856268 - 1.47112432073039*i;-1.38087732586044 + 0.71790958762677*i;-1.38087732586044 - 0.71790958762677*i;-1.50231627144748];
k = 11.21283668537052;
case 6
p = [-1.57149040361604 + 0.32089637422262*i; -1.57149040361604 - 0.32089637422262*i;-1.38185809759657 + 0.97147189071158*i;-1.38185809759657 - 0.97147189071158*i; -0.93065652294686 + 1.66186326894259*i;-0.93065652294686 - 1.66186326894259*i];
k = 26.62976888914601;
case 7
p = [-0.90986778062347 + 1.83645135303639*i;-0.90986778062347 - 1.83645135303639*i; -1.37890321679547 + 1.19156677780065*i; -1.37890321679547 - 1.19156677780065*i; -1.61203876622612 + 0.58924450693146*i; -1.61203876622612 - 0.58924450693146*i; -1.68436817927317];
k = 69.22126457866750;
case 8
p = [-1.75740840040164 + 0.27286757510224*i;-1.75740840040164 - 0.27286757510224*i;-1.63693941812687 + 0.82279562513969*i;-1.63693941812687 - 0.82279562513969*i;-1.37384121763736 + 1.38835657587755*i;-1.37384121763736 - 1.38835657587755*i;-0.89286971884713 + 1.99832584364129*i;-0.89286971884713 - 1.99832584364129*i];
k = 1.940261933033208e+002;
case 9
p = [-0.87839927616096 + 2.14980052431333*i;-0.87839927616096 - 2.14980052431333*i; -1.36758830979291 + 1.56773371223728*i;-1.36758830979291 - 1.56773371223728*i;-1.65239648457884 + 1.03138956698440*i;-1.65239648457884 - 1.03138956698440*i;-1.80717053496210 + 0.51238373057492*i;-1.80717053496210 - 0.51238373057492*i;-1.85660050122801];
k = 5.801750529768317e+002;
case 10
p = [-1.92761969137237 + 0.24162347097177*i;-1.92761969137237 - 0.24162347097177*i;-1.84219624452473 + 0.72725759775741*i;-1.84219624452473 - 0.72725759775741*i;-1.66181024136221 + 1.22110021857916*i;-1.66181024136221 - 1.22110021857916*i;-1.36069227838455 + 1.73350574266150*i;-1.36069227838455 - 1.73350574266150*i;-0.86575690170838 + 2.29260483098249*i;-0.86575690170838 - 2.29260483098249*i];
k = 1.836246770717193e+003;
case 11
p = [-0.85451258135236 + 2.42805946691507*i;-0.85451258135236 - 2.42805946691507*i;-1.35348667738810 + 1.88829684475974*i;-1.35348667738810 - 1.88829684475974*i;-1.66719364224535 + 1.39596290364648*i;-1.66719364224535 - 1.39596290364648*i;-1.86736123888712 + 0.92311558295178*i;-1.86736123888712 - 0.92311558295178*i;-1.98016064530384 + 0.45959874382676*i;-1.98016064530384 - 0.45959874382676*i;-2.01670147345004];
k = 6.114589477119062e+003;
case 12
p = [ -2.08464450693174 + 0.21916153519047*i;-2.08464450693174 - 0.21916153519047*i;-2.01994593307477 + 0.65899650071675*i;-2.01994593307477 - 0.65899650071675*i;-1.88564961973203 + 1.10381488121541*i;-1.88564961973203 - 1.10381488121541*i;-1.66980358885276 + 1.55880270084110*i;-1.66980358885276 - 1.55880270084110*i;-1.34617468029050 + 2.03399850827847*i;-1.34617468029050 - 2.03399850827847*i;-0.84437887285039 + 2.55718896920289*i;-0.84437887285039 - 2.55718896920289*i];
k = 2.131985288096244e+004;
case 13
p = [-0.83515201045011 + 2.68080279689105*i;-0.83515201045011 - 2.68080279689105*i;-1.33888032408279 + 2.17202294710701*i;-1.33888032408279 - 2.17202294710701*i;-1.67045856262298 + 1.71167828638810*i;-1.67045856262298 - 1.71167828638810*i;-1.89898611748036 + 1.27211943651370*i;-1.89898611748036 - 1.27211943651370*i;-2.05058087608408 + 0.84338310857716*i;-2.05058087608408 - 0.84338310857716*i;-2.13764829462372 + 0.42041630675713*i;-2.13764829462372 - 0.42041630675713*i;-2.16608270567884];
k = 7.752998977990125e+004;
case 14
p = [-2.23093074227585 + 0.20200027007892*i;-2.23093074227585 - 0.20200027007892*i;-2.17970952065207 + 0.60702982702828*i;-2.17970952065207 - 0.60702982702828*i;-2.07445158463977 + 1.01536708959161*i;-2.07445158463977 - 1.01536708959161*i;-1.90866457514154 + 1.43007973190289*i;-1.90866457514154 - 1.43007973190289*i;-1.66971016070877 + 1.85613874359928*i;-1.66971016070877 - 1.85613874359928*i;-1.33167919736814 + 2.30345534461641*i;-1.33167919736814 - 2.30345534461641*i;-0.82668133243230 + 2.79955221217277*i;-0.82668133243230 - 2.79955221217277*i];
k = 2.930813527521330e+005;
case 15
p = [ -0.81885183033332 + 2.91396992652773*i;-0.81885183033332 - 2.91396992652773*i;-2.28342656234184 + 0.38982893598505*i;-2.28342656234184 - 0.38982893598505*i;-2.21352748734394 + 0.78142997785105*i;-2.21352748734394 - 0.78142997785105*i;-2.09319972155537 + 1.17691617609367*i;-2.09319972155537 - 1.17691617609367*i;-1.91558434659226 + 1.57926035556851*i;-1.91558434659226 - 1.57926035556851*i;-1.66794080077851 + 1.99338080832681*i;-1.66794080077851 - 1.99338080832681*i;-1.32461676006183 + 2.42914977398455*i;-1.32461676006183 - 2.42914977398455*i;-2.30637005662894];
k = 1.148461735754945e+006;
case 16
p = [ -2.36834668175327 + 0.18833295674897*i;-2.36834668175327 - 0.18833295674897*i;-2.32647906263646 + 0.56573669095214*i;-2.32647906263646 - 0.56573669095214*i;-2.24099322267511 + 0.94547404667305*i;-2.24099322267511 - 0.94547404667305*i;-2.10799083457213 + 1.32955250584788*i;-2.10799083457213 - 1.32955250584788*i;-1.92038809489843 + 1.72088333292392*i;-1.92038809489843 - 1.72088333292392*i;-1.66542192928512 + 2.12434959299958*i;-1.66542192928512 - 2.12434959299958*i;-1.31771943728305 + 2.54979207329592*i;-1.31771943728305 - 2.54979207329592*i;-0.81157346724783 + 3.02449807602193*i;-0.81157346724783 - 3.02449807602193*i];
k = 4.653711491998211e+006;
otherwise
error(['Order of bessel filter in ' mfilename ' cannot be greater than 16'])
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Butterworth %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [z,p,k] = NormalButterworth(n)
z = [];
p = exp(i*(pi*(1:2:n-1)/(2*n) + pi/2));
p = [p; conj(p)];
p = p(:);
if rem(n,2)==1 % n is odd
p = [p; -1];
end
k = real(prod(-p));
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Chebychev I %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [z,p,k] = NormalChebychevI(n,Gp)
epsilon = sqrt(10^(.1*Gp)-1);
mu = asinh(1/epsilon)/n;
p = exp(j*(pi*(1:2:2*n-1)/(2*n) + pi/2)).';
p = sinh(mu)*real(p) + j*cosh(mu)*imag(p);
z = [];
k = real(prod(-p));
if ~rem(n,2) % n is even so patch k
k = k/sqrt((1 + epsilon^2));
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Chebychev II %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [z,p,k] = NormalChebychevII(n,Gs)
delta = 1/sqrt(10^(.1*Gs)-1);
mu = asinh(1/delta)/n;
if (rem(n,2))
m = n - 1;
z = j ./ cos([1:2:n-2 n+2:2:2*n-1]*pi/(2*n))';
else
m = n;
z = j ./ cos((1:2:2*n-1)*pi/(2*n))';
end
p = exp(j*(pi*(1:2:2*n-1)/(2*n) + pi/2)).';
p = sinh(mu)*real(p) + j*cosh(mu)*imag(p);
p = 1 ./ p;
k = real(prod(-p)/prod(-z));
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Elliptic %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [z,p,k] = NormalElliptic(n,Gp,Gs)
if n == 1,
z = []; p = -sqrt(1/(10^(Gp/10)-1)); k = -p;
return
else
% Zeros
epsilon = sqrt(10^(0.1*Gp)-1);
k1 = epsilon/sqrt(10^(0.1*Gs)-1);
k1p = sqrt(1-k1^2);
if k1p == 1
error('Cannot design filter, Gp and Gs specifications are too strict.')
end
wp = 1;
if abs(1-k1p^2) < eps
krat = 0;
else
capk1 = ellipke([k1^2,k1p^2]);
krat = n*capk1(1)/capk1(2);
end
fopt = optimset('maxfunevals',250,'maxiter',250,'display','none');
m = fminsearch('Utility_zpk',.5,fopt,krat,[],'krat');
if m<0 | m>1
m = fminbnd('Utility_zpk',0,1,fopt,krat,[],'krat');
end
capk = ellipke(m);
ws = wp/sqrt(m);
m1 = 1 - m;
j = (1-rem(n,2)):2:n-1;
[ij,jj] = size(j);
[s,c,d] = ellipj(j*capk/n,m*ones(ij,jj));
is = find(abs(s) > eps);
z = 1 ./(sqrt(m)*s(is));
z = i*z(:);
z = [z ; conj(z)];
% Poles
r = fminsearch('Utility_zpk', ellipke(1-m),fopt,1/epsilon,k1p^2,'vrat');
v0 = capk*r/(n*capk1(1));
[sv,cv,dv] = ellipj(v0,1-m);
p = -(c.*d*sv*cv + i*s*dv)./(1-(d*sv).^2);
p = p(:);
if rem(n,2)
ip = find(abs(imag(p)) < eps*norm(p));
[pm,pn] = size(p);
pp = 1:pm;
pp(ip) = [];
p = [p ; conj(p(pp))];
else
p = [p; conj(p)];
end
% Gain
k = real(prod(-p)/prod(-z));
if (~rem(n,2))
k = k/sqrt((1 + epsilon^2));
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Lowpass Denormalize %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [z,p,k] = denormalizeLP(z,p,k,w)
Np = length(p);
Nz = length(z);
k = k*w^(Np-Nz);
p = p*w;
z = z*w;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Highpass Denormalize %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function[z,p,k] = denormalizeHP(z,p,k,w)
Np = length(p);
Nz = length(z);
k = abs( k * prod(z) / prod(p) );
z = w./z;
p = w./p;
if Np > Nz % add extra zeros at zero
z = [zeros(Np-Nz,1); z];
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -