00001
00007 #include <stdio.h>
00008 #include <stdlib.h>
00009 #include <string.h>
00010 #include <math.h>
00011 #include <malloc.h>
00012 #include <sys/time.h>
00013 #include "tuple.h"
00014
00015
00016
00017 static void compute_W(int n, double *W_re, double *W_im);
00018 static void permute_bitrev(int n, double *A_re, double *A_im);
00019 static int bitrev(int inp, int numbits);
00020 static int log_2(int n);
00021 static void fft(int n, double *A_re, double *A_im, double *W_re, double *W_im);
00022
00023
00024
00035 int main(int argc, char *argv[])
00036 {
00037 struct context ctx;
00038 struct tuple *s, *t, *u;
00039 double *A_re, *A_im, *W_re, *W_im;
00040
00041 if (get_server_portnumber(&ctx)) {
00042 if (argc < 3) {
00043
00044 fprintf(stderr,
00045 "Usage: %s <server> <pornumber>\n",
00046 argv[0]);
00047 return 1;
00048 }
00049 strcpy(ctx.servername, argv[1]);
00050 ctx.portnumber = atoi(argv[2]);
00051 }
00052
00053 s = make_tuple("s?????", "fft");
00054 t = make_tuple("s???ss", "fft done", "", "");
00055
00056 while (1) {
00057 int n;
00058 u = get_tuple(s, &ctx);
00059 if (u == NULL) {
00060 perror("get_tuple failed");
00061 exit(1);
00062 }
00063 A_re = (double*) tuple_string_field(u, &n, 4);
00064 n /= sizeof(double);
00065 A_im = (double*) tuple_string_field(u, NULL, 5);
00066
00067 W_re = (double*)malloc(sizeof(double)*n/2);
00068 if (W_re == NULL) {
00069 fprintf(stderr, "out of memory\n");
00070 return 1;
00071 }
00072 W_im = (double*)malloc(sizeof(double)*n/2);
00073 if (W_im == NULL) {
00074 fprintf(stderr, "out of memory\n");
00075 return 1;
00076 }
00077
00078 compute_W(n, W_re, W_im);
00079 fft(n, A_re, A_im, W_re, W_im);
00080 permute_bitrev(n, A_re, A_im);
00081
00082 t->elements[1] = u->elements[1];
00083 t->elements[2] = u->elements[2];
00084 t->elements[3] = u->elements[3];
00085
00086 t->elements[4].data.s.len = n * sizeof(double);
00087 t->elements[5].data.s.len = n * sizeof(double);
00088 t->elements[4].data.s.ptr = (char*) A_re;
00089 t->elements[5].data.s.ptr = (char*) A_im;
00090
00091 if (put_tuple(t, &ctx)) {
00092 perror("put_tuple failed");
00093 exit(1);
00094 }
00095 free(W_re);
00096 free(W_im);
00097 }
00098
00099 return 0;
00100 }
00101
00102
00103
00113 static void compute_W(int n, double *W_re, double *W_im)
00114 {
00115 int i, br;
00116 int log2n = log_2(n);
00117
00118 for (i = 0; i < (n/2); i++) {
00119 br = bitrev(i,log2n-1);
00120 W_re[br] = cos(((double)i*2.0*M_PI)/((double)n));
00121 W_im[br] = sin(((double)i*2.0*M_PI)/((double)n));
00122 }
00123 }
00124
00125
00129 static void permute_bitrev(int n, double *A_re, double *A_im)
00130 {
00131 int i, bri, log2n;
00132 double t_re, t_im;
00133
00134 log2n = log_2(n);
00135
00136 for (i = 0; i < n; i++) {
00137 bri = bitrev(i, log2n);
00138
00139
00140 if (bri <= i) continue;
00141
00142 t_re = A_re[i];
00143 t_im = A_im[i];
00144 A_re[i]= A_re[bri];
00145 A_im[i]= A_im[bri];
00146 A_re[bri]= t_re;
00147 A_im[bri]= t_im;
00148 }
00149 }
00150
00151
00156 static int bitrev(int inp, int numbits)
00157 {
00158 int i, rev = 0;
00159 for (i = 0; i < numbits; i++) {
00160 rev = (rev << 1) | (inp & 1);
00161 inp >>= 1;
00162 }
00163 return rev;
00164 }
00165
00166
00170 static int log_2(int n)
00171 {
00172 int res;
00173 for (res = 0; n >= 2; res++)
00174 n = n >> 1;
00175 return res;
00176 }
00177
00188 static void fft(int n, double *A_re, double *A_im, double *W_re, double *W_im)
00189 {
00190 double w_re, w_im, u_re, u_im, t_re, t_im;
00191 int m, g, b;
00192 int mt, k;
00193
00194
00195 for (m = n; m >= 2; m >>= 1) {
00196 mt = m >> 1;
00197
00198
00199 for (g = 0, k = 0; g < n; g += m, k++) {
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215 w_re = W_re[k];
00216 w_im = W_im[k];
00217
00218
00219 for (b = g; b < (g+mt); b++) {
00220 t_re = w_re * A_re[b+mt] - w_im * A_im[b+mt];
00221 t_im = w_re * A_im[b+mt] + w_im * A_re[b+mt];
00222
00223 u_re = A_re[b];
00224 u_im = A_im[b];
00225 A_re[b] = u_re + t_re;
00226 A_im[b] = u_im + t_im;
00227 A_re[b+mt] = u_re - t_re;
00228 A_im[b+mt] = u_im - t_im;
00229
00230 }
00231 }
00232 }
00233 }