165 lines
4.2 KiB
C++
165 lines
4.2 KiB
C++
#include <iostream>
|
|
#include <fstream>
|
|
#include <cmath>
|
|
#include "nr.h"
|
|
using namespace std;
|
|
|
|
void NR::fourfs(Vec_FSTREAM_p &file, Vec_I_INT &nn, const int isign)
|
|
{
|
|
const int KBF=128;
|
|
static int mate[4]={1,0,3,2};
|
|
int cc,cc0,j,j12,jk,k,kk,n=1,mm,kc=0,kd,ks,kr,na,nb,nc,nd,nr,ns,nv;
|
|
DP tempr,tempi,wr,wi,wpr,wpi,wtemp,theta;
|
|
Vec_DP afa(KBF),afb(KBF),afc(KBF);
|
|
|
|
int ndim=nn.size();
|
|
for (j=0;j<ndim;j++) {
|
|
n *= nn[j];
|
|
if (nn[j] <= 1) nrerror("invalid DP or wrong ndim in fourfs");
|
|
}
|
|
nv=0;
|
|
jk=nn[nv];
|
|
mm=n;
|
|
ns=n/KBF;
|
|
nr=ns >> 1;
|
|
kd=KBF >> 1;
|
|
ks=n;
|
|
fourew(file,na,nb,nc,nd);
|
|
for (;;) {
|
|
theta=isign*3.141592653589793/(n/mm);
|
|
wtemp=sin(0.5*theta);
|
|
wpr = -2.0*wtemp*wtemp;
|
|
wpi=sin(theta);
|
|
wr=1.0;
|
|
wi=0.0;
|
|
mm >>= 1;
|
|
for (j12=0;j12<2;j12++) {
|
|
kr=0;
|
|
do {
|
|
cc0=(*file[na]).tellg()/sizeof(DP);
|
|
(*file[na]).read((char *) &afa[0],KBF*sizeof(DP));
|
|
cc=(*file[na]).tellg()/sizeof(DP);
|
|
if ((cc-cc0) != KBF) nrerror("read error 1 in fourfs");
|
|
cc0=(*file[nb]).tellg()/sizeof(DP);
|
|
(*file[nb]).read((char *) &afb[0],KBF*sizeof(DP));
|
|
cc=(*file[nb]).tellg()/sizeof(DP);
|
|
if ((cc-cc0) != KBF) nrerror("read error 2 in fourfs");
|
|
for (j=0;j<KBF;j+=2) {
|
|
tempr=wr*afb[j]-wi*afb[j+1];
|
|
tempi=wi*afb[j]+wr*afb[j+1];
|
|
afb[j]=afa[j]-tempr;
|
|
afa[j] += tempr;
|
|
afb[j+1]=afa[j+1]-tempi;
|
|
afa[j+1] += tempi;
|
|
}
|
|
kc += kd;
|
|
if (kc == mm) {
|
|
kc=0;
|
|
wr=(wtemp=wr)*wpr-wi*wpi+wr;
|
|
wi=wi*wpr+wtemp*wpi+wi;
|
|
}
|
|
cc0=(*file[nc]).tellp()/sizeof(DP);
|
|
(*file[nc]).write((char *) &afa[0],KBF*sizeof(DP));
|
|
cc=(*file[nc]).tellp()/sizeof(DP);
|
|
if ((cc-cc0) != KBF) nrerror("write error 1 in fourfs");
|
|
cc0=(*file[nd]).tellp()/sizeof(DP);
|
|
(*file[nd]).write((char *) &afb[0],KBF*sizeof(DP));
|
|
cc=(*file[nd]).tellp()/sizeof(DP);
|
|
if ((cc-cc0) != KBF) nrerror("write error 2 in fourfs");
|
|
} while (++kr < nr);
|
|
if (j12 == 0 && ks != n && ks == KBF) {
|
|
na=mate[na];
|
|
nb=na;
|
|
}
|
|
if (nr == 0) break;
|
|
}
|
|
fourew(file,na,nb,nc,nd);
|
|
jk >>= 1;
|
|
while (jk == 1) {
|
|
mm=n;
|
|
jk=nn[++nv];
|
|
}
|
|
ks >>= 1;
|
|
if (ks > KBF) {
|
|
for (j12=0;j12<2;j12++) {
|
|
for (kr=0;kr<ns;kr+=ks/KBF) {
|
|
for (k=0;k<ks;k+=KBF) {
|
|
cc0=(*file[na]).tellg()/sizeof(DP);
|
|
(*file[na]).read((char *) &afa[0],KBF*sizeof(DP));
|
|
cc=(*file[na]).tellg()/sizeof(DP);
|
|
if ((cc-cc0) != KBF) nrerror("read error 3 in fourfs");
|
|
cc0=(*file[nc]).tellp()/sizeof(DP);
|
|
(*file[nc]).write((char *) &afa[0],KBF*sizeof(DP));
|
|
cc=(*file[nc]).tellp()/sizeof(DP);
|
|
if ((cc-cc0) != KBF) nrerror("write error 3 in fourfs");
|
|
}
|
|
nc=mate[nc];
|
|
}
|
|
na=mate[na];
|
|
}
|
|
fourew(file,na,nb,nc,nd);
|
|
} else if (ks == KBF) nb=na;
|
|
else break;
|
|
}
|
|
j=0;
|
|
for (;;) {
|
|
theta=isign*3.141592653589793/(n/mm);
|
|
wtemp=sin(0.5*theta);
|
|
wpr = -2.0*wtemp*wtemp;
|
|
wpi=sin(theta);
|
|
wr=1.0;
|
|
wi=0.0;
|
|
mm >>= 1;
|
|
ks=kd;
|
|
kd >>= 1;
|
|
for (j12=0;j12<2;j12++) {
|
|
for (kr=0;kr<ns;kr++) {
|
|
cc0=(*file[na]).tellg()/sizeof(DP);
|
|
(*file[na]).read((char *) &afc[0],KBF*sizeof(DP));
|
|
cc=(*file[na]).tellg()/sizeof(DP);
|
|
if ((cc-cc0) != KBF) nrerror("read error 4 in fourfs");
|
|
kk=0;
|
|
k=ks;
|
|
for (;;) {
|
|
tempr=wr*afc[kk+ks]-wi*afc[kk+ks+1];
|
|
tempi=wi*afc[kk+ks]+wr*afc[kk+ks+1];
|
|
afa[j]=afc[kk]+tempr;
|
|
afb[j]=afc[kk]-tempr;
|
|
afa[++j]=afc[++kk]+tempi;
|
|
afb[j++]=afc[kk++]-tempi;
|
|
if (kk < k) continue;
|
|
kc += kd;
|
|
if (kc == mm) {
|
|
kc=0;
|
|
wr=(wtemp=wr)*wpr-wi*wpi+wr;
|
|
wi=wi*wpr+wtemp*wpi+wi;
|
|
}
|
|
kk += ks;
|
|
if (kk > KBF-1) break;
|
|
else k=kk+ks;
|
|
}
|
|
if (j > KBF-1) {
|
|
cc0=(*file[nc]).tellp()/sizeof(DP);
|
|
(*file[nc]).write((char *) &afa[0],KBF*sizeof(DP));
|
|
cc=(*file[nc]).tellp()/sizeof(DP);
|
|
if ((cc-cc0) != KBF) nrerror("write error 4 in fourfs");
|
|
cc0=(*file[nd]).tellp()/sizeof(DP);
|
|
(*file[nd]).write((char *) &afb[0],KBF*sizeof(DP));
|
|
cc=(*file[nd]).tellp()/sizeof(DP);
|
|
if ((cc-cc0) != KBF) nrerror("write error 5 in fourfs");
|
|
j=0;
|
|
}
|
|
}
|
|
na=mate[na];
|
|
}
|
|
fourew(file,na,nb,nc,nd);
|
|
jk >>= 1;
|
|
if (jk > 1) continue;
|
|
mm=n;
|
|
do {
|
|
if (nv < ndim-1) jk=nn[++nv];
|
|
else return;
|
|
} while (jk == 1);
|
|
}
|
|
}
|