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