#include #include #include #include "nr.h" using namespace std; void NR::frenel(const DP x, complex &cs) { const int MAXIT=100; const DP EPS=numeric_limits::epsilon(); const DP FPMIN=numeric_limits::min(); const DP BIG=numeric_limits::max()*EPS; const DP PI=3.141592653589793238, PIBY2=(PI/2.0), XMIN=1.5; bool odd; int k,n; DP a,ax,fact,pix2,sign,sum,sumc,sums,term,test; complex b,cc,d,h,del; ax=fabs(x); if (ax < sqrt(FPMIN)) { cs=ax; } else if (ax <= XMIN) { sum=sums=0.0; sumc=ax; sign=1.0; fact=PIBY2*ax*ax; odd=true; term=ax; n=3; for (k=1;k<=MAXIT;k++) { term *= fact/k; sum += sign*term/n; test=fabs(sum)*EPS; if (odd) { sign = -sign; sums=sum; sum=sumc; } else { sumc=sum; sum=sums; } if (term < test) break; odd=!odd; n += 2; } if (k > MAXIT) nrerror("series failed in frenel"); cs=complex(sumc,sums); } else { pix2=PI*ax*ax; b=complex(1.0,-pix2); cc=BIG; d=h=1.0/b; n = -1; for (k=2;k<=MAXIT;k++) { n += 2; a = -n*(n+1); b += 4.0; d=1.0/(a*d+b); cc=b+a/cc; del=cc*d; h *= del; if (fabs(real(del)-1.0)+fabs(imag(del)) <= EPS) break; } if (k > MAXIT) nrerror("cf failed in frenel"); h *= complex(ax,-ax); cs=complex(0.5,0.5) *(1.0-complex(cos(0.5*pix2),sin(0.5*pix2))*h); } if (x < 0.0) { cs = -cs; } return; }