傅立叶方法
诸如傅里叶变换的方法通常用于信号处理。 该方法允许在时域和频域之间变换信号。 使用FFTW库在Julia中实现了一种高效的快速傅里叶变换(FFT)算法。
In [ ]:
using FFTW
一维傅立叶变换
让我们从一维的傅立叶变换开始。 我们将使用宽矩形函数在时域中创建测试数据。
In [ ]:
f = [abs(x) <= 1 ? 1 : 0 for x in -5:0.1:5];
plot(real(f))
Out[0]:
现在我们使用*fft()*将数据转换到频域,并使用复数的模数构建信号频谱。
In [ ]:
FFT = fft(f);
typeof(FFT)
Out[0]:
In [ ]:
abs_FFT = sqrt.(real(FFT).^2+imag(FFT).^2)
plot(abs_FFT)
Out[0]:
频域数据为与时域数据长度相同的复数数组。
由于每个复数由两部分组成(实数和虚数),似乎我们以某种方式将信号的信息内容增加了一倍。 情况并非如此:一半的频域数据是冗余的。 *Fftshift()*函数方便地在频域中重新排列数据,使负频率位于左侧。
In [ ]:
F = fftshift(FFT);
abs_F = sqrt.(real(F).^2+imag(F).^2)
plot(abs_F)
Out[0]:
矩形函数的解析傅里叶变换是一个sinc函数,与上图中的数值数据很好地拟合。
二维傅立叶变换
让我们考虑一个类似的二维问题。 但这次我们将走相反的方向,从二维sinc函数开始,并采取其傅立叶变换。
使用列表生成器构建sinc数据数组很容易。
In [ ]:
f = [(r = sqrt(x^2 + y^2); sinc(r)) for x in -6:0.125:6, y in -6:0.125:6];
plot(f)
Out[0]:
考虑时域中的二维函数没有多大意义。 但傅立叶变换同时适用于时间信号和空间信号(或几乎任何其他域中的信号)。 所以,让我们假设我们的二维数据在空间域中。
In [ ]:
heatmap(f)
Out[0]:
多维信号的傅立叶变换的生成也是使用fft()执行的。
In [ ]:
F = fft(f);
F = fftshift(F);
abs_F = sqrt.(real(F).^2+imag(F).^2)
heatmap(abs_F)
Out[0]:
结论
除了上述之外,将FFT应用于更高维度的数据是方便的。
FFTW库的大部分功能都是在Julia接口中实现的。
究竟如何:
- 使用plan_fft()生成优化Fft的计划;
- 使用离散余弦变换使用dct();
- 使用rfft()在实变换中使用共轭对称;
- 您还可以通过FFTW运行多个线程。set_num_threads()。