add numerical recipes library
This commit is contained in:
73
lib/nr/cpp/recipes/frenel.cpp
Normal file
73
lib/nr/cpp/recipes/frenel.cpp
Normal file
@@ -0,0 +1,73 @@
|
||||
#include <cmath>
|
||||
#include <complex>
|
||||
#include <limits>
|
||||
#include "nr.h"
|
||||
using namespace std;
|
||||
|
||||
void NR::frenel(const DP x, complex<DP> &cs)
|
||||
{
|
||||
const int MAXIT=100;
|
||||
const DP EPS=numeric_limits<DP>::epsilon();
|
||||
const DP FPMIN=numeric_limits<DP>::min();
|
||||
const DP BIG=numeric_limits<DP>::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<DP> 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<DP>(sumc,sums);
|
||||
} else {
|
||||
pix2=PI*ax*ax;
|
||||
b=complex<DP>(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<DP>(ax,-ax);
|
||||
cs=complex<DP>(0.5,0.5)
|
||||
*(1.0-complex<DP>(cos(0.5*pix2),sin(0.5*pix2))*h);
|
||||
}
|
||||
if (x < 0.0) {
|
||||
cs = -cs;
|
||||
}
|
||||
return;
|
||||
}
|
||||
Reference in New Issue
Block a user