#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); } }