有没有简单的方法来计算以下函数的频率响应?
我尝试过使用重质功能,但没有运气。
基本上我想编写一个函数来根据输入N1和N2以及0和pi之间的点数(比如x)返回频率响应
输出将是一个向量,它返回相应频率的频率响应的x值=> 0:PI / X:PI
答案 0 :(得分:1)
假设N1 + N2 < num_points
,其中num_points
是序列的长度,你可以简单地编写函数:
function [gr] = rosenburg(N1, N2, num_points)
gr = zeros(num_points,1);
range1 = 0:N1;
range2 = N1+1:N1+N2;
gr(range1+1) = 0.5*(1 - cos(pi*range1/N1));
gr(range2+1) = cos(pi*(range2-N1) / (2*N2));
end
函数原型rosenburg
接收N1
,N2
以及您希望此函数接收的总点数num_points
。这段代码的工作原理是我们首先分配一个大小为num_points
的零的数组。然后,我们计算两个线性范围:一个来自0 <= n <= N1
,另一个来自N1 < n <= N2
。请注意,第二个范围首先将N1
偏移1,因为我们已经计算了n = N1
处的值。一旦我们计算了这些范围,我们就可以在正确的范围内应用正确的关系。请注意,当我将关系分配给数组中的正确间隔时,我需要偏移1,因为MATLAB开始在索引1处索引数组。其余的值由于在开头的初始化而为零。功能
现在,如果您想查找此信号的频率响应,请使用fft
Fast Fourier Transform。这是在数字基础上找到离散输入信号的频域版本的经典方法。因此,一旦使用rosenburg
函数创建信号,就将其输入FFT函数。你怎么称呼它是这样的:
X = fft(gr);
这计算N
点FFT,其中N
是信号gr
的长度。或者,您可以提供要为其计算FFT的点数。具体做法是:
X = fft(gr, N);
基本上,N
越高,频率分量越细或越精细。请注意,频率轴在0到2*pi
之间归一化,因此N
越高,轴上相邻点之间的分辨率就越高。具体而言,该轴上的每个点具有以下频率:
w = i*(2*pi)/x;
i
将是x
- 轴上的索引(0,1,2,...,num_points-1),x
将是总点数FFT。通常情况下,人们会显示-pi <= w <= pi
之间的频谱,因此有些人会应用fftshift
来移动频谱,以便DC分量位于频谱的中心,这就是我们如何自然地将频谱感知到是
当您说&#34;频率响应&#34;时,我认为您指的是幅度,因此请使用abs
来计算每个值的复杂幅度,如fft
通常是复杂的。因此,假设您希望将FFT计算为与信号长度一样多的点,并且让我们选择N1 = 4, N2 = 8
并且我们想要64点,并且我们想要绘制频谱。只需这样做:
gr = rosenburg(4, 8, 64);
X = fft(gr);
Xshift = fftshift(X);
plot(linspace(-pi,pi,64), abs(Xshift));
grid;
上述代码将移动频谱,然后将其幅度绘制在-pi
到pi
之间。这就是我得到的:
作为一个例子,在我们应用fftshift
:
以下是生成上图的代码:
plot(linspace(0,2*pi,64), abs(X));
grid;
您可以看到光谱是对称的。在频率pi
处,您可以看到它是镜像反射的,这从pi
到2*pi
的范围是有意义的,精确地映射到-pi
为0。信号是真实的,频谱是对称的。实际上,我们可以将此信号称为Hermitian symmetric。显然,频率分量有点稀疏。将点总数增加到256可能会更好。这是我将点数更改为256时得到的结果:
非常流畅!现在,如果要将频率分量从0提取到pi
,则需要提取存储在X
中的一半频率分解。因此,您只需:
f = X(1:numel(X)/2);
numel
确定数组或矩阵中有多少个元素。但请记住,每个频率点都定义为:
w = i*(2*pi)/x
你特别想要:
w = i*pi/x
因此,您需要首先以两倍的信号计算FFT,然后以相同的方式提取一半的光谱。例如,64点:
gr = rosenburg(4, 8, 64);
X = fft(gr, 128);
f = X(1:numel(X)/2);
这应该有希望让你开始。祝你好运!