ソース
0~π/4のsin,cosをテーブル化。π/4~π/2はsin,cosを入れ替えて使用。
ad_t *sc2 = NULL;
inline unsigned int bitrv_v(int nx, unsigned int a );
void *mk_sincos_table2(int nx)
{
int i,j,k,m,n,nr;
double r;
n=1<<nx;
sc2=(ad_t *)malloc(sizeof(ad_t)*n/4);
r = M_PI /(double)n;
for(j= 2 ; j < n; j *= 2) {
i = j / 4;
for(k = 0; k < j/2; k+=2) {
nr = j + k ;
m = bitrv_v(nx,nr);
/* wi = cos(r*(double)m)*0.5; */
/* wr = sin(r*(double)m)*0.5; */
sc2[i].i=cos(r*(double)m)*0.5;
sc2[i].r=sin(r*(double)m)*0.5;
i++;
}
}
}
/* 実数fft後処理+乗算+実数ifft前処理 */
/* c = a * b ; a=b=c OK */
void *r_mul( int nx,ad_t c[],ad_t a[],ad_t b[] )
{
double wr,wi,tmpr,tmpi;
ad_t anr,amr,bnr,bmr;
int m,n,mr,nr,j,k ;
/* double r ; */
n = 1<< nx;
anr.r = a[0].r + a[0].i ;
anr.i = a[0].r - a[0].i ;
anr.r *= b[0].r + b[0].i ;
anr.i *= b[0].r - b[0].i ;
c[0].r = (anr.r + anr.i)*0.5 ;
c[0].i = (anr.r - anr.i)*0.5 ;
anr = a[1];
bnr = b[1];
c[1].r = anr.r * bnr.r - anr.i * bnr.i ;
c[1].i = anr.r * bnr.i + anr.i * bnr.r ;
/* r = M_PI /(double)n; */
/* m = 0; */
for(j= 2 ; j < n; j *= 2) {
m = j/4 -1 ;
for(k = 0; k < j; k+=2) {
nr = j + k ;
mr = j*2-1-k ;
/* m = inc_rvbit(nx-1,m); */
/* wi = cos(r*(double)m)*0.5; */
/* wr = sin(r*(double)m)*0.5+0.5;*/
if ( k < j/2 ){
m ++ ;
wi = sc2[m].i;
wr = sc2[m].r+0.5;
}else{
wi = sc2[m].r;
wr = sc2[m].i+0.5;
m --;
}
#ifdef FFT_INDEX_CHECK
if(nr < 0 ) { printf("r_mul index under nr\n"); exit ;};
if(mr< 0 ) { printf("r_mul index under mr\n"); exit ;};
if(m< 0 ) { printf("r_mul index under m\n"); exit ;};
if(nr >=n ) { printf("r_mul index over nr\n"); exit ;};
if(mr >=n ) { printf("r_mul index over mr\n"); exit ;};
if(m >=n/4 ){ printf("r_mul index over m\n"); exit ;};
#endif
anr = a[nr];
amr = a[mr];
bnr = b[nr];
bmr = b[mr];
/* fft 後処理 a */
tmpr = wr * (anr.r - amr.r) - wi * (anr.i + amr.i);
tmpi = wr * (anr.i + amr.i) + wi * (anr.r - amr.r);
anr.r = anr.r - tmpr ;
anr.i = anr.i - tmpi;
amr.r = amr.r + tmpr ;
amr.i = amr.i - tmpi;
/* fft 後処理 b */
tmpr = wr * (bnr.r - bmr.r) - wi * (bnr.i + bmr.i);
tmpi = wr * (bnr.i + bmr.i) + wi * (bnr.r - bmr.r);
bnr.r = bnr.r - tmpr ;
bnr.i = bnr.i - tmpi;
bmr.r = bmr.r + tmpr ;
bmr.i = bmr.i - tmpi;
/* 乗算 */
tmpr = anr.r ;
anr.r = tmpr * bnr.r - anr.i * bnr.i ;
anr.i = tmpr * bnr.i + anr.i * bnr.r ;
tmpr = amr.r ;
amr.r = tmpr * bmr.r - amr.i * bmr.i ;
amr.i = tmpr * bmr.i + amr.i * bmr.r ;
/* ifft 前処理 */
tmpr = wr * (anr.r - amr.r) + wi * (anr.i + amr.i);
tmpi = wr * (anr.i + amr.i) - wi * (anr.r - amr.r);
c[nr].r = anr.r - tmpr ;
c[nr].i = anr.i - tmpi;
c[mr].r = amr.r + tmpr ;
c[mr].i = amr.i - tmpi;
}
}
}
|
結果
No.1 n=67108864=1<<26 radix=1000 fft 39.964405 , r_mul 5.791993 , ifft 38.881574 , error 0.085938 No.2 n=67108864=1<<26 radix=1000 fft 38.348005 , r_mul 5.744716 , ifft 41.086747 , error 0.085938 No.3 n=67108864=1<<26 radix=1000 fft 3.771606 , r_mul 4.460116 , ifft 4.872133 , error 0.046875 No.4 n=67108864=1<<26 radix=1000 fft 3.780859 , r_mul 3.618985 , ifft 4.872954 , error 0.046875 No.5 n=67108864=1<<26 radix=1000 fft 3.802325 , r_mul 1.972648 , ifft 4.882619 , error 0.046875 No.6 n=67108864=1<<26 radix=1000 fft 3.779546 , r_mul 0.482001 , ifft 4.864007 , error 0.046875 |
sin,cosテーブルを、n=67108864=1<<26 で作成
mk_sincos_table* 1.746971 n=67108864=1<<26 radix=1000 fft 3.779546 , r_mul 0.482001 , ifft 4.864007 , error 0.046875 mk_sincos_table* 1.739643 n=33554432=1<<25 radix=1000 fft 1.801143 , r_mul 0.239757 , ifft 2.291959 , error 0.023438 mk_sincos_table* 1.743299 n=16777216=1<<24 radix=1000 fft 0.867854 , r_mul 0.119740 , ifft 1.079338 , error 0.009766 |
0 件のコメント:
コメントを投稿