void FastMul(const BigInt &A,const BigInt &B, BigInt &C) { ulong Len = 2; while ( Len < A.Size + B.Size ) Len *=2; if ( Len < 40 ) { BigInt Atmp(A), Btmp(B); Mul(Atmp,Btmp,C); return; } ulong x; const ushort *a=A.Coef, *b=B.Coef; for (x = 0; x < A.Size; x++) LongNum1[x] = a[x]; for (; x < Len; x++) LongNum1[x] = 0.0; FHT_F(LongNum1,Len); if (a == b) { FHTConvolution(LongNum1,LongNum1,Len); } else { for (x = 0; x < B.Size; x++) LongNum2[x] = b[x]; for (; x < Len; x++) LongNum2[x] = 0.0; FHT_F(LongNum2,Len); FHTConvolution(LongNum1,LongNum2,Len); } FHT_T(LongNum1,Len); CarryNormalize(LongNum1, Len, C); }
void RFHT_T(FFT_DATA_TYPE *Data,int Len) /* ** recursive Decimation in Time style Fast Hartley Transform */ {int x,Len2,Len4; TRIG_VARS FFT_DATA_TYPE *Left,*Right; Len/=2;Right=&Data[Len];Left=&Data[0]; if (Len<4) FatalError("OOps, how did rfht get called with %d\n",Len*2); if (Len==4) {FFT_DATA_TYPE d45,d67,sd0123,dd0123; StartTimer(FFTRTime); StartTimer(CRTTime); {FFT_DATA_TYPE ss0123,ds0123,ss4567,ds4567; {FFT_DATA_TYPE s01,s23,d01,d23; DD_Sub(&Data[0],&Data[1],&d01); DD_Add(&Data[0],&Data[1],&s01); DD_Sub(&Data[2],&Data[3],&d23); DD_Add(&Data[2],&Data[3],&s23); DD_Sub(&s01,&s23,&ds0123); DD_Add(&s01,&s23,&ss0123); DD_Sub(&d01,&d23,&dd0123); DD_Add(&d01,&d23,&sd0123); } {FFT_DATA_TYPE s45,s67; DD_Add(&Data[4],&Data[5],&s45); DD_Add(&Data[6],&Data[7],&s67); DD_Sub(&Data[4],&Data[5],&d45); DD_Sub(&Data[6],&Data[7],&d67); DD_Sub(&s45,&s67,&ds4567); DD_Add(&s45,&s67,&ss4567); } DD_Sub(&ss0123,&ss4567,&Data[4]); DD_Add(&ss0123,&ss4567,&Data[0]); DD_Sub(&ds0123,&ds4567,&Data[6]); DD_Add(&ds0123,&ds4567,&Data[2]); } DD_Mul(&d45,&Sqrt2,&d45); DD_Mul(&d67,&Sqrt2,&d67); DD_Sub(&sd0123,&d45,&Data[5]); DD_Add(&sd0123,&d45,&Data[1]); DD_Sub(&dd0123,&d67,&Data[7]); DD_Add(&dd0123,&d67,&Data[3]); StopTimer(FFTRTime); StopTimer(CRTTime); return; } if (Len<=(CPU_CACHE/sizeof(FFT_DATA_TYPE))) {FHT_T(Data,Len*2);return;} RFHT_T(&Left[0], Len); RFHT_T(&Right[0],Len); StartTimer(FFTRTime); /* Do the special x=0 loop below. */ FHT_T1Butterfly(0,0,1.0,0.0); INIT_TRIG(Len); Len2=Len/2; Len4=Len/4; for (x=1;x<Len4;x++) { NEXT_TRIG_POW; FHT_T2Butterfly(x,Len-x,Pow_r,Pow_i); FHT_T2Butterfly(Len2-x,Len2+x,Pow_i,Pow_r); } /* Now do the two Len/4 points the loop missed */ if (Len4) // {FFT_DATA_TYPE sq=MY_SQRT_2; /* variable allows optimizations */ // FHT_T2Butterfly(Len4,Len-Len4,sq,sq); { FHT_T2Butterfly(Len4,Len-Len4,Sqrt05,Sqrt05); } /* Now do the Len/2 point the loop couldn't do. */ if (Len2) FHT_T1Butterfly(Len2,Len2,0.0,1.0); StopTimer(FFTRTime); }