Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define Xr(i) x[dX*(i)]
- #define Xi(i) x[dX*(i)+1]
- #define Wr(i) w[dX*(i)]
- #define Wi(i) w[dX*(i)+1]
- #define Yr(i) y[dY*(i)]
- #define Yi(i) y[dY*(i)+1]
- #define Wpr(i) Wp[dWp*(i)]
- #define Wpi(i) Wp[dWp*(i)+1]
- #define Wnr(i) Wn[dWp*(i)]
- #define Wni(i) Wn[dWp*(i)+1]
- #define Ynr(i) yn[dY*(i)]
- #define Yni(i) yn[dY*(i)+1]
- /* Fast Fourier Series */
- void FFT(int N, double *x, double *w, int dX, double *y, int dY, double *Wp, int dWp) {
- int i, Nyd, NWpd;
- double *xe, *ye, *yn, *We, *Wn, re, im, RE, IM, ra, ia;
- double t0, t1, t2, t3;
- switch (N) {
- case 1:
- /* CN = [ 1 ] */
- Xr(0) = Yr(0);
- Xi(0) = Yi(0);
- break;
- #if silly_fast
- case 2:
- /* CN = [ 1 1 ]
- [ 1 -1 ] */
- Xr(0) = Yr(0) + Yr(1);
- Xi(0) = Yi(0) + Yi(1);
- Xr(1) = Yr(0) - Yr(1);
- Xi(1) = Yi(0) - Yi(1);
- break;
- #endif
- #if faster
- case 3:
- /* CN = [ 1 1 1 ]
- [ 1 w w*]
- [ 1 w* w ]
- */
- re = Wpr(1);
- im = Wpi(1);
- Xr(0) = Yr(0) + Yr(1) + Yr(2);
- Xi(0) = Yi(0) + Yi(1) + Yi(2);
- Xr(1) = Xr(2) = Yr(0) + (Yr(1) + Yr(2))*re;
- Xi(1) = Xi(2) = Yi(0) + (Yi(1) + Yi(2))*re;
- ra = (Yi(2) - Yi(1))*im;
- ia = (Yr(1) - Yr(2))*im;
- Xr(1) += ra;
- Xi(1) += ia;
- Xr(2) -= ra;
- Xi(2) -= ia;
- break;
- #endif
- #if even_faster
- case 4:
- /* CN = [ 1 1 1 1 ]
- [ 1 i -1 -i ]
- [ 1 -1 1 -1 ]
- [ 1 -i -1 i ] */
- Xr(0) = Xr(2) = Yr(0) + Yr(2);
- Xi(0) = Xi(2) = Yi(0) + Yi(2);
- ra = Yr(1) + Yr(3);
- ia = Yi(1) + Yi(3);
- Xr(0) += ra;
- Xi(0) += ia;
- Xr(2) -= ra;
- Xi(2) -= ia;
- Xr(1) = Xr(3) = Yr(0) - Yr(2);
- Xi(1) = Xi(3) = Yi(0) - Yi(2);
- ra = Yi(3) - Yi(1);
- ia = Yr(1) - Yr(3);
- if (dWp > 0) { /* FastDFS */
- Xr(1) += ra;
- Xi(1) += ia;
- Xr(3) -= ra;
- Xi(3) -= ia;
- }
- else { /* FastDFT */
- Xr(1) -= ra;
- Xi(1) -= ia;
- Xr(3) += ra;
- Xi(3) += ia;
- }
- break;
- #endif
- #if faster
- case 5:
- /* CN = [ 1 1 1 1 1 ]
- [ 1 w q q* w*]
- [ 1 q w* w q*]
- [ 1 q* w w* q ]
- [ 1 w* q* q w ]
- q = w^2 */
- re = Wpr(1);
- im = Wpi(1);
- RE = Wpr(2);
- IM = Wpi(2);
- Xr(0) = Yr(0) + Yr(1) + Yr(2) + Yr(3) + Yr(4);
- Xi(0) = Yi(0) + Yi(1) + Yi(2) + Yi(3) + Yi(4);
- Xr(1) = Xr(4) = Yr(0) + (t0 = Yr(1) + Yr(4))*re + (t1 = Yr(2) + Yr(3))*RE;
- Xi(1) = Xi(4) = Yi(0) + (t2 = Yi(1) + Yi(4))*re + (t3 = Yi(2) + Yi(3))*RE;
- Xr(2) = Xr(3) = Yr(0) + t1*re + t0*RE;
- Xi(2) = Xi(3) = Yi(0) + t3*re + t2*RE;
- ra = (t0 = Yi(4) - Yi(1))*im + (t1 = Yi(3) - Yi(2))*IM;
- ia = (t2 = Yr(1) - Yr(4))*im + (t3 = Yr(2) - Yr(3))*IM;
- Xr(1) += ra;
- Xi(1) += ia;
- Xr(4) -= ra;
- Xi(4) -= ia;
- ra = t0*IM - t1*im;
- ia = t2*IM - t3*im;
- Xr(2) += ra;
- Xi(2) += ia;
- Xr(3) -= ra;
- Xi(3) -= ia;
- break;
- #endif
- #if silly_fast
- case 6:
- /* CN = [ 1 1 1 1 1 1 ]
- [ 1 w #w -1 -w w*]
- [ 1 #w -w 1 #w -w ]
- [ 1 -1 1 -1 1 -1 ]
- [ 1 -w #w 1 -w #w ]
- [ 1 w* -w -1 #w w ]
- #w = -(w*) */
- re = Wpr(1);
- im = Wpi(1);
- Xr(0) = Xr(3) = Yr(0) + Yr(2) + Yr(4);
- Xi(0) = Xi(3) = Yi(0) + Yi(2) + Yi(4);
- ra = Yr(1) + Yr(3) + Yr(5);
- ia = Yi(1) + Yi(3) + Yi(5);
- Xr(0) += ra;
- Xi(0) += ia;
- Xr(3) -= ra;
- Xi(3) -= ia;
- Xr(1) = Xr(2) = Xr(4) = Xr(5) = Yr(0) - re*(Yr(2) + Yr(4));
- Xi(1) = Xi(2) = Xi(4) = Xi(5) = Yi(0) - re*(Yi(2) + Yi(4));
- ra = im*(Yi(4) - Yi(2));
- ia = im*(Yr(2) - Yr(4));
- Xr(1) += ra; Xr(4) += ra;
- Xi(1) += ia; Xi(4) += ia;
- Xr(2) -= ra; Xr(5) -= ra;
- Xi(2) -= ia; Xi(5) -= ia;
- ra = re*(Yr(1) + Yr(5)) - Yr(3);
- ia = re*(Yi(1) + Yi(5)) - Yi(3);
- Xr(1) += ra; Xr(4) -= ra;
- Xi(1) += ia; Xi(4) -= ia;
- Xr(2) -= ra; Xr(5) += ra;
- Xi(2) -= ia; Xi(5) += ia;
- ra = im*(Yi(5) - Yi(1));
- ia = im*(Yr(1) - Yr(5));
- Xr(1) += ra; Xr(4) -= ra;
- Xi(1) += ia; Xi(4) -= ia;
- Xr(2) += ra; Xr(5) -= ra;
- Xi(2) += ia; Xi(5) -= ia;
- break;
- #endif
- default:
- if ((N%2) != 0) {
- Nyd = N*dY;
- NWpd = N*dWp;
- ye = y + Nyd, We = Wp + NWpd;
- Xr(0) = Yr(0);
- Xi(0) = Yi(0);
- for (yn = y+dY; yn < ye; yn += dY) {
- Xr(0) += Ynr(0);
- Xi(0) += Yni(0);
- }
- x += dX;
- for (Wn = Wp, i = dWp; i*dWp < NWpd*dWp; i += dWp, x += dX, Wn = Wp) {
- Xr(0) = Yr(0);
- Xi(0) = Yi(0);
- Wn += i;
- for (yn = y+dY; yn < ye; yn += dY) {
- Xr(0) += Wnr(0)*Ynr(0) - Wni(0)*Yni(0);
- Xi(0) += Wnr(0)*Yni(0) + Wni(0)*Ynr(0);
- Wn += i;
- if (((size_t)Wn)*dWp >= ((size_t)We)*dWp)
- Wn -= NWpd;
- }
- }
- }
- else {
- FFT(N/2, w, x, dX, y, dY*2, Wp,dWp*2);
- FFT(N/2, w+N*dX/2,x+N*dX/2,dX, y+dY,dY*2, Wp,dWp*2);
- #if even_faster
- xe = x + N*dX/2;
- Xr(0) = Wr(0) + Wr(N/2);
- Xi(0) = Wi(0) + Wi(N/2);
- Xr(N/2) = Wr(0) - Wr(N/2);
- Xi(N/2) = Wi(0) - Wi(N/2);
- x += dX;
- w += dX;
- Wp += dWp;
- for (; x < xe; x += dX, w += dX, Wp += dWp) {
- re = Wpr(0)*Wr(N/2) - Wpi(0)*Wi(N/2);
- im = Wpr(0)*Wi(N/2) + Wpi(0)*Wr(N/2);
- Xr(0) = Wr(0) + re;
- Xi(0) = Wi(0) + im;
- Xr(N/2) = Wr(0) - re;
- Xi(N/2) = Wi(0) - im;
- }
- #else
- for (Wn = Wp, xe = x + N*dX/2; x < xe; x += dX, w += dX, Wn += dWp) {
- /* FastDFT calls FFT with Wp pointing to 'just past' the end of the
- true Wp array, and accessing Wp[N] for positive N is not valid.
- At this point, we've not optimised FFT algorithm to 'know' that
- Wp[0] is actually 1, and it would mess up the operation counts
- to include this optimisation at this point in time.
- So... I do it like this until later in the exercise
- when -D even_faster is defined. */
- re = (Wn==Wp?1:Wnr(0))*Wr(N/2) - (Wn==Wp?0:Wni(0))*Wi(N/2);
- im = (Wn==Wp?1:Wnr(0))*Wi(N/2) + (Wn==Wp?0:Wni(0))*Wni(0)*Wr(N/2);
- Xr(0) = Wr(0) + re;
- Xi(0) = Wi(0) + im;
- Xr(N/2) = Wr(0) - re;
- Xi(N/2) = Wi(0) - im;
- }
- #endif
- }
- }
- }
- void FastDFS(double *x, double *y, double *w, double *Wp, int N, int skip) {
- FFT(N, x,w,skip, y,skip, Wp,2);
- }
- void FastDFT(double *x, double *y, double *w, double *Wp, int N, int skip) {
- int i;
- double iN = 1./N;
- double *ye;
- FFT(N, y,w,skip, x,skip, Wp+N*2,-2);
- ye = y + N*skip;
- for (ye = y + N*skip; y < ye; y += skip) {
- y[0] *= iN;
- y[1] *= iN;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment