source: Sophya/trunk/SophyaLib/NTools/fftmayer_r8.c@ 3750

Last change on this file since 3750 was 717, checked in by ansari, 26 years ago

Introduction FFTMayer, debug de FFTPack - Reza 5/2/2000

File size: 6.5 KB
Line 
1/*
2** FFT and FHT routines
3** Copyright 1988, 1993; Ron Mayer
4**
5** fht(fz,n);
6** Does a hartley transform of "n" points in the array "fz".
7** fft(n,real,imag)
8** Does a fourier transform of "n" points of the "real" and
9** "imag" arrays.
10** ifft(n,real,imag)
11** Does an inverse fourier transform of "n" points of the "real"
12** and "imag" arrays.
13** realfft(n,real)
14** Does a real-valued fourier transform of "n" points of the
15** "real" array. The real part of the transform ends
16** up in the first half of the array and the imaginary part of the
17** transform ends up in the second half of the array.
18** realifft(n,real)
19** The inverse of the realfft() routine above.
20**
21**
22** NOTE: This routine uses at least 2 patented algorithms, and may be
23** under the restrictions of a bunch of different organizations.
24** Although I wrote it completely myself; it is kind of a derivative
25** of a routine I once authored and released under the GPL, so it
26** may fall under the free software foundation's restrictions;
27** it was worked on as a Stanford Univ project, so they claim
28** some rights to it; it was further optimized at work here, so
29** I think this company claims parts of it. The patents are
30** held by R. Bracewell (the FHT algorithm) and O. Buneman (the
31** trig generator), both at Stanford Univ.
32** If it were up to me, I'd say go do whatever you want with it;
33** but it would be polite to give credit to the following people
34** if you use this anywhere:
35** Euler - probable inventor of the fourier transform.
36** Gauss - probable inventor of the FFT.
37** Hartley - probable inventor of the hartley transform.
38** Buneman - for a really cool trig generator
39** Mayer(me) - for authoring this particular version and
40** including all the optimizations in one package.
41** Thanks,
42** Ron Mayer; mayer@acuson.com
43**
44*/
45
46#include "fftmayer.h"
47
48#define GOOD_TRIG
49#define REAL r_8
50#include "trigtbl.h"
51
52char fht_r8_version[] = "Brcwl-Hrtly-Ron-dbld";
53
54#define SQRT2_2 0.70710678118654752440084436210484
55#define SQRT2 2*0.70710678118654752440084436210484
56
57void fht_r8(r_8 *fz,int n)
58{
59 r_8 a,b;
60 r_8 c1,s1,s2,c2,s3,c3,s4,c4;
61 r_8 f0,g0,f1,g1,f2,g2,f3,g3;
62 int i,k,k1,k2,k3,k4,kx;
63 r_8 *fi,*fn,*gi;
64 TRIG_VARS;
65
66 for (k1=1,k2=0;k1<n;k1++)
67 {
68 r_8 a;
69 for (k=n>>1; (!((k2^=k)&k)); k>>=1);
70 if (k1>k2)
71 {
72 a=fz[k1];fz[k1]=fz[k2];fz[k2]=a;
73 }
74 }
75 for ( k=0 ; (1<<k)<n ; k++ );
76 k &= 1;
77 if (k==0)
78 {
79 for (fi=fz,fn=fz+n;fi<fn;fi+=4)
80 {
81 r_8 f0,f1,f2,f3;
82 f1 = fi[0 ]-fi[1 ];
83 f0 = fi[0 ]+fi[1 ];
84 f3 = fi[2 ]-fi[3 ];
85 f2 = fi[2 ]+fi[3 ];
86 fi[2 ] = (f0-f2);
87 fi[0 ] = (f0+f2);
88 fi[3 ] = (f1-f3);
89 fi[1 ] = (f1+f3);
90 }
91 }
92 else
93 {
94 for (fi=fz,fn=fz+n,gi=fi+1;fi<fn;fi+=8,gi+=8)
95 {
96 r_8 s1,c1,s2,c2,s3,c3,s4,c4,g0,f0,f1,g1,f2,g2,f3,g3;
97 c1 = fi[0 ] - gi[0 ];
98 s1 = fi[0 ] + gi[0 ];
99 c2 = fi[2 ] - gi[2 ];
100 s2 = fi[2 ] + gi[2 ];
101 c3 = fi[4 ] - gi[4 ];
102 s3 = fi[4 ] + gi[4 ];
103 c4 = fi[6 ] - gi[6 ];
104 s4 = fi[6 ] + gi[6 ];
105 f1 = (s1 - s2);
106 f0 = (s1 + s2);
107 g1 = (c1 - c2);
108 g0 = (c1 + c2);
109 f3 = (s3 - s4);
110 f2 = (s3 + s4);
111 g3 = SQRT2*c4;
112 g2 = SQRT2*c3;
113 fi[4 ] = f0 - f2;
114 fi[0 ] = f0 + f2;
115 fi[6 ] = f1 - f3;
116 fi[2 ] = f1 + f3;
117 gi[4 ] = g0 - g2;
118 gi[0 ] = g0 + g2;
119 gi[6 ] = g1 - g3;
120 gi[2 ] = g1 + g3;
121 }
122 }
123 if (n<16) return;
124
125 do
126 {
127 r_8 s1,c1;
128 k += 2;
129 k1 = 1 << k;
130 k2 = k1 << 1;
131 k4 = k2 << 1;
132 k3 = k2 + k1;
133 kx = k1 >> 1;
134 fi = fz;
135 gi = fi + kx;
136 fn = fz + n;
137 do
138 {
139 r_8 g0,f0,f1,g1,f2,g2,f3,g3;
140 f1 = fi[0 ] - fi[k1];
141 f0 = fi[0 ] + fi[k1];
142 f3 = fi[k2] - fi[k3];
143 f2 = fi[k2] + fi[k3];
144 fi[k2] = f0 - f2;
145 fi[0 ] = f0 + f2;
146 fi[k3] = f1 - f3;
147 fi[k1] = f1 + f3;
148 g1 = gi[0 ] - gi[k1];
149 g0 = gi[0 ] + gi[k1];
150 g3 = SQRT2 * gi[k3];
151 g2 = SQRT2 * gi[k2];
152 gi[k2] = g0 - g2;
153 gi[0 ] = g0 + g2;
154 gi[k3] = g1 - g3;
155 gi[k1] = g1 + g3;
156 gi += k4;
157 fi += k4;
158 } while (fi<fn);
159 TRIG_INIT(k,c1,s1);
160 for (i=1;i<kx;i++)
161 {
162 r_8 c2,s2;
163 TRIG_NEXT(k,c1,s1);
164 c2 = c1*c1 - s1*s1;
165 s2 = 2*(c1*s1);
166 fn = fz + n;
167 fi = fz +i;
168 gi = fz +k1-i;
169 do
170 {
171 r_8 a,b,g0,f0,f1,g1,f2,g2,f3,g3;
172 b = s2*fi[k1] - c2*gi[k1];
173 a = c2*fi[k1] + s2*gi[k1];
174 f1 = fi[0 ] - a;
175 f0 = fi[0 ] + a;
176 g1 = gi[0 ] - b;
177 g0 = gi[0 ] + b;
178 b = s2*fi[k3] - c2*gi[k3];
179 a = c2*fi[k3] + s2*gi[k3];
180 f3 = fi[k2] - a;
181 f2 = fi[k2] + a;
182 g3 = gi[k2] - b;
183 g2 = gi[k2] + b;
184 b = s1*f2 - c1*g3;
185 a = c1*f2 + s1*g3;
186 fi[k2] = f0 - a;
187 fi[0 ] = f0 + a;
188 gi[k3] = g1 - b;
189 gi[k1] = g1 + b;
190 b = c1*g2 - s1*f3;
191 a = s1*g2 + c1*f3;
192 gi[k2] = g0 - a;
193 gi[0 ] = g0 + a;
194 fi[k3] = f1 - b;
195 fi[k1] = f1 + b;
196 gi += k4;
197 fi += k4;
198 } while (fi<fn);
199 }
200 TRIG_RESET(k,c1,s1);
201 } while (k4<n);
202}
203
204
205void ifft_r8(int n, r_8 *real, r_8 *imag)
206{
207 r_8 a,b,c,d;
208 r_8 q,r,s,t;
209 int i,j,k;
210 fht_r8(real,n);
211 fht_r8(imag,n);
212 for (i=1,j=n-1,k=n/2;i<k;i++,j--) {
213 a = real[i]; b = real[j]; q=a+b; r=a-b;
214 c = imag[i]; d = imag[j]; s=c+d; t=c-d;
215 imag[i] = (s+r)*0.5; imag[j] = (s-r)*0.5;
216 real[i] = (q-t)*0.5; real[j] = (q+t)*0.5;
217 }
218}
219
220void realfft_r8(int n, r_8 *real)
221{
222 r_8 a,b,c,d;
223 int i,j,k;
224 fht_r8(real,n);
225 for (i=1,j=n-1,k=n/2;i<k;i++,j--) {
226 a = real[i];
227 b = real[j];
228 real[j] = (a-b)*0.5;
229 real[i] = (a+b)*0.5;
230 }
231}
232
233void fft_r8(int n, r_8 *real,r_8 *imag)
234{
235 r_8 a,b,c,d;
236 r_8 q,r,s,t;
237 int i,j,k;
238 for (i=1,j=n-1,k=n/2;i<k;i++,j--) {
239 a = real[i]; b = real[j]; q=a+b; r=a-b;
240 c = imag[i]; d = imag[j]; s=c+d; t=c-d;
241 real[i] = (q+t)*.5; real[j] = (q-t)*.5;
242 imag[i] = (s-r)*.5; imag[j] = (s+r)*.5;
243 }
244 fht_r8(real,n);
245 fht_r8(imag,n);
246}
247
248void realifft_r8(int n,r_8 *real)
249{
250 r_8 a,b,c,d;
251 int i,j,k;
252 for (i=1,j=n-1,k=n/2;i<k;i++,j--) {
253 a = real[i];
254 b = real[j];
255 real[j] = (a-b);
256 real[i] = (a+b);
257 }
258 fht_r8(real,n);
259}
Note: See TracBrowser for help on using the repository browser.