📄 elliptint.h
字号:
Doub rc(const Doub x, const Doub y) {
static const Doub ERRTOL=0.0012, THIRD=1.0/3.0, C1=0.3, C2=1.0/7.0,
C3=0.375, C4=9.0/22.0;
static const Doub TINY=5.0*numeric_limits<Doub>::min(),
BIG=0.2*numeric_limits<Doub>::max(), COMP1=2.236/sqrt(TINY),
COMP2=SQR(TINY*BIG)/25.0;
Doub alamb,ave,s,w,xt,yt;
if (x < 0.0 || y == 0.0 || (x+abs(y)) < TINY || (x+abs(y)) > BIG ||
(y<-COMP1 && x > 0.0 && x < COMP2)) throw("invalid arguments in rc");
if (y > 0.0) {
xt=x;
yt=y;
w=1.0;
} else {
xt=x-y;
yt= -y;
w=sqrt(x)/sqrt(xt);
}
do {
alamb=2.0*sqrt(xt)*sqrt(yt)+yt;
xt=0.25*(xt+alamb);
yt=0.25*(yt+alamb);
ave=THIRD*(xt+yt+yt);
s=(yt-ave)/ave;
} while (abs(s) > ERRTOL);
return w*(1.0+s*s*(C1+s*(C2+s*(C3+s*C4))))/sqrt(ave);
}
Doub rd(const Doub x, const Doub y, const Doub z) {
static const Doub ERRTOL=0.0015, C1=3.0/14.0, C2=1.0/6.0, C3=9.0/22.0,
C4=3.0/26.0, C5=0.25*C3, C6=1.5*C4;
static const Doub TINY=2.0*pow(numeric_limits<Doub>::max(),-2./3.),
BIG=0.1*ERRTOL*pow(numeric_limits<Doub>::min(),-2./3.);
Doub alamb,ave,delx,dely,delz,ea,eb,ec,ed,ee,fac,sqrtx,sqrty,
sqrtz,sum,xt,yt,zt;
if (MIN(x,y) < 0.0 || MIN(x+y,z) < TINY || MAX(MAX(x,y),z) > BIG)
throw("invalid arguments in rd");
xt=x;
yt=y;
zt=z;
sum=0.0;
fac=1.0;
do {
sqrtx=sqrt(xt);
sqrty=sqrt(yt);
sqrtz=sqrt(zt);
alamb=sqrtx*(sqrty+sqrtz)+sqrty*sqrtz;
sum += fac/(sqrtz*(zt+alamb));
fac=0.25*fac;
xt=0.25*(xt+alamb);
yt=0.25*(yt+alamb);
zt=0.25*(zt+alamb);
ave=0.2*(xt+yt+3.0*zt);
delx=(ave-xt)/ave;
dely=(ave-yt)/ave;
delz=(ave-zt)/ave;
} while (MAX(MAX(abs(delx),abs(dely)),abs(delz)) > ERRTOL);
ea=delx*dely;
eb=delz*delz;
ec=ea-eb;
ed=ea-6.0*eb;
ee=ed+ec+ec;
return 3.0*sum+fac*(1.0+ed*(-C1+C5*ed-C6*delz*ee)
+delz*(C2*ee+delz*(-C3*ec+delz*C4*ea)))/(ave*sqrt(ave));
}
Doub rf(const Doub x, const Doub y, const Doub z) {
static const Doub ERRTOL=0.0025, THIRD=1.0/3.0,C1=1.0/24.0, C2=0.1,
C3=3.0/44.0, C4=1.0/14.0;
static const Doub TINY=5.0*numeric_limits<Doub>::min(),
BIG=0.2*numeric_limits<Doub>::max();
Doub alamb,ave,delx,dely,delz,e2,e3,sqrtx,sqrty,sqrtz,xt,yt,zt;
if (MIN(MIN(x,y),z) < 0.0 || MIN(MIN(x+y,x+z),y+z) < TINY ||
MAX(MAX(x,y),z) > BIG) throw("invalid arguments in rf");
xt=x;
yt=y;
zt=z;
do {
sqrtx=sqrt(xt);
sqrty=sqrt(yt);
sqrtz=sqrt(zt);
alamb=sqrtx*(sqrty+sqrtz)+sqrty*sqrtz;
xt=0.25*(xt+alamb);
yt=0.25*(yt+alamb);
zt=0.25*(zt+alamb);
ave=THIRD*(xt+yt+zt);
delx=(ave-xt)/ave;
dely=(ave-yt)/ave;
delz=(ave-zt)/ave;
} while (MAX(MAX(abs(delx),abs(dely)),abs(delz)) > ERRTOL);
e2=delx*dely-delz*delz;
e3=delx*dely*delz;
return (1.0+(C1*e2-C2-C3*e3)*e2+C4*e3)/sqrt(ave);
}
Doub rj(const Doub x, const Doub y, const Doub z, const Doub p) {
static const Doub ERRTOL=0.0015, C1=3.0/14.0, C2=1.0/3.0, C3=3.0/22.0,
C4=3.0/26.0, C5=0.75*C3, C6=1.5*C4, C7=0.5*C2, C8=C3+C3;
static const Doub TINY=pow(5.0*numeric_limits<Doub>::min(),1./3.),
BIG=0.3*pow(0.2*numeric_limits<Doub>::max(),1./3.);
Doub a,alamb,alpha,ans,ave,b,beta,delp,delx,dely,delz,ea,eb,ec,ed,ee,
fac,pt,rcx,rho,sqrtx,sqrty,sqrtz,sum,tau,xt,yt,zt;
if (MIN(MIN(x,y),z) < 0.0 || MIN(MIN(x+y,x+z),MIN(y+z,abs(p))) < TINY
|| MAX(MAX(x,y),MAX(z,abs(p))) > BIG) throw("invalid arguments in rj");
sum=0.0;
fac=1.0;
if (p > 0.0) {
xt=x;
yt=y;
zt=z;
pt=p;
} else {
xt=MIN(MIN(x,y),z);
zt=MAX(MAX(x,y),z);
yt=x+y+z-xt-zt;
a=1.0/(yt-p);
b=a*(zt-yt)*(yt-xt);
pt=yt+b;
rho=xt*zt/yt;
tau=p*pt/yt;
rcx=rc(rho,tau);
}
do {
sqrtx=sqrt(xt);
sqrty=sqrt(yt);
sqrtz=sqrt(zt);
alamb=sqrtx*(sqrty+sqrtz)+sqrty*sqrtz;
alpha=SQR(pt*(sqrtx+sqrty+sqrtz)+sqrtx*sqrty*sqrtz);
beta=pt*SQR(pt+alamb);
sum += fac*rc(alpha,beta);
fac=0.25*fac;
xt=0.25*(xt+alamb);
yt=0.25*(yt+alamb);
zt=0.25*(zt+alamb);
pt=0.25*(pt+alamb);
ave=0.2*(xt+yt+zt+pt+pt);
delx=(ave-xt)/ave;
dely=(ave-yt)/ave;
delz=(ave-zt)/ave;
delp=(ave-pt)/ave;
} while (MAX(MAX(abs(delx),abs(dely)),
MAX(abs(delz),abs(delp))) > ERRTOL);
ea=delx*(dely+delz)+dely*delz;
eb=delx*dely*delz;
ec=delp*delp;
ed=ea-3.0*ec;
ee=eb+2.0*delp*(ea-ec);
ans=3.0*sum+fac*(1.0+ed*(-C1+C5*ed-C6*ee)+eb*(C7+delp*(-C8+delp*C4))
+delp*ea*(C2-delp*C3)-C2*delp*ec)/(ave*sqrt(ave));
if (p <= 0.0) ans=a*(b*ans+3.0*(rcx-rf(xt,yt,zt)));
return ans;
}
Doub ellf(const Doub phi, const Doub ak) {
Doub s=sin(phi);
return s*rf(SQR(cos(phi)),(1.0-s*ak)*(1.0+s*ak),1.0);
}
Doub elle(const Doub phi, const Doub ak) {
Doub cc,q,s;
s=sin(phi);
cc=SQR(cos(phi));
q=(1.0-s*ak)*(1.0+s*ak);
return s*(rf(cc,q,1.0)-(SQR(s*ak))*rd(cc,q,1.0)/3.0);
}
Doub ellpi(const Doub phi, const Doub en, const Doub ak) {
Doub cc,enss,q,s;
s=sin(phi);
enss=en*s*s;
cc=SQR(cos(phi));
q=(1.0-s*ak)*(1.0+s*ak);
return s*(rf(cc,q,1.0)-enss*rj(cc,q,1.0,1.0+enss)/3.0);
}
void sncndn(const Doub uu, const Doub emmc, Doub &sn, Doub &cn, Doub &dn) {
static const Doub CA=1.0e-8;
Bool bo;
Int i,ii,l;
Doub a,b,c,d,emc,u;
VecDoub em(13),en(13);
emc=emmc;
u=uu;
if (emc != 0.0) {
bo=(emc < 0.0);
if (bo) {
d=1.0-emc;
emc /= -1.0/d;
u *= (d=sqrt(d));
}
a=1.0;
dn=1.0;
for (i=0;i<13;i++) {
l=i;
em[i]=a;
en[i]=(emc=sqrt(emc));
c=0.5*(a+emc);
if (abs(a-emc) <= CA*a) break;
emc *= a;
a=c;
}
u *= c;
sn=sin(u);
cn=cos(u);
if (sn != 0.0) {
a=cn/sn;
c *= a;
for (ii=l;ii>=0;ii--) {
b=em[ii];
a *= c;
c *= dn;
dn=(en[ii]+a)/(b+a);
a=c/b;
}
a=1.0/sqrt(c*c+1.0);
sn=(sn >= 0.0 ? a : -a);
cn=c*sn;
}
if (bo) {
a=dn;
dn=cn;
cn=a;
sn /= d;
}
} else {
cn=1.0/cosh(u);
dn=cn;
sn=tanh(u);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -