00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include <stdlib.h>
00033 #include <math.h>
00034 #include <string.h>
00035 #include "bluestein.h"
00036 #include "fftpack.h"
00037 #include "ls_fft.h"
00038
00039 complex_plan make_complex_plan (int length)
00040 {
00041 complex_plan plan = (complex_plan) malloc(sizeof(complex_plan_i));
00042 int pfsum = prime_factor_sum(length);
00043 double comp1 = length*pfsum;
00044 double comp2 = 2*3*length*log(3.*length);
00045 plan->length=length;
00046 plan->bluestein = (comp2<comp1);
00047 if (plan->bluestein)
00048 bluestein_i (length,&(plan->work));
00049 else
00050 {
00051 plan->work=(double *)malloc((4*length+15)*sizeof(double));
00052 cffti(length, plan->work);
00053 }
00054 return plan;
00055 }
00056
00057 void kill_complex_plan (complex_plan plan)
00058 {
00059 free(plan->work);
00060 free(plan);
00061 }
00062
00063 void complex_plan_forward (complex_plan plan, double *data)
00064 {
00065 if (plan->bluestein)
00066 bluestein (plan->length, data, plan->work, -1);
00067 else
00068 cfftf (plan->length, data, plan->work);
00069 }
00070
00071 void complex_plan_backward (complex_plan plan, double *data)
00072 {
00073 if (plan->bluestein)
00074 bluestein (plan->length, data, plan->work, 1);
00075 else
00076 cfftb (plan->length, data, plan->work);
00077 }
00078
00079
00080 real_plan make_real_plan (int length)
00081 {
00082 real_plan plan = (real_plan) malloc(sizeof(real_plan_i));
00083 int pfsum = prime_factor_sum(length);
00084 double comp1 = .5*length*pfsum;
00085 double comp2 = 2*3*length*log(3.*length);
00086 plan->length=length;
00087 plan->bluestein = (comp2<comp1);
00088 if (plan->bluestein)
00089 bluestein_i (length,&(plan->work));
00090 else
00091 {
00092 plan->work=(double *)malloc((2*length+15)*sizeof(double));
00093 rffti(length, plan->work);
00094 }
00095 return plan;
00096 }
00097
00098 void kill_real_plan (real_plan plan)
00099 {
00100 free(plan->work);
00101 free(plan);
00102 }
00103
00104 void real_plan_forward_fftpack (real_plan plan, double *data)
00105 {
00106 if (plan->bluestein)
00107 {
00108 int m;
00109 int n=plan->length;
00110 double *tmp = (double *)malloc(2*n*sizeof(double));
00111 for (m=0; m<n; ++m)
00112 {
00113 tmp[2*m] = data[m];
00114 tmp[2*m+1] = 0.;
00115 }
00116 bluestein(n,tmp,plan->work,-1);
00117 data[0] = tmp[0];
00118 memcpy (data+1, tmp+2, (n-1)*sizeof(double));
00119 free (tmp);
00120 }
00121 else
00122 rfftf (plan->length, data, plan->work);
00123 }
00124
00125 static void fftpack2halfcomplex (double *data, int n)
00126 {
00127 int m;
00128 double *tmp = (double *)malloc(n*sizeof(double));
00129 tmp[0]=data[0];
00130 for (m=1; m<(n+1)/2; ++m)
00131 {
00132 tmp[m]=data[2*m-1];
00133 tmp[n-m]=data[2*m];
00134 }
00135 if (!(n&1))
00136 tmp[n/2]=data[n-1];
00137 memcpy (data,tmp,n*sizeof(double));
00138 free(tmp);
00139 }
00140
00141 static void halfcomplex2fftpack (double *data, int n)
00142 {
00143 int m;
00144 double *tmp = (double *)malloc(n*sizeof(double));
00145 tmp[0]=data[0];
00146 for (m=1; m<(n+1)/2; ++m)
00147 {
00148 tmp[2*m-1]=data[m];
00149 tmp[2*m]=data[n-m];
00150 }
00151 if (!(n&1))
00152 tmp[n-1]=data[n/2];
00153 memcpy (data,tmp,n*sizeof(double));
00154 free(tmp);
00155 }
00156
00157 void real_plan_forward_fftw (real_plan plan, double *data)
00158 {
00159 real_plan_forward_fftpack (plan, data);
00160 fftpack2halfcomplex (data,plan->length);
00161 }
00162
00163 void real_plan_backward_fftpack (real_plan plan, double *data)
00164 {
00165 if (plan->bluestein)
00166 {
00167 int m;
00168 int n=plan->length;
00169 double *tmp = (double *)malloc(2*n*sizeof(double));
00170 tmp[0]=data[0];
00171 tmp[1]=0.;
00172 memcpy (tmp+2,data+1, (n-1)*sizeof(double));
00173 if ((n&1)==0) tmp[n+1]=0.;
00174 for (m=2; m<n; m+=2)
00175 {
00176 tmp[2*n-m]=tmp[m];
00177 tmp[2*n-m+1]=-tmp[m+1];
00178 }
00179 bluestein (n, tmp, plan->work, 1);
00180 for (m=0; m<n; ++m)
00181 data[m] = tmp[2*m];
00182 free (tmp);
00183 }
00184 else
00185 rfftb (plan->length, data, plan->work);
00186 }
00187
00188 void real_plan_backward_fftw (real_plan plan, double *data)
00189 {
00190 halfcomplex2fftpack (data,plan->length);
00191 real_plan_backward_fftpack (plan, data);
00192 }
00193
00194 void real_plan_forward_c (real_plan plan, double *data)
00195 {
00196 int m;
00197 int n=plan->length;
00198
00199 if (plan->bluestein)
00200 {
00201 for (m=1; m<2*n; m+=2)
00202 data[m]=0;
00203 bluestein (plan->length, data, plan->work, -1);
00204 data[1]=0;
00205 for (m=2; m<n; m+=2)
00206 {
00207 double avg;
00208 avg = 0.5*(data[2*n-m]+data[m]);
00209 data[2*n-m] = data[m] = avg;
00210 avg = 0.5*(data[2*n-m+1]-data[m+1]);
00211 data[2*n-m+1] = avg;
00212 data[m+1] = -avg;
00213 }
00214 if ((n&1)==0) data[n+1] = 0.;
00215 }
00216 else
00217 {
00218 for (m=0; m<n; ++m) data[m+1] = data[2*m];
00219 rfftf (n, data+1, plan->work);
00220 data[0] = data[1];
00221 data[1] = 0;
00222 for (m=2; m<n; m+=2)
00223 {
00224 data[2*n-m] = data[m];
00225 data[2*n-m+1] = -data[m+1];
00226 }
00227 if ((n&1)==0) data[n+1] = 0.;
00228 }
00229 }
00230
00231 void real_plan_backward_c (real_plan plan, double *data)
00232 {
00233 int m;
00234 int n=plan->length;
00235
00236 if (plan->bluestein)
00237 {
00238 data[1]=0;
00239 for (m=2; m<n; m+=2)
00240 {
00241 double avg;
00242 avg = 0.5*(data[2*n-m]+data[m]);
00243 data[2*n-m] = data[m] = avg;
00244 avg = 0.5*(data[2*n-m+1]-data[m+1]);
00245 data[2*n-m+1] = avg;
00246 data[m+1] = -avg;
00247 }
00248 if ((n&1)==0) data[n+1] = 0.;
00249 bluestein (plan->length, data, plan->work, 1);
00250 for (m=1; m<2*n; m+=2)
00251 data[m]=0;
00252 }
00253 else
00254 {
00255 data[1] = data[0];
00256 rfftb (n, data+1, plan->work);
00257 for (m=n-1; m>=0; --m)
00258 {
00259 data[2*m] = data[m+1];
00260 data[2*m+1] = 0.;
00261 }
00262 }
00263 }