Algorithm matlab中的数字滤波未给出预期结果

Algorithm matlab中的数字滤波未给出预期结果,algorithm,matlab,filtering,digital-filter,Algorithm,Matlab,Filtering,Digital Filter,我试图在matlab中设计和测试一个简单的数字高通滤波器。 我有两个脚本:第一个是设计过滤器,第二个是实现递归算法 第一个脚本:过滤器的设计: s=sym('s'); z=sym('z'); w=sym('w'); p=sym('p'); f=sym('f'); x=sym('x'); Pi=sym('Pi'); Ts=sym('Ts'); vc=sym('vc'); n=2; Fspb=1/(s^2+sqrt(2)*s+1); % simple low pass butterworth

我试图在matlab中设计和测试一个简单的数字高通滤波器。 我有两个脚本:第一个是设计过滤器,第二个是实现递归算法

第一个脚本:过滤器的设计:

s=sym('s');
z=sym('z');
w=sym('w');
p=sym('p');
f=sym('f');
x=sym('x');
Pi=sym('Pi');
Ts=sym('Ts');
vc=sym('vc');

n=2;
Fspb=1/(s^2+sqrt(2)*s+1);   % simple low pass butterworth
Fs=subs(Fspb, s, 2*Pi*vc/s); % tranform to high pass butterworth with vc cutting freq
Fz=subs(Fs, s, 2/Ts*(z-1)/(z+1)); %bilinear transformation
Fp=subs(Fz, z, exp(Ts*p))
Fw=subs(Fp, p, 1i*w);
Ff=subs(Fw, w, 2*Pi*f);

vmax=5000;
vc_val=1000; %1000 Hz
vccont=1/Pi/Ts*tan(Pi*Ts*vc_val);
Ts_val=0.0001
fval=0:0.1:vmax;

pretty(expand(Fz))

[num, den]=numden(Fz);
cn=coeffs(num,z)
cd=coeffs(den,z)
cn =     
[ 1, -2, 1]

cd =
[ Pi^2*Ts^2*vc^2 - 2^(1/2)*Pi*Ts*vc + 1, 2*Pi^2*Ts^2*vc^2 - 2, Pi^2*Ts^2*vc^2 + 2^(1/2)*Pi*Ts*vc + 1] 
它给出了系数(z)和滤波器的频率响应:

s=sym('s');
z=sym('z');
w=sym('w');
p=sym('p');
f=sym('f');
x=sym('x');
Pi=sym('Pi');
Ts=sym('Ts');
vc=sym('vc');

n=2;
Fspb=1/(s^2+sqrt(2)*s+1);   % simple low pass butterworth
Fs=subs(Fspb, s, 2*Pi*vc/s); % tranform to high pass butterworth with vc cutting freq
Fz=subs(Fs, s, 2/Ts*(z-1)/(z+1)); %bilinear transformation
Fp=subs(Fz, z, exp(Ts*p))
Fw=subs(Fp, p, 1i*w);
Ff=subs(Fw, w, 2*Pi*f);

vmax=5000;
vc_val=1000; %1000 Hz
vccont=1/Pi/Ts*tan(Pi*Ts*vc_val);
Ts_val=0.0001
fval=0:0.1:vmax;

pretty(expand(Fz))

[num, den]=numden(Fz);
cn=coeffs(num,z)
cd=coeffs(den,z)
cn =     
[ 1, -2, 1]

cd =
[ Pi^2*Ts^2*vc^2 - 2^(1/2)*Pi*Ts*vc + 1, 2*Pi^2*Ts^2*vc^2 - 2, Pi^2*Ts^2*vc^2 + 2^(1/2)*Pi*Ts*vc + 1] 

以下是使用freqz功能显示的mfilter:

Pi=3.14;
v=500;
Ts=0.0001;
x=0:Ts:100000*Ts;

y=sin(x*2*Pi*v); % sinus, freq=v
figure;
plot(x,y);

%% filter def
vc_val=1; %1000 Hz
vccont=1/Pi/Ts*tan(Pi*Ts*vc_val);

a=Pi^2*Ts^2*vccont^2;
b=sqrt(2)*Pi*Ts*vccont;

%% filtering
yf=zeros(1,size(y,2));

y1=0; y2=0; y3=0; y4=0; x1=0; x2=0; x3=0; x4=0;

for i=3:size(y,2)
     if (i>1)
         y1=yf(i-1);
         x1=xyi-1);
         if (i>2)
             y2=yf(i-2);
             x2=y(i-2);
         end
     end
    yf(i)=1/(a-b+1)*(-(2*a-2)*y1-(a+b+1)*y2+y(i)-2*x1+x2);
end

figure;
plot(x,yf);

还有我的第二个脚本,在一个简单的窦函数上实现过滤器和测试:

Pi=3.14;
v=500;
Ts=0.0001;
x=0:Ts:100000*Ts;

y=sin(x*2*Pi*v); % sinus, freq=v
figure;
plot(x,y);

%% filter def
vc_val=1; %1000 Hz
vccont=1/Pi/Ts*tan(Pi*Ts*vc_val);

a=Pi^2*Ts^2*vccont^2;
b=sqrt(2)*Pi*Ts*vccont;

%% filtering
yf=zeros(1,size(y,2));

y1=0; y2=0; y3=0; y4=0; x1=0; x2=0; x3=0; x4=0;

for i=3:size(y,2)
     if (i>1)
         y1=yf(i-1);
         x1=xyi-1);
         if (i>2)
             y2=yf(i-2);
             x2=y(i-2);
         end
     end
    yf(i)=1/(a-b+1)*(-(2*a-2)*y1-(a+b+1)*y2+y(i)-2*x1+x2);
end

figure;
plot(x,yf);
但它并没有给出我期望的结果(左:原始窦,右:1/2切割频率下的过滤结果):

我检查了我的过滤器是否稳定,我看不出有什么问题。你有什么提示吗


谢谢

结果可能是正确的。您的正弦波频率为500,采样频率为10000。您的标准化频率为500/10000=0.05,已过滤。因此,您可以看到高度衰减的输出。你应该增加正弦波频率,看看滤波后是否能恢复正弦波。

我发现了问题,那就是matlab的
numden()
函数没有给出正确的分子和分母。感谢那些花时间帮助我的人

以下代码给出了错误的结果:

z=sym('z');
Pi=sym('Pi');
Ts=sym('Ts');
vc=sym('vc');

Fz=1/((Pi^2*Ts^2*vc^2)/(z^2 - 2*z + 1) + (2^(1/2)*Pi*Ts*vc)/(z - 1) + (2*Pi^2*Ts^2*vc^2*z)/(z^2 - 2*z + 1) + (Pi^2*Ts^2*vc^2*z^2)/(z^2 - 2*z + 1) + (2^(1/2)*Pi*Ts*vc*z)/(z - 1) + 1)

[num, den]=numden(Fz);
cn=coeffs(num,z)
cd=coeffs(den,z)
matlab给出了系数:

cn=

[1,-2,1]

光盘=

[Pi^2*Ts^2*vc^2-2^(1/2)*Pi*Ts*vc+1,2*Pi^2*Ts^2*vc^2-2,Pi^2*Ts^2*vc^2+2^(1/2)*Pi*Ts*vc+1]

哪些是明显错误的


谢谢

第二个脚本只给出1
b
系数。你不应该有3吗?我不确定我是否理解你所说的只有一个
b
系数是什么意思
b
正好等于
2^(1/2)*Pi*Ts*vc
,它不是分母的系数,分母是
a-b+1
2a-2
a+b+1
,您可以尝试使用filter命令吗?这将把问题缩小到过滤函数或过滤系数。还可以用你的过滤系数运行freqz或fvtool来检查你的响应。谢谢!当使用过滤函数时,我得到的结果与我的算法相似,所以我猜问题来自于过滤器的设计。我用freqzCan的结果更新了这个问题。你能澄清numden是否有bug或者你的使用不受支持吗?好吧,我很难说这是bug还是我没有按预期使用它。。。我更新了我的回答,给出了一个简单的代码示例,该示例使用numdem显示了错误的系数。我正在使用Matlab2011b为什么你说那些系数是错误的,或者说
numden
不起作用?对我来说似乎是正确的
Fz
不是标准形式,其中分子和分母是
z
中的多项式。请尝试
pretty(简化(Fz))
。这是
numden
操作的形式,也是系数的来源。pretty(simplify(Fz))也没有给我正确的公式