bluestein.c
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 #include <math.h>
00031 #include <stdlib.h>
00032 #include "fftpack.h"
00033 #include "bluestein.h"
00034
00035
00036 size_t prime_factor_sum (size_t n)
00037 {
00038 size_t result=0,x,limit,tmp;
00039 while (((tmp=(n>>1))<<1)==n)
00040 { result+=2; n=tmp; }
00041
00042 limit=(size_t)sqrt(n+0.01);
00043 for (x=3; x<=limit; x+=2)
00044 while ((tmp=(n/x))*x==n)
00045 {
00046 result+=x;
00047 n=tmp;
00048 limit=(size_t)sqrt(n+0.01);
00049 }
00050 if (n>1) result+=n;
00051
00052 return result;
00053 }
00054
00055
00056 static size_t good_size(size_t n)
00057 {
00058 size_t f2, f23, f235, bestfac=2*n;
00059 if (n<=6) return n;
00060
00061 for (f2=1; f2<bestfac; f2*=2)
00062 for (f23=f2; f23<bestfac; f23*=3)
00063 for (f235=f23; f235<bestfac; f235*=5)
00064 if (f235>=n) bestfac=f235;
00065 return bestfac;
00066 }
00067
00068 void bluestein_i (size_t n, double **tstorage, size_t *worksize)
00069 {
00070 static const double pi=3.14159265358979323846;
00071 size_t n2=good_size(n*2-1);
00072 size_t m, coeff;
00073 double angle, xn2;
00074 double *bk, *bkf, *work;
00075 double pibyn=pi/n;
00076 *worksize=2+2*n+8*n2+16;
00077 *tstorage = RALLOC(double,2+2*n+8*n2+16);
00078 ((size_t *)(*tstorage))[0]=n2;
00079 bk = *tstorage+2;
00080 bkf = *tstorage+2+2*n;
00081 work= *tstorage+2+2*(n+n2);
00082
00083
00084 bk[0] = 1;
00085 bk[1] = 0;
00086
00087 coeff=0;
00088 for (m=1; m<n; ++m)
00089 {
00090 coeff+=2*m-1;
00091 if (coeff>=2*n) coeff-=2*n;
00092 angle = pibyn*coeff;
00093 bk[2*m] = cos(angle);
00094 bk[2*m+1] = sin(angle);
00095 }
00096
00097
00098 xn2 = 1./n2;
00099 bkf[0] = bk[0]*xn2;
00100 bkf[1] = bk[1]*xn2;
00101 for (m=2; m<2*n; m+=2)
00102 {
00103 bkf[m] = bkf[2*n2-m] = bk[m] *xn2;
00104 bkf[m+1] = bkf[2*n2-m+1] = bk[m+1] *xn2;
00105 }
00106 for (m=2*n;m<=(2*n2-2*n+1);++m)
00107 bkf[m]=0.;
00108 cffti (n2,work);
00109 cfftf (n2,bkf,work);
00110 }
00111
00112 void bluestein (size_t n, double *data, double *tstorage, int isign)
00113 {
00114 size_t n2=*((size_t *)tstorage);
00115 size_t m;
00116 double *bk, *bkf, *akf, *work;
00117 bk = tstorage+2;
00118 bkf = tstorage+2+2*n;
00119 work= tstorage+2+2*(n+n2);
00120 akf = tstorage+2+2*n+6*n2+16;
00121
00122
00123 if (isign>0)
00124 for (m=0; m<2*n; m+=2)
00125 {
00126 akf[m] = data[m]*bk[m] - data[m+1]*bk[m+1];
00127 akf[m+1] = data[m]*bk[m+1] + data[m+1]*bk[m];
00128 }
00129 else
00130 for (m=0; m<2*n; m+=2)
00131 {
00132 akf[m] = data[m]*bk[m] + data[m+1]*bk[m+1];
00133 akf[m+1] =-data[m]*bk[m+1] + data[m+1]*bk[m];
00134 }
00135 for (m=2*n; m<2*n2; ++m)
00136 akf[m]=0;
00137
00138 cfftf (n2,akf,work);
00139
00140
00141 if (isign>0)
00142 for (m=0; m<2*n2; m+=2)
00143 {
00144 double im = -akf[m]*bkf[m+1] + akf[m+1]*bkf[m];
00145 akf[m ] = akf[m]*bkf[m] + akf[m+1]*bkf[m+1];
00146 akf[m+1] = im;
00147 }
00148 else
00149 for (m=0; m<2*n2; m+=2)
00150 {
00151 double im = akf[m]*bkf[m+1] + akf[m+1]*bkf[m];
00152 akf[m ] = akf[m]*bkf[m] - akf[m+1]*bkf[m+1];
00153 akf[m+1] = im;
00154 }
00155
00156
00157
00158 cfftb (n2,akf,work);
00159
00160
00161 if (isign>0)
00162 for (m=0; m<2*n; m+=2)
00163 {
00164 data[m] = bk[m] *akf[m] - bk[m+1]*akf[m+1];
00165 data[m+1] = bk[m+1]*akf[m] + bk[m] *akf[m+1];
00166 }
00167 else
00168 for (m=0; m<2*n; m+=2)
00169 {
00170 data[m] = bk[m] *akf[m] + bk[m+1]*akf[m+1];
00171 data[m+1] =-bk[m+1]*akf[m] + bk[m] *akf[m+1];
00172 }
00173 }