68 lines
1.4 KiB
C++
68 lines
1.4 KiB
C++
#include <cmath>
|
|
#include "nr.h"
|
|
using namespace std;
|
|
|
|
void NR::fourn(Vec_IO_DP &data, Vec_I_INT &nn, const int isign)
|
|
{
|
|
int idim,i1,i2,i3,i2rev,i3rev,ip1,ip2,ip3,ifp1,ifp2;
|
|
int ibit,k1,k2,n,nprev,nrem,ntot;
|
|
DP tempi,tempr,theta,wi,wpi,wpr,wr,wtemp;
|
|
|
|
int ndim=nn.size();
|
|
ntot=data.size()/2;
|
|
nprev=1;
|
|
for (idim=ndim-1;idim>=0;idim--) {
|
|
n=nn[idim];
|
|
nrem=ntot/(n*nprev);
|
|
ip1=nprev << 1;
|
|
ip2=ip1*n;
|
|
ip3=ip2*nrem;
|
|
i2rev=0;
|
|
for (i2=0;i2<ip2;i2+=ip1) {
|
|
if (i2 < i2rev) {
|
|
for (i1=i2;i1<i2+ip1-1;i1+=2) {
|
|
for (i3=i1;i3<ip3;i3+=ip2) {
|
|
i3rev=i2rev+i3-i2;
|
|
SWAP(data[i3],data[i3rev]);
|
|
SWAP(data[i3+1],data[i3rev+1]);
|
|
}
|
|
}
|
|
}
|
|
ibit=ip2 >> 1;
|
|
while (ibit >= ip1 && i2rev+1 > ibit) {
|
|
i2rev -= ibit;
|
|
ibit >>= 1;
|
|
}
|
|
i2rev += ibit;
|
|
}
|
|
ifp1=ip1;
|
|
while (ifp1 < ip2) {
|
|
ifp2=ifp1 << 1;
|
|
theta=isign*6.28318530717959/(ifp2/ip1);
|
|
wtemp=sin(0.5*theta);
|
|
wpr= -2.0*wtemp*wtemp;
|
|
wpi=sin(theta);
|
|
wr=1.0;
|
|
wi=0.0;
|
|
for (i3=0;i3<ifp1;i3+=ip1) {
|
|
for (i1=i3;i1<i3+ip1-1;i1+=2) {
|
|
for (i2=i1;i2<ip3;i2+=ifp2) {
|
|
k1=i2;
|
|
k2=k1+ifp1;
|
|
tempr=wr*data[k2]-wi*data[k2+1];
|
|
tempi=wr*data[k2+1]+wi*data[k2];
|
|
data[k2]=data[k1]-tempr;
|
|
data[k2+1]=data[k1+1]-tempi;
|
|
data[k1] += tempr;
|
|
data[k1+1] += tempi;
|
|
}
|
|
}
|
|
wr=(wtemp=wr)*wpr-wi*wpi+wr;
|
|
wi=wi*wpr+wtemp*wpi+wi;
|
|
}
|
|
ifp1=ifp2;
|
|
}
|
|
nprev *= n;
|
|
}
|
|
}
|