2026a

# fft


傅里叶变换 (一维、二维、多维)

函数库: TyMath

# 语法

Y = fft(X)
Y = fft(X,dim)

# 说明

Y = fft(X) 用快速傅里叶变换 (FFT) 算法计算 X 的离散傅里叶变换 (DFT)。

  • 如果 X 是向量,则 fft(X) 返回该向量的傅里叶变换;示例
  • 如果 X 是矩阵,则 fft(X) 返回该矩阵的二维傅里叶变换;示例
  • 如果 X 是一个多维数组,返回该多维数组的 N 维傅里叶变换。示例

Y = fft(X,dim) 返回对数组 X 沿维度 dim 进行计算傅里叶变换。示例

# 示例

含噪信号

使用傅里叶变换求噪声中隐藏的信号的频率分量。

指定信号的参数,采样频率为 1 kHz,信号持续时间为 1.5 秒。

using TyMath
using TyPlot
Fs = 1000
T = 1/Fs
L = 1500
t = (0:L-1)*T

构造一个信号,其中包含幅值为 0.7 的 50 Hz 正弦量和幅值为 1 的 120 Hz 正弦量。

S = 0.7*sin.(2*pi*50*t) + sin.(2*pi*120*t)

用均值为 0、方差为 4 的白噪声扰乱该信号。

X = S + 2*randn(size(t))

在时域中绘制含噪信号。通过查看信号 X(t) 很难确定频率分量。

plot(1000*t[1:50],X[1:50])
title("均值为0的随机噪声信号")
xlabel("t(milliseconds)")
ylabel("X(t)")

计算信号的傅里叶变换。

Y = fft(X)

计算双侧频谱 P2。然后基于 P2 和偶数信号长度 L 计算单侧频谱 P1。

P2 = abs.(Y/L)
P1 = P2[1:Int(L/2)+1]
P1[2:end-1] = 2*P1[2:end-1]

定义频域 f 并绘制单侧幅值频谱 P1。与预期相符,由于增加了噪声,幅值并不精确等于 0.7 和 1。一般情况下,较长的信号会产生更好的频率近似值。

f = Fs*(0:(L/2))/L
plot(f,P1)
title("X(t) 的单侧振幅图")
xlabel("f (Hz)")
ylabel("|P1(f)|")

现在,采用原始的、未破坏信号的傅里叶变换并检索精确幅值 0.7 和 1.0。

Y = fft(S)
P2 = abs.(Y/L)
P1 = P2[1:Int(L/2)+1]
P1[2:end-1] = 2*P1[2:end-1]
plot(f,P1)
title("S(t)的单侧振幅谱")
xlabel("f (Hz)")
ylabel("|P1(f)|")
高斯脉冲

将高斯脉冲从时域转换为频域。

定义信号参数和高斯脉冲 X。

using TyMath
using TyPlot
Fs = 100
t = -0.5:1/Fs:0.5
L = length(t)
X = 1/(4*sqrt.(2*pi*0.01))*(exp.(-t.^2/(2*0.01)))

在时域中绘制脉冲。

plot(t,X)
title("时域高斯脉冲")
xlabel("Time (t)")
ylabel("X(t)")

要使用 fft 将信号转换为频域,首先从原始信号长度确定下一个 2 次幂的新输入长度。这将用尾随零填充信号 X 以改善 fft 的性能。

n = 2^nextpow2(L)

将高斯脉冲转换为频域。

X = append!(X,zeros(n-L))
Y = fft(X)

定义频域并绘制唯一频率。

f = Fs*(0:Int(n/2))/n
P = abs.(Y/n) .^ 2

plot(f,P[1:Int(n/2)+1])
title("频域上的高斯脉冲")
xlabel("Frequency (f)")
ylabel("|P(f)|^2")
余弦波

比较时域和频域中的余弦波。

指定信号的参数,采样频率为 1kHz,信号持续时间为 1 秒。

using TyMath
using TyPlot
Fs = 1000
T = 1/Fs
L = 1000
t = (0:L-1)*T

创建一个矩阵,其中每一列代表一个频率经过缩放的余弦波。结果 X 为 1000×3 矩阵。第一列的波频为 50,第二列的波频为 150,第三列的波频为 300。

x1 = cos.(2*pi*50*t)
x2 = cos.(2*pi*150*t)
x3 = cos.(2*pi*300*t)

X = hcat(x1,x2,x3)

在单个图窗中按顺序绘制 X 的每列的前 100 个项,并比较其频率。

for i = 1:3
  ax = subplot(3,1,i)
  plot(ax,t[1:100],X[1:100,i])
  title("Row $i in the Time Domain")
end

出于算法性能的考虑,fft 允许您用尾随零填充输入。在这种情况下,用零填充 X 的每一列,以使每列的长度为比当前长度大的下一个最小的 2 的次幂值。使用 nextpow2 函数定义新长度。

n = 2^nextpow2(L)

指定 dim 参数沿 X 的列(即对每个信号)使用 fft。

dim = 1

计算信号的傅里叶变换。

X = vcat(X,zeros(n-L,3))
Y = fft(X,dim)

计算每个信号的双侧频谱和单侧频谱。

P2 = abs.(Y/L)
P1 = P2[1:Int(n/2)+1,:]
P1[2:end-1,:] = 2*P1[2:end-1,:]

在频域内,为单个图窗中的每一行绘制单侧幅值频谱。

for i = 1:3
  ax = subplot(3,1,i)
  plot(ax,0:(Fs/n):(Fs/2-Fs/n),P1[1:Int(n/2),i])
  title("Row $i in the Time Domain")
end
二维变换

二维傅里叶变换对处理二维信号和其他二维数据(如图像)很有用。

创建并绘制具有重复块的二维数据。

using TyMath
using TyPlot
P = peaks(20)[3]
X = repeat(P,5,10)
imagesc(X)

计算数据的二维傅里叶变换。将零频分量移动到输出的中心,并绘制生成的 100×200 矩阵,它与 X 的大小相同。

Y = fft(X)
imagesc(abs.(fftshift(Y)))

用零填充 X 以计算 128×256 变换。

n1 = 2^nextpow2(100)
n2 = 2^nextpow2(200)
X = hcat(X,zeros(100,n2-200))
X = vcat(X,zeros(n1-100,n2))
Y = fft(X)
imagesc(abs.(fftshift(Y)))
三维变换

您可以使用 fft 函数计算多维数组中每个维度的一维快速傅里叶变换。

创建一个三维信号 X。X 的大小为 20×20×20。

using TyMath
x = [1:20;]
y = [1:20;]'
z = reshape(1:20,1,1,20)
X = cos.(2*pi*0.01*x) .+ sin.(2*pi*0.02*y) .+ cos.(2*pi*0.03*z)

计算该信号的三维傅里叶变换,这也是一个 20×20×20 数组。

Y = fft(X)

# 输入参数

X - 输入数组
向量 | 矩阵 | 多维数组

数据类型: Int | Float |Bool

复数支持: 是

dim - 沿其运算的维度
正整数标量

沿其运算的维度,指定为正整数标量。如果未指定值,则默认是对数组的 ndims(X) 维傅里叶变换。

fft(X,1) 沿 X 的第一个维度进行傅里叶变换。

数据类型: Int |Bool

# 输出参数

Y - 频域表示
向量 | 矩阵 | 多维数组

频域表示,以向量、矩阵或多维数组形式返回。

数据类型: Float | Int

复数支持: 是

# 详细信息

向量的离散傅里叶变换

Y = fft(X) 和 X = ifft(Y) 分别实现傅里叶变换和傅里叶逆变换。对于长度为 n 的 X 和 Y,这些变换定义如下:

其中, 为 n 次单位根之一。

二维傅里叶变换

以下公式定义 m×n 矩阵 X 的离散傅里叶变换 Y:

i 是虚数单位。p 和 j 是值范围从 0 到 m–1 的索引,q 和 k 是值范围从 0 到 n–1 的索引。此公式将 X 和 Y 的索引平移 1 位。

N 维傅里叶变换

N 维数组 X 的离散傅里叶变换 Y 定义为:

每个维度的长度为 ,其中 ,而 是复单位根,其中i是虚数单位

# 提示

  • fft 的执行时间取决于变换的长度。仅具有小质因数的变换长度的 fft 执行时间明显快于本身是质数或具有较大质因数的变换长度的 fft 执行时间;
  • 对于大多数 n 值,实数输入的 DFT 需要的计算时间大致是复数输入的 DFT 计算时间的一半。但是,当 n 有较大的质因数时,速度很少有差别或没有差别。

# 算法

FFT 函数(fft、ifft)基于一个称为 FFTW [1]的库。

# 参考文献

[1] Frigo, M., and S. G. Johnson. “FFTW: An Adaptive Software Architecture for the FFT.” Proceedings of the International Conference on Acoustics, Speech, and Signal Processing. Vol. 3, 1998, pp. 1381-1384.

# 另请参阅

fftshift | ifft | FFTW (opens new window)