本帖最后由 wdhd 于 2016-3-14 14:33 编辑
- 1, DIT:
- ==============
- 1.1 Matlab code:
- ===============
- function fft_2dit(n)
- t = [0:n-1];
- m= log2(n);
- %%%%%%%% raw data %%%%%%%%%%%
- x = sin(t)/1 + sin(2*t)/2 - sin(3*t)/3 - sin(4*t)/4 + sin(5*t)/5;
- y = t*0;
- subplot(3,1,1)
- plot(t, x, '-');
- title('radix-2 DIT FFT');
- xlabel(' t');
- ylabel(' x');
- grid;
- %%%%%%%%%%% FFT %%%%%%%%%%%%%
- %inverse bits
- j = 1;
- n1 = n - 1;
- for i = 1:n1
- if i < j
- xt = x(j);
- x(j) = x(i);
- x(i) = xt;
- xt = y(j);
- y(j) = y(i);
- y(i) = xt;
- end
- k = n / 2;
- while k<j
- j = j - k;
- k = k / 2;
- end
- j = j + k;
- end
- %calculate FFT
- for k = 1:m
- n2 = 2.^(k-1);
- n1 = 2.^k;
- ee = -2*pi/n1;
- for j = 1 : n2
- a = (j-1)*ee;
- c = cos(a);
- s = sin(a);
- for p = j:n1:n
- q = p + n2;
- xtt = x(p);
- ytt = y(p);
- xt = x(q)*c - y(q)*s;
- yt = x(q)*s + y(q)*c;
- x(p) = xtt + xt;
- y(p) = ytt + yt;
- x(q) = xtt - xt;
- y(q) = ytt - yt;
- end
- end
- end
- subplot(3,1,2)
- plot(t, x,'-r');
- xlabel(' t');
- ylabel('x');
- grid;
- %%%%%%%%%% IFFT %%%%%%%%%%
- %inverse bits
- j = 1;
- n1 = n - 1;
- for i = 1:n1
- if i < j
- xt = x(j);
- x(j) = x(i);
- x(i) = xt;
- xt = y(j);
- y(j) = y(i);
- y(i) = xt;
- end
- k = n / 2;
- while k<j
- j = j - k;
- k = k / 2;
- end
- j = j + k;
- end
- %calculate IFFT
- n2 = 2;
- for k = 1:m
- n2 = 2.^(k-1);
- n1 = 2.^k;
- ee = 2*pi/n1;
- for j = 1 : n2
- a = (j-1)*ee;
- c = cos(a);
- s = sin(a); for p = j:n1:n
- q = p + n2;
- xtt = x(p);
- ytt = y(p);
- xt = x(q)*c - y(q)*s;
- yt = x(q)*s + y(q)*c;
- x(p) = xtt + xt;
- y(p) = ytt + yt;
- x(q) = xtt - xt;
- y(q) = ytt - yt;
- end
- end
- end
- subplot(3,1,3)
- plot(t, x/n, '-');
- xlabel('t');
- ylabel('x');
- grid;
- ======================
- 1.2 C code:
- ======================
- #define PI 3.1415926535
- /**************************************************************
- *
- *
- *
- *
- *
- ***************************************************************/
- void fft_2dit(int n, double* x, double* y)
- {
- double a, e, xt, yt, c, s, xtt,ytt;
- int n1, n2, i, j, k, m, q;
- /*
- * Calculate m such that n=2^m
- *
- * NOTE: If frexp() == 1, then frexp does not conform
- * to the ANSI C spec of [0.5, 1)
- */
- m = (int)(log10(n) / log10(2));
- if( pow(2, m) != n)
- {
- printf("m must be 2's pow!\n");
- }
- /* --------------MAIN FFT LOOPS----------------------------- */
- /* Parameter adjustments */
- --y;
- --x;
- /* ------------DIGIT REVERSE COUNTER----------------- */
- j = 1;
- n1 = n - 1;
- for(i= 1; i<= n1; i++)
- {
- if(i < j)
- {
- xt = x[j];
- x[j] = x[i];
- x[i] = xt;
- xt = y[j];
- y[j] = y[i];
- y[i] = xt;
- }
- k = n / 2;
- while(k < j)
- {
- j = j - k;
- k = k / 2;
- }
- j = j + k;
- }
- //calculate FFT
- for(k = 1; k <= m; k++)
- {
- n2 = 1<<(k-1);
- n1 = 1<<k;
- e = -2*PI/n1;
- for(j = 1; j <= n2; j++)
- {
- a = (j-1)*e;
- c = cos(a);
- s = sin(a);
- for(i = j; i <= n; i += n1)
- {
- q = i + n2;
- xtt = x[i];
- ytt = y[i];
- xt = x[q]*c - y[q]*s;
- yt = x[q]*s + y[q]*c;
- x[i] = xtt + xt;
- y[i] = ytt + yt;
- x[q] = xtt - xt;
- y[q] = ytt - yt;
- }
- }
- }
- }
- /**************************************************************
- *
- *
- *
- *
- *
- ***************************************************************/
- void ifft_2dit(int n, double* x, double* y)
- {
- double a, e, xt, yt, c, s, xtt,ytt;
- int n1, n2, i, j, k, m, q;
- /*
- * Calculate m such that n=2^m
- *
- * NOTE: If frexp() == 1, then frexp does not conform
- * to the ANSI C spec of [0.5, 1)
- */
- m = (int)(log10(n) / log10(2));
- if( pow(2, m) != n)
- {
- printf("m must be 2's pow!\n");
- }
- /* --------------MAIN FFT LOOPS----------------------------- */
- /* Parameter adjustments */
- --y;
- --x;
- /* ------------DIGIT REVERSE COUNTER----------------- */
- j = 1;
- n1 = n - 1;
- for(i= 1; i<= n1; i++)
- {
- if(i < j)
- {
- xt = x[j];
- x[j] = x[i];
- x[i] = xt;
- xt = y[j];
- y[j] = y[i];
- y[i] = xt;
- }
- k = n / 2;
- while(k < j)
- {
- j = j - k;
- k = k / 2;
- }
- j = j + k;
- }
- //calculate IFFT
- for(k = 1; k <= m; k++)
- {
- n2 = 1<<(k-1);
- n1 = 1<<k;
- e = 2*PI/n1;
- for(j = 1; j <= n2; j++)
- {
- a = (j-1)*e;
- c = cos(a);
- s = sin(a);
- for(i = j; i <= n; i += n1)
- {
- q = i + n2;
- xtt = x[i];
- ytt = y[i];
- xt = x[q]*c - y[q]*s;
- yt = x[q]*s + y[q]*c;
- x[i] = xtt + xt;
- y[i] = ytt + yt;
- x[q] = xtt - xt;
- y[q] = ytt - yt;
- }
- }
- }
- //each IFFT-ed data must be divided by 8
- for(i = 1; i <= n; i++)
- {
- x[i] = x[i]/n;
- y[i] = y[i]/n;
- }
- }
- ===================
- 2, DIF
- ===================
- 2.1 Matlab code:
- ===================
- function fft_2dif(n)
- m = log2(n);
- t = [0:n-1];
- %%%%%%%%%% raw data %%%%%%%%
- x = sin(t)/1 + sin(2*t)/2 - sin(3*t)/3 - sin(4*t)/4 + sin(5*t)/5;
- y = t*0;
- subplot(3,1,1)
- plot(t, x, '-');
- title('radix-2 DIF FFT');
- xlabel(' t');
- ylabel(' x');
- grid;
- %%%%%%%%%% FFT %%%%%%%%%%%%
- n2 = n;
- for k = 1:m
- n1 = n2;
- n2 = n2 / 2;
- ee = -2*pi/n1;
- a = 0.0;
- for j = 1:n2
- c = cos(a);
- s = sin(a);
- a = j*ee;
- for p = j:n1:n
- q = p + n2;
- xt = x(p) - x(q);
- yt = y(p) - y(q);
- x(p) = x(p) + x(q);
- y(p) = y(p) + y(q);
- x(q) = c*xt - s*yt;
- y(q) = c*yt + s*xt;
- end
- end
- end
- j = 1;
- n1 = n - 1;
- for i = 1:n1
- if i < j
- xt = x(j);
- x(j) = x(i);
- x(i) = xt;
- xt = y(j);
- y(j) = y(i);
- y(i) = xt;
- end
- k = n / 2;
- while k<j
- j = j - k;
- k = k / 2;
- end
- j = j + k;
- end
- subplot(3,1,2)
- plot(t, x,'-r');
- xlabel('t');
- ylabel('x');
- grid;
- %%%%%%%%% IFFT %%%%%%%%%%%%%
- n2 = n;
- for k = 1:m
- n1 = n2;
- n2 = n2 / 2;
- ee = 2*pi/n1;
- a = 0.0;
- for j = 1:n2
- c = cos(a);
- s = sin(a);
- a = j*ee;
- for p = j:n1:n
- q = p + n2;
- xt = x(p) - x(q);
- yt = y(p) - y(q);
- x(p) = x(p) + x(q);
- y(p) = y(p) + y(q);
- x(q) = c*xt - s*yt;
- y(q) = c*yt + s*xt;
- end
- end
- end
- j = 1;
- n1 = n - 1;
- for i = 1:n1
- if i < j
- xt = x(j);
- x(j) = x(i);
- x(i) = xt;
- xt = y(j);
- y(j) = y(i);
- y(i) = xt;
- end
- k = n / 2;
- while k<j
- j = j - k;
- k = k / 2;
- end
- j = j + k;
- end
- subplot(3,1,3)
- plot(t, x/n, '-');
- xlabel(' t');
- ylabel(' x');
- grid;
- ======================
- 2.2 C code:
- ======================
- /*****************************************************************************
- *
- * fft: FFT implementation with Cooley-Tukey radix-2 DIF
- *
- * Arguments: n -- data number to be FFT-ed
- * x -- pointer to real section of original data
- * y -- pointer to imaginary section of original data
- *
- * Notes: (original comments for the implementation)
- * fft_rt.c - Cooley-Tukey radix-2 DIF FFT
- * Complex input data in arrays x and y
- * C.S. Burrus, Rice University, Sept. 1983
- *
- * Copyright 1995-2002 The MathWorks, Inc.
- * $Revision: 1.15 $ $Date: 2002/04/12 22:18:20 $
- *****************************************************************************
- */
- void fft_2dif(int n, double *x, double *y)
- {
- double a, e, xt, yt, c, s;
- int n1, n2, i, j, k, m, q;
- /*
- * Calculate m such that n=2^m
- *
- * NOTE: If frexp() == 1, then frexp does not conform
- * to the ANSI C spec of [0.5, 1)
- */
- m = (int)(log10(n) / log10(2));
- if( pow(2, m) != n)
- {
- printf("m must be 2's pow!\n");
- }
- /* --------------MAIN FFT LOOPS----------------------------- */
- /* Parameter adjustments */
- --y;
- --x;
- /* Function Body */
- n2 = n;
- for (k = 1; k <= m; ++k)
- {
- n1 = n2;
- n2 /= 2;
- e = (double)-6.283185307179586476925286766559005768394 / n1;
- a = 0.0;
- for (j = 1; j <= n2; ++j)
- {
- c = cos(a);
- s = sin(a);
- a = j * e;
- for (i = j;
- i <= n;
- i += n1
- )
- {
- q = i + n2;
- xt = x[i] - x[q];
- x[i] += x[q];
- yt = y[i] - y[q];
- y[i] += y[q];
- x[q] = c * xt - s * yt;
- y[q] = c * yt + s * xt;
- }
- }
- }
- /* ------------DIGIT REVERSE COUNTER----------------- */
- j = 1;
- n1 = n - 1;
- for (i = 1; i <= n1; ++i)
- {
- if (i < j)
- {
- xt = x[j];
- x[j] = x[i];
- x[i] = xt;
- xt = y[j];
- y[j] = y[i];
- y[i] = xt;
- }
- k = n / 2;
- while (k<j)
- {
- j -= k;
- k /= 2;
- }
- j += k;
- }
- }
- /*****************************************************************************
- *
- * ifft: IFFT implementation with Cooley-Tukey radix-2 DIF
- *
- * Arguments: n -- data number to be IFFT-ed
- * x -- poiter to the real section of FFT-ed data
- * y -- poiter to the imaginary section of FFT-ed data
- *
- * Notes: the only two difference between fft() and ifft() are:
- * (1) e = (double) 6.283185307179586476925286766559005768394 / n1, in
- fft()
- * changed to
- * e = (double)-6.283185307179586476925286766559005768394 / n1, in
- iff();
- * (2)each IFFT-ed data must be divied by n;
- *****************************************************************************
- */
- void ifft_2dif(int n, double *x, double *y)
- {
- double a, e, xt, yt, c, s;
- int n1, n2, i, j, k, m, q;
- /*
- * Calculate m such that n=2^m
- *
- * NOTE: If frexp() == 1, then frexp does not conform
- * to the ANSI C spec of [0.5, 1)
- */
- m = (int)(log10(n) / log10(2));
- if( pow(2, m) != n)
- {
- printf("m must be 2's pow!\n");
- }
- /* --------------MAIN FFT LOOPS----------------------------- */
- /* Parameter adjustments */
- --y;
- --x;
- /* Function Body */
- n2 = n;
- for (k = 1; k <= m; ++k) //step loops
- {
- n1 = n2;
- n2 /= 2;
- e = (double)6.283185307179586476925286766559005768394 / n1;
- a = 0.0;
- for (j = 1; j <= n2; ++j) //butterfly loops within each gr
- oup
- {
- c = cos(a);
- s = sin(a);
- a = j * e; //theta for calculating scale fa
- ctor
- for (i = j; //group loops
- i <= n;
- i += n1
- ) //top input of a butterfly
- {
- q = i + n2; //bottom input of a butterfly
- xt = x[i] - x[q];
- x[i] += x[q];
- yt = y[i] - y[q];
- y[i] += y[q];
- x[q] = c * xt - s * yt;
- y[q] = c * yt + s * xt;
- }
- }
- }
- /* ------------DIGIT REVERSE COUNTER----------------- */
- j = 1;
- n1 = n - 1;
- for (i = 1; i <= n1; ++i)
- {
- if (i < j)
- {
- xt = x[j];
- x[j] = x[i];
- x[i] = xt;
- xt = y[j];
- y[j] = y[i];
- y[i] = xt;
- }
- k = n / 2;
- while (k<j)
- {
- j -= k;
- k /= 2;
- }
- j += k;
- }
- //each IFFT-ed data must be divided by n
- for(i = 1; i <= n; i++)
- {
- x[i] = x[i]/n;
- y[i] = y[i]/n;
- }
- }
复制代码
这是matlab的,你用c实现一下就可以了
|