doku newon / DokuFFTPACK

Dependents:   Peach_AudioChannelDividerAndCompensator

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers fftpack_inc.inc Source File

fftpack_inc.inc

00001 /*
00002  *  This file is part of libfftpack.
00003  *
00004  *  libfftpack is free software; you can redistribute it and/or modify
00005  *  it under the terms of the GNU General Public License as published by
00006  *  the Free Software Foundation; either version 2 of the License, or
00007  *  (at your option) any later version.
00008  *
00009  *  libfftpack is distributed in the hope that it will be useful,
00010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *  GNU General Public License for more details.
00013  *
00014  *  You should have received a copy of the GNU General Public License
00015  *  along with libfftpack; if not, write to the Free Software
00016  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00017  */
00018 
00019 /*
00020  *  libfftpack is being developed at the Max-Planck-Institut fuer Astrophysik
00021  *  and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
00022  *  (DLR).
00023  */
00024 
00025 /*
00026   fftpack.c : A set of FFT routines in C.
00027   Algorithmically based on Fortran-77 FFTPACK by Paul N. Swarztrauber
00028   (Version 4, 1985).
00029 
00030   C port by Martin Reinecke (2010)
00031  */
00032 
00033 #ifdef BACKWARD
00034 #define PSIGN +
00035 #define PMSIGNC(a,b,c,d) { a.r=c.r+d.r; a.i=c.i+d.i; b.r=c.r-d.r; b.i=c.i-d.i; }
00036 /* a = b*c */
00037 #define MULPMSIGNC(a,b,c) { a.r=b.r*c.r-b.i*c.i; a.i=b.r*c.i+b.i*c.r; }
00038 #else
00039 #define PSIGN -
00040 #define PMSIGNC(a,b,c,d) { a.r=c.r-d.r; a.i=c.i-d.i; b.r=c.r+d.r; b.i=c.i+d.i; }
00041 /* a = conj(b)*c */
00042 #define MULPMSIGNC(a,b,c) { a.r=b.r*c.r+b.i*c.i; a.i=b.r*c.i-b.i*c.r; }
00043 #endif
00044 
00045 static void X(2) (size_t ido,size_t l1,const cmplx *cc,cmplx *ch,const cmplx *wa)
00046   {
00047   const size_t cdim=2;
00048   size_t k,i;
00049   cmplx t;
00050   if (ido==1)
00051     for (k=0;k<l1;++k)
00052       PMC (CH(0,k,0),CH(0,k,1),CC(0,0,k),CC(0,1,k))
00053   else
00054     for (k=0;k<l1;++k)
00055       for (i=0;i<ido;++i)
00056         {
00057         PMC (CH(i,k,0),t,CC(i,0,k),CC(i,1,k))
00058         MULPMSIGNC (CH(i,k,1),WA(0,i),t)
00059         }
00060   }
00061 
00062 static void X(3)(size_t ido, size_t l1, const cmplx *cc, cmplx *ch,
00063   const cmplx *wa)
00064   {
00065   const size_t cdim=3;
00066   static const FLOAT taur=-0.5, taui= PSIGN 0.86602540378443864676;
00067   size_t i, k;
00068   cmplx c2, c3, d2, d3, t2;
00069 
00070   if (ido==1)
00071     for (k=0; k<l1; ++k)
00072       {
00073       PMC (t2,c3,CC(0,1,k),CC(0,2,k))
00074       ADDC (CH(0,k,0),t2,CC(0,0,k))
00075       SCALEC(t2,taur)
00076       ADDC(c2,CC(0,0,k),t2)
00077       SCALEC(c3,taui)
00078       CONJFLIPC(c3)
00079       PMC(CH(0,k,1),CH(0,k,2),c2,c3)
00080       }
00081   else
00082     for (k=0; k<l1; ++k)
00083       for (i=0; i<ido; ++i)
00084         {
00085         PMC (t2,c3,CC(i,1,k),CC(i,2,k))
00086         ADDC (CH(i,k,0),t2,CC(i,0,k))
00087         SCALEC(t2,taur)
00088         ADDC(c2,CC(i,0,k),t2)
00089         SCALEC(c3,taui)
00090         CONJFLIPC(c3)
00091         PMC(d2,d3,c2,c3)
00092         MULPMSIGNC(CH(i,k,1),WA(0,i),d2)
00093         MULPMSIGNC(CH(i,k,2),WA(1,i),d3)
00094         }
00095   }
00096 
00097 static void X(4)(size_t ido, size_t l1, const cmplx *cc, cmplx *ch,
00098   const cmplx *wa)
00099   {
00100   const size_t cdim=4;
00101   size_t i, k;
00102   cmplx c2, c3, c4, t1, t2, t3, t4;
00103 
00104   if (ido==1)
00105     for (k=0; k<l1; ++k)
00106       {
00107       PMC(t2,t1,CC(0,0,k),CC(0,2,k))
00108       PMC(t3,t4,CC(0,1,k),CC(0,3,k))
00109       CONJFLIPC(t4)
00110       PMC(CH(0,k,0),CH(0,k,2),t2,t3)
00111       PMSIGNC (CH(0,k,1),CH(0,k,3),t1,t4)
00112       }
00113   else
00114     for (k=0; k<l1; ++k)
00115       for (i=0; i<ido; ++i)
00116         {
00117         PMC(t2,t1,CC(i,0,k),CC(i,2,k))
00118         PMC(t3,t4,CC(i,1,k),CC(i,3,k))
00119         CONJFLIPC(t4)
00120         PMC(CH(i,k,0),c3,t2,t3)
00121         PMSIGNC (c2,c4,t1,t4)
00122         MULPMSIGNC (CH(i,k,1),WA(0,i),c2)
00123         MULPMSIGNC (CH(i,k,2),WA(1,i),c3)
00124         MULPMSIGNC (CH(i,k,3),WA(2,i),c4)
00125         }
00126   }
00127 
00128 static void X(5)(size_t ido, size_t l1, const cmplx *cc, cmplx *ch,
00129   const cmplx *wa)
00130   {
00131   const size_t cdim=5;
00132   static const FLOAT tr11= 0.3090169943749474241,
00133                       ti11= PSIGN 0.95105651629515357212,
00134                       tr12=-0.8090169943749474241,
00135                       ti12= PSIGN 0.58778525229247312917;
00136   size_t i, k;
00137   cmplx c2, c3, c4, c5, d2, d3, d4, d5, t2, t3, t4, t5;
00138 
00139   if (ido==1)
00140     for (k=0; k<l1; ++k)
00141       {
00142       PMC (t2,t5,CC(0,1,k),CC(0,4,k))
00143       PMC (t3,t4,CC(0,2,k),CC(0,3,k))
00144       CH(0,k,0).r=CC(0,0,k).r+t2.r+t3.r;
00145       CH(0,k,0).i=CC(0,0,k).i+t2.i+t3.i;
00146       c2.r=CC(0,0,k).r+tr11*t2.r+tr12*t3.r;
00147       c2.i=CC(0,0,k).i+tr11*t2.i+tr12*t3.i;
00148       c3.r=CC(0,0,k).r+tr12*t2.r+tr11*t3.r;
00149       c3.i=CC(0,0,k).i+tr12*t2.i+tr11*t3.i;
00150       c5.r=ti11*t5.r+ti12*t4.r;
00151       c5.i=ti11*t5.i+ti12*t4.i;
00152       c4.r=ti12*t5.r-ti11*t4.r;
00153       c4.i=ti12*t5.i-ti11*t4.i;
00154       CONJFLIPC(c5)
00155       PMC(CH(0,k,1),CH(0,k,4),c2,c5)
00156       CONJFLIPC(c4)
00157       PMC(CH(0,k,2),CH(0,k,3),c3,c4)
00158       }
00159   else
00160     for (k=0; k<l1; ++k)
00161       for (i=0; i<ido; ++i)
00162         {
00163         PMC (t2,t5,CC(i,1,k),CC(i,4,k))
00164         PMC (t3,t4,CC(i,2,k),CC(i,3,k))
00165         CH(i,k,0).r=CC(i,0,k).r+t2.r+t3.r;
00166         CH(i,k,0).i=CC(i,0,k).i+t2.i+t3.i;
00167         c2.r=CC(i,0,k).r+tr11*t2.r+tr12*t3.r;
00168         c2.i=CC(i,0,k).i+tr11*t2.i+tr12*t3.i;
00169         c3.r=CC(i,0,k).r+tr12*t2.r+tr11*t3.r;
00170         c3.i=CC(i,0,k).i+tr12*t2.i+tr11*t3.i;
00171         c5.r=ti11*t5.r+ti12*t4.r;
00172         c5.i=ti11*t5.i+ti12*t4.i;
00173         c4.r=ti12*t5.r-ti11*t4.r;
00174         c4.i=ti12*t5.i-ti11*t4.i;
00175         CONJFLIPC(c5)
00176         PMC(d2,d5,c2,c5)
00177         CONJFLIPC(c4)
00178         PMC(d3,d4,c3,c4)
00179         MULPMSIGNC (CH(i,k,1),WA(0,i),d2)
00180         MULPMSIGNC (CH(i,k,2),WA(1,i),d3)
00181         MULPMSIGNC (CH(i,k,3),WA(2,i),d4)
00182         MULPMSIGNC (CH(i,k,4),WA(3,i),d5)
00183         }
00184   }
00185 
00186 static void X(6)(size_t ido, size_t l1, const cmplx *cc, cmplx *ch,
00187   const cmplx *wa)
00188   {
00189   const size_t cdim=6;
00190   static const FLOAT taui= PSIGN 0.86602540378443864676;
00191   cmplx ta1,ta2,ta3,a0,a1,a2,tb1,tb2,tb3,b0,b1,b2,d1,d2,d3,d4,d5;
00192   size_t i, k;
00193 
00194   if (ido==1)
00195     for (k=0; k<l1; ++k)
00196       {
00197       PMC(ta1,ta3,CC(0,2,k),CC(0,4,k))
00198       ta2.r = CC(0,0,k).r - .5*ta1.r;
00199       ta2.i = CC(0,0,k).i - .5*ta1.i;
00200       SCALEC(ta3,taui)
00201       ADDC(a0,CC(0,0,k),ta1)
00202       CONJFLIPC(ta3)
00203       PMC(a1,a2,ta2,ta3)
00204       PMC(tb1,tb3,CC(0,5,k),CC(0,1,k))
00205       tb2.r = CC(0,3,k).r - .5*tb1.r;
00206       tb2.i = CC(0,3,k).i - .5*tb1.i;
00207       SCALEC(tb3,taui)
00208       ADDC(b0,CC(0,3,k),tb1)
00209       CONJFLIPC(tb3)
00210       PMC(b1,b2,tb2,tb3)
00211       PMC(CH(0,k,0),CH(0,k,3),a0,b0)
00212       PMC(CH(0,k,4),CH(0,k,1),a1,b1)
00213       PMC(CH(0,k,2),CH(0,k,5),a2,b2)
00214       }
00215   else
00216     for (k=0; k<l1; ++k)
00217       for (i=0; i<ido; ++i)
00218         {
00219         PMC(ta1,ta3,CC(i,2,k),CC(i,4,k))
00220         ta2.r = CC(i,0,k).r - .5*ta1.r;
00221         ta2.i = CC(i,0,k).i - .5*ta1.i;
00222         SCALEC(ta3,taui)
00223         ADDC(a0,CC(i,0,k),ta1)
00224         CONJFLIPC(ta3)
00225         PMC(a1,a2,ta2,ta3)
00226         PMC(tb1,tb3,CC(i,5,k),CC(i,1,k))
00227         tb2.r = CC(i,3,k).r - .5*tb1.r;
00228         tb2.i = CC(i,3,k).i - .5*tb1.i;
00229         SCALEC(tb3,taui)
00230         ADDC(b0,CC(i,3,k),tb1)
00231         CONJFLIPC(tb3)
00232         PMC(b1,b2,tb2,tb3)
00233         PMC(CH(i,k,0),d3,a0,b0)
00234         PMC(d4,d1,a1,b1)
00235         PMC(d2,d5,a2,b2)
00236         MULPMSIGNC (CH(i,k,1),WA(0,i),d1)
00237         MULPMSIGNC (CH(i,k,2),WA(1,i),d2)
00238         MULPMSIGNC (CH(i,k,3),WA(2,i),d3)
00239         MULPMSIGNC (CH(i,k,4),WA(3,i),d4)
00240         MULPMSIGNC (CH(i,k,5),WA(4,i),d5)
00241         }
00242   }
00243 
00244 static void X(g)(size_t ido, size_t ip, size_t l1, const cmplx *cc, cmplx *ch,
00245   const cmplx *wa)
00246   {
00247   const size_t cdim=ip;
00248   cmplx *tarr=RALLOC(cmplx,2*ip);
00249   cmplx *ccl=tarr, *wal=tarr+ip;
00250   size_t i,j,k,l,jc,lc;
00251   size_t ipph = (ip+1)/2;
00252 
00253   for (i=1; i<ip; ++i)
00254     wal[i]=wa[ido*(i-1)];
00255   for (k=0; k<l1; ++k)
00256     for (i=0; i<ido; ++i)
00257       {
00258       cmplx s=CC(i,0,k);
00259       ccl[0] = CC(i,0,k);
00260       for(j=1,jc=ip-1; j<ipph; ++j,--jc)
00261         {
00262         PMC (ccl[j],ccl[jc],CC(i,j,k),CC(i,jc,k))
00263         ADDC (s,s,ccl[j])
00264         }
00265       CH(i,k,0) = s;
00266       for (j=1, jc=ip-1; j<=ipph; ++j,--jc)
00267         {
00268         cmplx abr=ccl[0], abi={0.,0.};
00269         size_t iang=0;
00270         for (l=1,lc=ip-1; l<ipph; ++l,--lc)
00271           {
00272           iang+=j;
00273           if (iang>ip) iang-=ip;
00274           abr.r += ccl[l ].r*wal[iang].r;
00275           abr.i += ccl[l ].i*wal[iang].r;
00276           abi.r += ccl[lc].r*wal[iang].i;
00277           abi.i += ccl[lc].i*wal[iang].i;
00278           }
00279 #ifndef BACKWARD
00280           { abi.i=-abi.i; abi.r=-abi.r; }
00281 #endif
00282         CONJFLIPC(abi)
00283         PMC(CH(i,k,j),CH(i,k,jc),abr,abi)
00284         }
00285       }
00286 
00287   DEALLOC(tarr);
00288 
00289   if (ido==1) return;
00290 
00291   for (j=1; j<ip; ++j)
00292     for (k=0; k<l1; ++k)
00293       {
00294       size_t idij=(j-1)*ido+1;
00295       for(i=1; i<ido; ++i, ++idij)
00296         {
00297         cmplx t=CH(i,k,j);
00298         MULPMSIGNC (CH(i,k,j),wa[idij],t)
00299         }
00300       }
00301   }
00302 
00303 #undef PSIGN
00304 #undef PMSIGNC
00305 #undef MULPMSIGNC