FFT_NEW
编程实现MATLAB 中的离散傅里叶变换FFT 函数的部分功能。即编写一个函数𝑌 = FFT_NEW(𝑋)
满足以下条件:
输入向量 X 的长度是 2𝑁,其中N 是任意自然数。你可以用 X = rand(1, 2𝑁) 产生这样的序列。(这个限制是为了降低难度)
输出 𝑌 要和 MATLAB 自带的函数 Y = fft(X) 一模一样,即实现离散傅里叶级数的快速计算。
必须采用快速傅里叶的变换蝴蝶型算法,而不是根据定义死算。
Matlab代码如下:
FFT_NEW.m
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| function Y = FFT_NEW(X) N = length(X); if N <= 1 Y = X; return; end X_even = FFT_NEW(X(1:2:end)); X_odd = FFT_NEW(X(2:2:end)); factor = exp(-2i * pi * (0:(N/2 - 1)) / N); Y = [X_even + factor .* X_odd, X_even - factor .* X_odd]; end
|
test_FFT.m
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| X = rand(1, 2^3); Y = FFT_NEW(X); Y_fft = fft(X);
figure; subplot(3, 1, 1); stem(0:length(X)-1, X, 'filled'); title('原始信号'); xlabel('样本点'); ylabel('幅值');
subplot(3, 1, 2); stem(0:length(Y)-1, abs(Y), 'filled'); title('FFT_NEW 结果'); xlabel('频率指数'); ylabel('幅值');
subplot(3, 1, 3); stem(0:length(Y_fft)-1, abs(Y_fft), 'filled'); title('MATLAB FFT 结果'); xlabel('频率指数'); ylabel('幅值');
figure; stem(0:length(Y)-1, abs(Y - Y_fft), 'filled'); title('FFT_NEW 与 MATLAB FFT 结果差异'); xlabel('频率指数'); ylabel('差值');
tolerance = 1e-10; difference = abs(Y - Y_fft); if all(difference < tolerance) disp('两者相等'); else disp('两者不相等'); end
|
IFFT_NEW
请编程实现 MATLAB 中的离散傅里叶变换 IFFT 函数的部分功能。即编写一个函数𝑋 = IFFT_NEW(𝑌)
满足以下条件:
输入向量 𝑌 的长度是 2𝑁,其中 𝑁 是任意自然数。你可以用 Y = rand(1, 2𝑁) 产生这样的序列。(这个限制是为了降低难度)
输出 𝑋 要和 MATLAB 自带的函数 X = ifft(Y) 一模一样,即实现离散傅里叶级数反变换的快速计算。
需采用快速傅里叶变换的蝴蝶型算法,而不是根据定义死算。
(提示:如果编出了 FFT,这题不难,但是请注意,如果用递归编程,应该是除以 2,而不是除以 𝑁。)
Matlab代码如下:
IFFT_NEW.m
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| function Y = IFFT_NEW(X) N = length(X); if N <= 1 Y = X; return; end X_even = IFFT_NEW(X(1:2:end)); X_odd = IFFT_NEW(X(2:2:end)); factor = exp(2i * pi * (0:(N/2 - 1)) / N); Y = [X_even + factor .* X_odd, X_even - factor .* X_odd] / 2; end
|
test_IFFT.m
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| N = 2^3; X = rand(1, N) + 1i * rand(1, N);
Y_ifft_new = IFFT_NEW(X); Y_ifft = ifft(X);
figure; subplot(3, 1, 1); stem(0:N-1, real(X), 'filled'); title('原始信号 (实部)'); xlabel('样本点'); ylabel('幅值');
subplot(3, 1, 2); stem(0:N-1, real(Y_ifft_new), 'filled'); title('IFFT_NEW 结果 (实部)'); xlabel('频率指数'); ylabel('幅值');
subplot(3, 1, 3); stem(0:N-1, real(Y_ifft), 'filled'); title('MATLAB IFFT 结果 (实部)'); xlabel('频率指数'); ylabel('幅值');
figure; stem(0:N-1, abs(Y_ifft_new - Y_ifft), 'filled'); title('IFFT_NEW 与 MATLAB IFFT 结果差异 (实部)'); xlabel('频率指数'); ylabel('差值');
tolerance = 1e-10; difference = abs(Y_ifft_new - Y_ifft); if all(difference < tolerance) disp('两者相等'); else disp('两者不相等'); end
|