17.11.2012 Views

Numerical recipes

Numerical recipes

Numerical recipes

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

528 Chapter 12. Fast Fourier Transform<br />

overwriting the input array of data. The three enclosing for loops (indices i2, i3,<br />

and i1, from inside to outside) could in fact be done in any order — their actions all<br />

commute. We chose the order shown because of the following considerations: (i) i3<br />

should not be the inner loop, because if it is, then the recurrence relations on wr and<br />

wi become burdensome. (ii) On virtual-memory machines, i1 should be the outer<br />

loop, because (with C order of array storage) this results in the array data, which<br />

might be very large, being accessed in block sequential order.<br />

Note that the work done in rlft3 is quite (logarithmically) small, compared to<br />

the associated complex FFT, fourn. Since C does not have a convenient complex<br />

type, the operations are carried out explicitly below in terms of real and imaginary<br />

parts. The routine rlft3 is based on an earlier routine by G.B. Rybicki.<br />

#include <br />

void rlft3(float ***data, float **speq, unsigned long nn1, unsigned long nn2,<br />

unsigned long nn3, int isign)<br />

Given a three-dimensional real array data[1..nn1][1..nn2][1..nn3] (where nn1 =1for<br />

the case of a logically two-dimensional array), this routine returns (for isign=1) thecomplex<br />

fast Fourier transform as two complex arrays: On output, data contains the zero and positive<br />

frequency values of the third frequency component, while speq[1..nn1][1..2*nn2] contains<br />

the Nyquist critical frequency values of the third frequency component. First (and second)<br />

frequency components are stored for zero, positive, and negative frequencies, in standard wraparound<br />

order. See text for description of how complex values are arranged. For isign=-1, the<br />

inverse transform (times nn1*nn2*nn3/2 as a constant multiplicative factor) is performed,<br />

with output data (viewed as a real array) deriving from input data (viewed as complex) and<br />

speq. For inverse transforms on data not generated first by a forward transform, make sure<br />

the complex input data array satisfies property (12.5.2). The dimensions nn1, nn2, nn3 must<br />

always be integer powers of 2.<br />

{<br />

void fourn(float data[], unsigned long nn[], int ndim, int isign);<br />

void nrerror(char error_text[]);<br />

unsigned long i1,i2,i3,j1,j2,j3,nn[4],ii3;<br />

double theta,wi,wpi,wpr,wr,wtemp;<br />

float c1,c2,h1r,h1i,h2r,h2i;<br />

if (1+&data[nn1][nn2][nn3]-&data[1][1][1] != nn1*nn2*nn3)<br />

nrerror("rlft3: problem with dimensions or contiguity of data array\n");<br />

c1=0.5;<br />

c2 = -0.5*isign;<br />

theta=isign*(6.28318530717959/nn3);<br />

wtemp=sin(0.5*theta);<br />

wpr = -2.0*wtemp*wtemp;<br />

wpi=sin(theta);<br />

nn[1]=nn1;<br />

nn[2]=nn2;<br />

nn[3]=nn3 >> 1;<br />

if (isign == 1) { Case of forward transform.<br />

fourn(&data[1][1][1]-1,nn,3,isign); Here is where most all of the com-<br />

for (i1=1;i1

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!