[ 簡単な説明 ] 高速フーリエ変換ライブラリの使用例です。 test16.c は、定数 CPX の定義の有無で、Complex 型入力と、double 型実数部・虚数部別入力を選択できるように、コーディングしています。1次元、2次元のルーチンでそれぞれFFT、逆FFTを行ない、結果を表示します。 test17.c は、fft1( )ルーチンを用いて、ベンチマークを行っています。 |
|
/* test16.c */ #include <stdio.h> #include "sslib.h" /*#define CPX /* Complex mode */ #ifndef CPX void print(double *ar, double *ai, int n); void print2(double *ar, double *ai, int n, int nmax); #else void printx(Complex *a, int n); void print2x(Complex *a, int n, int nmax); #endif #ifndef CPX void print(double *ar, double *ai, int n) { int i; double *p, *q; printf(" ar ai\n"); for(i = 0, p = ar, q = ai; i < n; i++) printf("%14.7e %14.7e\n", *p++, *q++); } #else void printx(Complex *a, int n) { int i; Complex *p; printf(" ar ai\n"); for(i = 0, p = a; i < n; i++, p++) printf("%14.7e %14.7e\n", p->r, p->i); } #endif #ifndef CPX void print2(double *ar, double *ai, int n, int nmax) { int i, j, k, l; double *p; printf("< ar >\n"); for(i = k = 0, p = ar; i < n; i++) { for(j = 0; j < nmax; j++, k++) printf("%14.7e ", *p++); putchar('\n'); } printf("< ai >\n"); for(i = k = 0, p = ai; i < n; i++) { for(j = 0; j < nmax; j++, k++) printf("%14.7e ", *p++); putchar('\n'); } } #else void print2x(Complex *a, int n, int nmax) { int i, j, k, l; Complex *p; printf("< Real part >\n"); for i = k = 0, p = a; i < n; i++) { for(j = 0; j < nmax; j++, k++, p++) printf("%14.7e ", p->r); putchar('\n'); } printf("< Imaginary part >\n"); for(i = k = 0, p = a; i < n; i++) { for(j = 0; j < nmax; j++, k++, p++) printf("%14.7e ", p->i); putchar('\n'); } } #endif int main(void) { static double ar[8] = { 0., 0., 0., 1., 1., 0., 0., 0.}; static double ai[8] = { 0., 0., 0., 0., 0., 0., 0., 0.}; static double ar2[16] = { 0., 0., 0., 0., 0., 1., 1., 0., 0., 1., 1., 0., 0., 0., 0., 0.}; static double ai2[16] = { 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.}; Complex a[8], a2[16]; int flag, i, iter, j, k, n, nmax; iter = 0; n = 8; #ifndef CPX for(i = 0; i < n; i++) a[i] = tocomplex(ar[i], ai[i]); print(ar, ai, n); #else printx(a, n); #endif /* forward FFT */ flag = 0; #ifndef CPX fft1(ar, ai, n, iter, flag); print(ar, ai, n); #else fft1x(a, n, iter, flag); printx(a, n); #endif /* reverse FFT */ flag = 1; #ifndef CPX fft1(ar, ai, n, iter, flag); print(ar, ai, n); #else fft1x(a, n, iter, flag); printx(a, n); #endif n = nmax = 4; for(i = k = 0; i < n; i++) for(j = 0; j < n; j++, k++) a2[k] = tocomplex(ar2[k], ai2[k]); #ifndef CPX print2(ar2, ai2, n, nmax); #else print2x(a2, n, nmax); #endif flag = 0; #ifndef CPX fft2(ar2, ai2, n, nmax, flag); print2(ar2, ai2, n, nmax); #else fft2x(a2, n, nmax, flag); print2x(a2, n, nmax); #endif flag = 1; #ifndef CPX fft2(ar2, ai2, n, nmax, flag); print2(ar2, ai2, n, nmax); #else fft2x(a2, n, nmax, flag); print2x(a2, n, nmax); #endif return 1; } |
ar ai 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 1.0000000e+00 0.0000000e+00 1.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 ar ai 2.0000000e+00 0.0000000e+00 -1.7071068e+00 -7.0710678e-01 1.0000000e+00 1.0000000e+00 -2.9289322e-01 -7.0710678e-01 0.0000000e+00 0.0000000e+00 -2.9289322e-01 7.0710678e-01 1.0000000e+00 -1.0000000e+00 -1.7071068e+00 7.0710678e-01 ar ai 0.0000000e+00 0.0000000e+00 1.9630836e-17 -2.6325784e-17 0.0000000e+00 0.0000000e+00 1.0000000e+00 -5.1675786e-17 1.0000000e+00 0.0000000e+00 -1.9630836e-17 2.9185367e-17 0.0000000e+00 0.0000000e+00 0.0000000e+00 4.8816203e-17 < ar > 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 1.0000000e+00 1.0000000e+00 0.0000000e+00 0.0000000e+00 1.0000000e+00 1.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 < ai > 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 < ar > 4.0000000e+00 -2.0000000e+00 0.0000000e+00 -2.0000000e+00 -2.0000000e+00 -1.1102230e-16 0.0000000e+00 2.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 -2.0000000e+00 2.0000000e+00 0.0000000e+00 1.1102230e-16 < ai > 0.0000000e+00 -2.0000000e+00 0.0000000e+00 2.0000000e+00 -2.0000000e+00 2.0000000e+00 0.0000000e+00 2.2204460e-16 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 2.0000000e+00 0.0000000e+00 0.0000000e+00 -2.0000000e+00 < ar > 1.3877788e-17 2.7755576e-17 -1.3877788e-17 -2.7755576e-17 0.0000000e+00 1.0000000e+00 1.0000000e+00 0.0000000e+00 0.0000000e+00 1.0000000e+00 1.0000000e+00 0.0000000e+00 0.0000000e+00 1.3877788e-17 0.0000000e+00 -1.3877788e-17 < ai > 0.0000000e+00 1.3877788e-17 0.0000000e+00 -1.3877788e-17 -1.4297916e-18 -3.2044950e-17 -1.4297916e-18 2.9185367e-17 0.0000000e+00 -3.0615159e-17 0.0000000e+00 3.0615159e-17 -1.2447996e-17 2.9185367e-17 1.5307579e-17 -2.6325784e-17 |
/* test17.c */ #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <time.h> #include "sslib.h" #define NN 1024 /* number of FFT sampling */ #define N 256 /* number of data */ static double f1[N], f2[N]; /* analysis data */ void sines_2(double *x, int n, double t1, double t2, double t3, double d1, double d2, double d3) { int i; double ii, *p, pi2, sc1, sc2, sc3; pi2 = 2. * M_PI; sc1 = pi2 / t1; sc2 = pi2 / t2; sc3 = pi2 / t3; d1 *= pi2; d2 *= pi2; d3 *= pi2; for(i = 0, ii = 0., p = x; i < n; i++, ii++) *p++ = (sin(ii * sc1 + d1) + sin(ii * sc2 + d2) / 2. + sin(ii * sc3 + d3) / 4.) / 1.75; } int main(void) { static double ar[8] = { 0., 0., 0., 1., 1., 0., 0., 0. }; static double ai[8] = { 0., 0., 0., 0., 0., 0., 0., 0. }; int i, iter, n, l; double err, maxerr, *x1, *y1; clock_t t1, t2; iter = 3; n = 8; printf(" ar ai\n"); for(i = 0; i < n; i++) printf("%14.7e %14.7e\n", ar[i], ai[i]); fft1(ar, ai, n, iter, 0); printf("<fourier transform>\n ar ai\n"); for(i = 0; i < n; i++) printf("%14.7e %14.7e\n", ar[i], ai[i]); fft1(ar, ai, n, iter, 1); printf("<reverse fourier transform>\n ar ai\n"); for(i = 0; i < n; i++) printf("%14.7e %14.7e\n", ar[i], ai[i]); printf("\n<Time Trial>\n"); n = i = NN; l = 0; while(i > 1) { i /= 2; l++; } x1 = (double *)malloc(n * sizeof(double)); y1 = (double *)malloc(n * sizeof(double)); if(x1 == NULL || y1 == NULL) { fprintf(stderr, "Error : Out of memory!\n"); exit(1); } sines_2(x1, n, 100., 25., 10., 0., 0.5, -0.25); for(i = 0; i < n; i++) y1[i] = 0.; t1 = clock(); for(i = 0; i < 500; i++) { fft1(x1, y1, n, l, 0); fft1(x1, y1, n, l, 1); } t2 = clock(); printf("fft1 (forward & reverse 50 times) : %ld [sec]\n", t2 - t1); free((char *)x1); free((char *)y1); return 1; } |
ar ai 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 1.0000000e+00 0.0000000e+00 1.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 <fourier transform> ar ai 2.0000000e+00 0.0000000e+00 -1.7071068e+00 -7.0710678e-01 1.0000000e+00 1.0000000e+00 -2.9289322e-01 -7.0710678e-01 0.0000000e+00 0.0000000e+00 -2.9289322e-01 7.0710678e-01 1.0000000e+00 -1.0000000e+00 -1.7071068e+00 7.0710678e-01 <reverse fourier transform> ar ai 0.0000000e+00 0.0000000e+00 1.9630836e-17 -2.6325784e-17 0.0000000e+00 0.0000000e+00 1.0000000e+00 -5.1675786e-17 1.0000000e+00 0.0000000e+00 -1.9630836e-17 2.9185367e-17 0.0000000e+00 0.0000000e+00 0.0000000e+00 4.8816203e-17 <Time Trial> fft1 (forward & reverse 50 times) : 163 [sec] |