Logo Coherent WaveBurst  
Reference Guide
Logo
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
wavefft.cc
Go to the documentation of this file.
1 /* --------------------------------------------------------------------
2  *
3  * Multivariate complex fourier transform, computed in place
4  * using mixed-radix fast fourier transform algorithm.
5  *
6  * Translated from Fortran to C++ by
7  * A. Sazonov (sazonov@thsun1.jinr.ru)
8  * March 2000.
9  *
10  * Original Fortran code by
11  * R. C. Singleton, Stanford Research Institute, Sept. 1968
12  * see source at http://www.netlib.org/go/wavefft.f
13  * or http://www.numis.nwu.edu/ftp/pub/transforms/wavefft.f
14  *
15  * -------------------------------------------------------------------
16  */
17 
18 #include <math.h>
19 #include <iostream>
20 #include <stdio.h>
21 #include "wavefft.hh"
22 
23 void wavefft(double a[], double b[], int ntot, int n, int nspan, int isn)
24 {
25 /* ----------------------------------------------------------------
26  * Indexing of external arrays a[] and b[] is changed according to C++
27  * requirements, internal arrays ( nfac[], np[], at[], ck[], bt[], sk[] )
28  * are still using index starting from 1.
29  *
30  * A.Sazonov (sazonov@thsun1.jinr.ru)
31  * -----------------------------------------------------------------
32  */
33 
34 /*
35 c multivariate complex fourier transform, computed in place
36 c using mixed-radix fast fourier transform algorithm.
37 c by r. c. singleton, stanford research institute, sept. 1968
38 c arrays a and b originally hold the real and imaginary
39 c components of the data, and return the real and
40 c imaginary components of the resulting fourier coefficients.
41 c multivariate data is indexed according to the fortran
42 c array element successor function, without limit
43 c on the number of implied multiple subscripts.
44 c the subroutine is called once for each variate.
45 c the calls for a multivariate transform may be in any order.
46 c ntot is the total number of complex data values.
47 c n is the dimension of the current variable.
48 c nspan/n is the spacing of consecutive data values
49 c while indexing the current variable.
50 c the sign of isn determines the sign of the complex
51 c exponential, and the magnitude of isn is normally one.
52 c a tri-variate transform with a(n1,n2,n3), b(n1,n2,n3)
53 c is computed by
54 c call wavefft(a,b,n1*n2*n3,n1,n1,1)
55 c call wavefft(a,b,n1*n2*n3,n2,n1*n2,1)
56 c call wavefft(a,b,n1*n2*n3,n3,n1*n2*n3,1)
57 c for a single-variate transform,
58 c ntot = n = nspan = (number of complex data values), e.g.
59 c call wavefft(a,b,n,n,n,1)
60 c the data can alternatively be stored in a single complex array c
61 c in standard fortran fashion, i.e. alternating real and imaginary
62 c parts. then with most fortran compilers, the complex array c can
63 c be equivalenced to a real array a, the magnitude of isn changed
64 c to two to give correct indexing increment, and a(1) and a(2) used
65 c to pass the initial addresses for the sequences of real and
66 c imaginary values, e.g.
67 c complex c(ntot)
68 c real a(2*ntot)
69 c equivalence (c(1),a(1))
70 c call wavefft(a(1),a(2),ntot,n,nspan,2)
71 c arrays at(maxf), ck(maxf), bt(maxf), sk(maxf), and np(maxp)
72 c are used for temporary storage. if the available storage
73 c is insufficient, the program is terminated by a stop.
74 c maxf must be .ge. the maximum prime factor of n.
75 c maxp must be .gt. the number of prime factors of n.
76 c in addition, if the square-free portion k of n has two or
77 c more prime factors, then maxp must be .ge. k-1.
78 c ***************************************
79 */
80 
81 //---------------------------------------------------------------
82 // Notes below are added by A.Sazonov, May 2000:
83 //---------------------------------------------------------------
84 // arrays at[maxf], ck[maxf], bt[maxf], sk[maxf], and np[maxp]
85 // are used for temporary storage.
86 // maxf must be >= the maximum prime factor of n.
87 // maxp must be > the number of prime factors of n.
88 // in addition, if the square-free portion k of n has two or
89 // more prime factors, then must be maxp >= k-1.
90 //---------------------------------------------------------------
91 // The advantage of C++ dynamic memory allocation is used
92 // to create arrays with sufficient lengths.
93 // The lengths of arrays at[maxf], ck[maxf], bt[maxf], sk[maxf]
94 // may be calculated at the begining of program.
95 // The array np[maxp] initially created with length maxp+1
96 // will be resized as soon as it will be found insufficient
97 // for further calculations.
98 //---------------------------------------------------------------
99  int maxp=209; // initial value
100  int maxf=1; // maxf will be adjusted later
101  int nf=32;
102 // array storage in 'nfac' for a maximum of 32 prime factors of n.
103 // it's surely enough if n <= 2^32, and minimal factor is 2
104  int nfac[nf];
105 
106  if (n < 2) return;
107  int inc=isn;
108  double c72=0.30901699437494742; // cos(72 deg)
109  double s72=0.95105651629515357; // sin(72 deg)
110  double s120=0.86602540378443865; // sin(120 deg)
111  double pi=3.141592653589793;
112  double rad=2.*pi;
113  double c1, c2=0., c3=0., s1, s2=0., s3=0.;
114 
115  if (isn < 0) { s72=-s72; s120=-s120; rad=-rad; inc=-inc; }
116 
117  int nt=inc*ntot;
118  int ks=inc*nspan;
119  int kspnn, kspan=ks;
120  int nn=nt-inc;
121  int jc=ks/n;
122  double radf=rad*double(jc)*0.5;
123  int i=0, jf=0;
124 
125  for ( int i=1; i<nf; i++) nfac[i]=0;
126 
127 // determine the factors of n
128  int kt, m=0, k=n;
129 
130  while ( ((k/16)*16) == k ) { m++; nfac[m]=4; k/=16; }
131 
132  int j=3, jj=9;
133 
134  do {
135  while ( (k%jj) == 0) { m++; nfac[m]=j; k/=jj ;}
136  j+=2;
137  jj=j*j;
138  } while ( jj <= k ) ;
139 
140  if ( k <= 4 ) { kt=m; nfac[m+1]=k; if (k != 1) m++; }
141  else
142  {
143  if ( ((k/4)*4) == k ) { m++; nfac[m]=2; k/=4; }
144 
145  kt=m; j=2;
146 
147  do {
148  if( (k%j) == 0) { m++; nfac[m]=j; k/=j; }
149  j=((j+1)/2)*2+1;
150  } while ( j <= k ) ;
151  }
152 
153  if ( kt != 0 )
154  { j=kt; do { m++; nfac[m]=nfac[j]; j--; } while ( j != 0 ) ; }
155 
156 // find maximum prime factor
157  for ( int i=1; i<nf; i++)
158  if ( nfac[i] > maxf) { maxf=nfac[i]; }
159 
160 // compute Fourier transform
161  int kk, k1, k2, k3=0, k4;
162  double sd, cd;
163  double aa, bb, ak, bk, aj, bj;
164  double ajm, ajp, akm, akp, bjm, bjp, bkm, bkp;
165 
166 // allocate temporary arrays, here np[] is not quaranteed to have enough size
167 // but it will be adjusted if data will not fit default size
168  double *at, *ck, *bt, *sk;
169  at=new double[maxf+1];
170  bt=new double[maxf+1];
171  ck=new double[maxf+1];
172  sk=new double[maxf+1];
173 
174  int *np;
175  np=new int[maxp+1];
176 
177 L100:
178  sd=radf/double(kspan);
179  cd=sin(sd); cd*=cd; cd*=2.;
180  sd=sin(sd+sd);
181  kk=0;
182  i++;
183 
184 // transform for factor of 2 (including rotation factor)
185  if ( nfac[i] != 2 ) goto L400;
186  kspan=kspan/2;
187  k1=kspan+2-1;
188  do
189  { do
190  { k2=kk+kspan;
191  ak=a[k2]; bk=b[k2];
192  a[k2]=a[kk]-ak; b[k2]=b[kk]-bk;
193  a[kk]=a[kk]+ak; b[kk]=b[kk]+bk;
194  kk=k2+kspan;
195 
196  } while (kk <= nn-1);
197 
198  kk=kk-nn;
199 
200  } while ( kk <= jc-1);
201  if ( kk > (kspan -1) ) goto L800 ;
202 
203  do
204  { c1=1.-cd;
205  s1=sd;
206  do
207  { do
208  { do
209  { k2=kk+kspan;
210  ak=a[kk]-a[k2]; bk=b[kk]-b[k2];
211  a[kk]=a[kk]+a[k2]; b[kk]=b[kk]+b[k2];
212  a[k2]=c1*ak-s1*bk; b[k2]=s1*ak+c1*bk;
213  kk=k2+kspan;
214 
215  } while (kk < nt-1);
216 
217  k2=kk-nt;
218  c1=-c1;
219  kk=k1-k2-1;
220 
221  } while (kk > k2);
222 
223  ak=c1-(cd*c1+sd*s1);
224  s1=(sd*c1-cd*s1)+s1;
225  c1=2.-(ak*ak+s1*s1);
226  s1=c1*s1;
227  c1=c1*ak;
228  kk+=jc;
229 
230  } while ( kk < k2 );
231 
232  k1+=inc; k1+=inc;
233  kk=(k1-kspan+1)/2+jc-1;
234 
235  } while (kk <= jc+jc-1);
236 
237  goto L100;
238 
239 // transform for factor of 3 (optional code)
240 L320:
241  do
242  { do
243  { k1=kk+kspan; k2=k1+kspan;
244  ak=a[kk]; bk=b[kk];
245  aj=a[k1]+a[k2]; bj=b[k1]+b[k2];
246  a[kk]=ak+aj; b[kk]=bk+bj;
247  ak=-0.5*aj+ak; bk=-0.5*bj+bk;
248  aj=(a[k1]-a[k2])*s120; bj=(b[k1]-b[k2])*s120;
249  a[k1]=ak-bj; b[k1]=bk+aj;
250  a[k2]=ak+bj; b[k2]=bk-aj;
251  kk=k2+kspan;
252 
253  } while ( kk < nn -1 );
254 
255  kk=kk-nn;
256 
257  } while ( kk <= kspan -1 );
258 
259  goto L700;
260 
261 // transform for factor of 4
262 L400:
263  if ( nfac[i] != 4 ) goto L600;
264  kspnn=kspan;
265  kspan=kspan/4;
266 L410:
267  c1=1.;
268  s1=0.;
269 L420:
270  k1=kk+kspan; k2=k1+kspan; k3=k2+kspan;
271  akp=a[kk]+a[k2]; akm=a[kk]-a[k2];
272  ajp=a[k1]+a[k3]; ajm=a[k1]-a[k3];
273  a[kk]=akp+ajp;
274  ajp=akp-ajp;
275  bkp=b[kk]+b[k2]; bkm=b[kk]-b[k2];
276  bjp=b[k1]+b[k3]; bjm=b[k1]-b[k3];
277  b[kk]=bkp+bjp;
278  bjp=bkp-bjp;
279  if ( isn < 0 ) goto L450;
280  akp=akm-bjm; akm=akm+bjm;
281  bkp=bkm+ajm; bkm=bkm-ajm;
282  if ( s1 == 0 ) goto L460;
283 L430:
284  a[k1]=akp*c1-bkp*s1; b[k1]=akp*s1+bkp*c1;
285  a[k2]=ajp*c2-bjp*s2; b[k2]=ajp*s2+bjp*c2;
286  a[k3]=akm*c3-bkm*s3; b[k3]=akm*s3+bkm*c3;
287  kk=k3+kspan;
288 
289  if ( kk <= nt-1 ) goto L420;
290 L440:
291  c2=c1-(cd*c1+sd*s1);
292  s1=(sd*c1-cd*s1)+s1;
293  c1=2.0-(c2*c2+s1*s1);
294  s1*=c1;
295  c1*=c2;
296  c2=c1*c1-s1*s1;
297  s2=2.0*c1*s1;
298  c3=c2*c1-s2*s1;
299  s3=c2*s1+s2*c1;
300  kk-=nt; kk+=jc;
301 
302  if ( kk <= kspan-1) goto L420;
303  kk-=kspan; kk+=inc;
304 
305  if ( kk <= jc-1 ) goto L410;
306  if ( kspan == jc ) goto L800;
307 
308  goto L100;
309 
310 L450:
311  akp=akm+bjm; akm=akm-bjm;
312  bkp=bkm-ajm; bkm=bkm+ajm;
313 
314  if ( s1 != 0) goto L430;
315 
316 L460:
317  a[k1]=akp; b[k1]=bkp;
318  a[k2]=ajp; b[k2]=bjp;
319  a[k3]=akm; b[k3]=bkm;
320  kk=k3+kspan;
321 
322  if ( kk <= nt-1 ) goto L420;
323 
324  goto L440;
325 
326 // transform for factor of 5 (optional code)
327 L510:
328  c2=c72*c72-s72*s72;
329  s2=2.0*c72*s72;
330  do
331  { do
332  { k1=kk+kspan; k2=k1+kspan; k3=k2+kspan; k4=k3+kspan;
333  akp=a[k1]+a[k4]; akm=a[k1]-a[k4];
334  bkp=b[k1]+b[k4]; bkm=b[k1]-b[k4];
335  ajp=a[k2]+a[k3]; ajm=a[k2]-a[k3];
336  bjp=b[k2]+b[k3]; bjm=b[k2]-b[k3];
337  aa=a[kk]; bb=b[kk];
338  a[kk]=aa+akp+ajp; b[kk]=bb+bkp+bjp;
339  ak=akp*c72+ajp*c2+aa; bk=bkp*c72+bjp*c2+bb;
340  aj=akm*s72+ajm*s2; bj=bkm*s72+bjm*s2;
341  a[k1]=ak-bj; a[k4]=ak+bj;
342  b[k1]=bk+aj; b[k4]=bk-aj;
343  ak=akp*c2+ajp*c72+aa; bk=bkp*c2+bjp*c72+bb;
344  aj=akm*s2-ajm*s72; bj=bkm*s2-bjm*s72;
345  a[k2]=ak-bj; a[k3]=ak+bj;
346  b[k2]=bk+aj; b[k3]=bk-aj;
347  kk=k4+kspan;
348  } while ( kk < nn-1 );
349  kk=kk-nn;
350  } while ( kk <= kspan-1 ) ;
351  goto L700;
352 
353 // transform for odd factors
354 
355 L600:
356  k=nfac[i];
357  kspnn=kspan;
358  kspan=kspan/k;
359  if ( k == 3 ) goto L320;
360  if ( k == 5 ) goto L510;
361  if ( k == jf ) goto L640;
362  jf=k;
363  s1=rad/double(k);
364  c1=cos(s1); s1=sin(s1);
365  if ( jf > maxf ) goto L998 ;
366  ck[jf]=1.0; sk[jf]=0.0;
367  j=1;
368  do
369  { ck[j]=ck[k]*c1+sk[k]*s1;
370  sk[j]=ck[k]*s1-sk[k]*c1;
371  k=k-1;
372  ck[k]=ck[j];
373  sk[k]=-sk[j];
374  j=j+1;
375  } while ( j < k );
376 L640:
377  do
378  { do
379  { k1=kk;
380  k2=kk+kspnn;
381  aa=a[kk]; bb=b[kk];
382  ak=aa; bk=bb;
383  j=1;
384  k1=k1+kspan;
385 
386  do
387  { k2=k2-kspan;
388  j++;
389  at[j]=a[k1]+a[k2];
390  ak=at[j]+ak;
391  bt[j]=b[k1]+b[k2];
392  bk=bt[j]+bk;
393  j++;
394  at[j]=a[k1]-a[k2];
395  bt[j]=b[k1]-b[k2];
396  k1=k1+kspan;
397  } while ( k1 < k2 );
398 
399  a[kk]=ak;
400  b[kk]=bk;
401  k1=kk;
402  k2=kk+kspnn;
403  j=1;
404 
405  do
406  { k1+=kspan; k2-=kspan;
407  jj=j;
408  ak=aa; bk=bb;
409  aj=0.0; bj=0.0;
410  k=1;
411 
412  do
413  { k++;
414  ak=at[k]*ck[jj]+ak;
415  bk=bt[k]*ck[jj]+bk;
416  k++;
417  aj=at[k]*sk[jj]+aj;
418  bj=bt[k]*sk[jj]+bj;
419  jj+=j;
420  if ( jj > jf ) jj-=jf;
421 
422  } while ( k < jf );
423 
424  k=jf-j;
425  a[k1]=ak-bj; b[k1]=bk+aj;
426  a[k2]=ak+bj; b[k2]=bk-aj;
427  j++;
428 
429  } while( j < k );
430 
431  kk=kk+kspnn;
432  } while ( kk <= nn-1 );
433  kk-=nn;
434  } while ( kk <= kspan-1 );
435 // multiply by rotation factor (except for factors of 2 and 4);
436 L700:
437  if ( i == m ) goto L800;
438  kk=jc;
439  do
440  { c2=1.0-cd;
441  s1=sd;
442 
443  do
444  { c1=c2;
445  s2=s1;
446  kk+=kspan;
447 
448  do
449  { do
450  { ak=a[kk];
451  a[kk]=c2*ak-s2*b[kk];
452  b[kk]=s2*ak+c2*b[kk];
453  kk+=kspnn;
454  } while ( kk <= nt-1 );
455 
456  ak=s1*s2;
457  s2=s1*c2+c1*s2;
458  c2=c1*c2-ak;
459  kk=kk-nt+kspan;
460  } while ( kk <= kspnn-1 );
461 
462  c2=c1-(cd*c1+sd*s1);
463  s1=s1+(sd*c1-cd*s1);
464  c1=2.0-(c2*c2+s1*s1);
465  s1=c1*s1;
466  c2=c1*c2;
467  kk=kk-kspnn+jc;
468 
469  } while ( kk <= kspan -1 );
470 
471  kk=kk-kspan+jc+inc;
472 
473  } while ( kk <= jc+jc-1 );
474  goto L100;
475 
476 // permute the results to normal order---done in two stages
477 // permutation for square factors of n
478 
479 L800:
480  np[1]=ks;
481  if ( kt == 0) goto L890;
482  k=kt+kt+1;
483  if ( m < k) k=k-1;
484  j=1;
485  np[k+1]=jc;
486  do
487  { np[j+1]=np[j]/nfac[j];
488  np[k]=np[k+1]*nfac[j];
489  j++;
490  k--;
491  } while ( j < k );
492 
493  k3=np[k+1]-1;
494  kspan=np[2];
495  kk=jc;
496  k2=kspan;
497  j=1;
498  if ( n != ntot ) goto L850;
499 // permutation for single-variate transform (optional code)
500 L820:
501  do
502  { ak=a[kk];
503  a[kk]=a[k2];
504  a[k2]=ak;
505  bk=b[kk];
506  b[kk]=b[k2];
507  b[k2]=bk;
508  kk+=inc;
509  k2+=kspan;
510  } while ( k2 < ks-1 );
511 L830:
512  do
513  { k2-=np[j];
514  j++;
515  k2+=np[j+1];
516  } while ( k2 > np[j]-1 );
517  j=1;
518 L840: if ( kk < k2 ) goto L820;
519  kk+=inc;
520  k2+=kspan;
521  if ( k2 < ks-1 ) goto L840;
522  if ( kk < ks-1 ) goto L830;
523  jc=k3+1;
524  goto L890;
525 // permutation for multivariate transform;
526 L850:
527  do
528  { do
529  { k=kk+jc+1;
530  do
531  { ak=a[kk]; a[kk]=a[k2]; a[k2]=ak;
532  bk=b[kk]; b[kk]=b[k2]; b[k2]=bk;
533  kk+=inc; k2+=inc;
534  } while ( kk < k-1 );
535 
536  kk=kk+ks-jc;
537  k2=k2+ks-jc;
538  } while ( kk < nt-1 );
539 
540  k2=k2-nt+kspan;
541  kk=kk-nt+jc;
542  } while ( k2 < ks-1 );
543  L870:
544  do { k2-=np[j]; j++; k2+=np[j+1]; } while ( k2 > np[j]-1 );
545 
546  j=1;
547  L880:
548  if ( kk < k2 ) goto L850;
549  kk+=jc;
550  k2+=kspan;
551  if ( k2 < ks-1 ) goto L880;
552  if ( kk < ks-1 ) goto L870;
553  jc=k3+1;
554  L890:
555  if ( 2*kt+1 >= m ) {delete [] np; delete [] at; delete [] bt;
556  delete [] ck ; delete [] sk; return;}
557  kspnn=np[kt+1];
558 // permutation for square-free factors of n;
559  j=m-kt;
560  nfac[j+1]=1;
561 //L900:
562  do { nfac[j]=nfac[j]*nfac[j+1]; j--; } while ( j != kt );
563 
564  kt++;
565  nn=nfac[kt]-1;
566  if ( nn > maxp ) // was goto L998;
567  { maxp=nn;
568  delete [] np; np=new int[maxp+1]; }
569 
570  jj=0;
571  j=0;
572  goto L906;
573 L902:
574  jj=jj-k2-1;
575  k2=kk;
576  k++;
577  kk=nfac[k]-1;
578 L904:
579  jj=kk+jj+1;
580  if ( jj-1 >= k2 ) goto L902;
581  np[j]=jj;
582 L906:
583  k2=nfac[kt]-1;
584  k=kt+1;
585  kk=nfac[k]-1;
586  j++;
587  if ( j <= nn ) goto L904;
588 // determine the permutation cycles of length greater than 1;
589  j=0;
590  goto L914;
591 L910:
592  do { k=kk+1; kk=np[k]-1; np[k]=-kk-1; } while ( kk != j-1 );
593 
594  k3=kk;
595 L914:
596  do { j++; kk=np[j]-1; } while ( kk < -1 );
597 
598  if ( kk != j-1 ) goto L910;
599  np[j]=-j;
600  if ( j != nn ) goto L914;
601  maxf=inc*maxf;
602 // reorder a and b, following the permutation cycles;
603  goto L950;
604 L924:
605  do
606  { do { j--; } while ( np[j] < 0 );
607 
608  jj=jc;
609  do
610  { kspan=jj;
611  if ( jj > maxf ) kspan=maxf;
612  jj-=kspan;
613  k=np[j];
614  kk=jc*k+i+jj-1;
615  k1=kk+kspan;
616  k2=0;
617  do { at[k2]=a[k1]; bt[k2]=b[k1]; k2++; k1-=inc; } while ( k1 != kk );
618 
619  do
620  { k1=kk+kspan;
621  k2=k1-jc*(k+np[k]);
622  k=-np[k];
623  do { a[k1]=a[k2]; b[k1]=b[k2]; k1-=inc; k2-=inc; } while( k1 != kk );
624  kk=k2;
625  } while ( k != j );
626 
627  k1=kk+kspan;
628  k2=0;
629  do { a[k1]=at[k2]; b[k1]=bt[k2]; k2++; k1-=inc; } while ( k1 != kk );
630 
631  } while ( jj != 0 );
632  } while ( j != 1 );
633 L950:
634  j=k3+2;
635  nt=nt-kspnn;
636  i=nt-inc+1;
637  if ( nt >= 0 ) goto L924;
638  delete [] np; delete [] at; delete [] bt; delete [] ck ; delete [] sk;
639  return;
640 // error finish, insufficient array storage;
641 L998:
642  delete [] np; delete [] at; delete [] bt; delete [] ck ; delete [] sk;
643  isn=0;
644  printf("Error: array bounds exceeded within subroutine wavefft.\n");
645  return;
646 }
647 
printf("total live time: non-zero lags = %10.1f \n", liveTot)
#define np
wavearray< double > a(hp.size())
int n
Definition: cwb_net.C:10
int m
Definition: cwb_net.C:10
int j
Definition: cwb_net.C:10
canvas cd(1)
i drho i
double pi
Definition: TestChirp.C:18
void wavefft(double a[], double b[], int ntot, int n, int nspan, int isn)
Definition: wavefft.cc:23
TCanvas * c1
int k
TCanvas * c2
Definition: slag.C:207
char c3[8]