FFT recursive code problem
Ältere Kommentare anzeigen
Hi,
I wrote a recursive FFT program. But when I run the program, the result is different from the build-in fft in MATLAB. Can someone help me to find the problems in the code? Thanks!
Jian
function F = fft_rec(f)
n = length(f);
if (n == 1)
F = f;
else
f_even = f(1:2:n);
f_odd = f(2:2:n);
X1 = fft_rec(f_even);
X2 = fft_rec(f_odd).*Wn(n);
F1 = X1 + X2;
F2 = X1 - X2;
F = [F1 F2];
end
function W = Wn(n)
m = n/2;
W = exp(-2*pi*j.*[0:1:m-1]/n);
function X = my_fft(f)
n = length(f);
N = pow2(ceil(log2(n)));
f = [f, zeros(1, N - n)];
X = fft_rec(f);
X = X(1:n);
function test_fft()
t = 1 : 40;
y = sin(t);
F = zeros(1, length(t));
F = my_fft(y);
x = zeros(1, length(F));
for i = 1 : length(F)
x(i) = i;
end
plot(x, abs(F));
hold;
F2 = fft(y);
plot(x, abs(F2),'c');
plot(x, abs(F2)-abs(F), 'r');
Antworten (3)
Walter Roberson
am 14 Mär. 2011
0 Stimmen
I'm not sure what X2 gets multiplied by Wn(n) but X1 does not?
If n is always odd for Wn(n) then why are you confusing things by using m = n/2 knowing that will be a number with a fraction, and then trying to use that fraction as the upper boundary of the 0:1:m-1 array?
Jian
am 14 Mär. 2011
0 Stimmen
2 Kommentare
Walter Roberson
am 14 Mär. 2011
You have if (n==1) and do something there. The implication is that it is possible for n==3 or other odd values. When that odd value (say 7) is passed to Wn(n) then m = 7/2 = 3.5, w = exp(-2*pi*j.*[0:1:3.5]/7) which will be exp(-2i*pi.*[0 3]/7) which will be [exp(0) exp(-6i/7*pi). f_odd will be f([2 4 6]) in this situation but f_even will be f([1 3 5 7]) in this situation, which is going to lead to crashes when you go to add the vector of length 4 to the vector of length 3.
Unless, that is, you posted incorrect code.
Jian
am 15 Mär. 2011
David Young
am 15 Mär. 2011
0 Stimmen
The return variable for the function Wn is W, but the result is assigned to w. Make them both the same, and it works fine.
Ideally, there should be a check that the length of the input is even (if it is not 1), to avoid a mysterious error message if the original length is not a power of 2.
(Please also format code in questions using the {}Code button so that the lines don't get run together.)
11 Kommentare
Jian
am 15 Mär. 2011
David Young
am 15 Mär. 2011
Hi Jian,
When I changed "W" to "w", your code worked perfectly. That is, it gave the same answer as the built-in fft function, to within a tolerance of about 10^-15.
What goes wrong for you - is there an error message, or do you get a numerical difference?
Thanks for editing the question to make the code clear.
Jian
am 15 Mär. 2011
David Young
am 15 Mär. 2011
The difference you see is because MY_FFT pads the input to 2^n entries, but FFT does not. If you change t=1:40 in your test code to t=1:128 (or any other power of 2), so no padding is needed, you'll find you get the results you expect. Alternatively, pad the input signal before you pass it to FFT.
Jian
am 16 Mär. 2011
Walter Roberson
am 16 Mär. 2011
No, Matlab does not use 2^n sequences: it factors the length of the array and then works on fragments determined by the factorization. I do not know the details.
Jian
am 16 Mär. 2011
Walter Roberson
am 16 Mär. 2011
Neither. It is not necessary for to use powers of two in order to fft. It might, for example, factor it in to 5 * 8, use the power-of-2 algorithm on the 8 portion, and use a different fft algorithm for the 5 part.
Jian
am 16 Mär. 2011
Walter Roberson
am 16 Mär. 2011
http://www.dspguru.com/dsp/faqs/fft
1.6 Are FFTs limited to sizes that are powers of 2?
No. The most common and familiar FFTs are "radix 2". However, other radices are sometimes used, which are usually small numbers less than 10. For example, radix-4 is especially attractive because the "twiddle factors" are all 1, -1, j, or -j, which can be applied without any multiplications at all.
Also, "mixed radix" FFTs also can be done on "composite" sizes. In this case, you break a non-prime size down into its prime factors, and do an FFT whose stages use those factors. For example, an FFT of size 1000 might be done in six stages using radices of 2 and 5, since 1000 = 2 * 2 * 2 * 5 * 5 * 5. It might also be done in three stages using radix 10, since 1000 = 10 * 10 * 10.
Jian
am 18 Mär. 2011
Kategorien
Mehr zu Fourier Analysis and Filtering finden Sie in Hilfe-Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!