数学分析
二分求零点、三分求极值点
需要
f(x)
在区间
[l,r]
上单调/凹凸性唯一。
double bs(double l,double r,double f(double x))
{
if(r-l<EPS)return l;
double m=(l+r)/2;
return sgn(f(l)*f(m))<0?bs(l,m,f):ts(m,r,f);
}
double ts(double l,double r,double f(double x))
{
if(r-l<EPS)return l;
double d=(r-l)/3,lm=l+d,rm=r-d;
return f(lm)<f(rm)?ts(l,rm,f):ts(lm,r,f);
}
积分表
反读可得导数表,此处略。
∫kdx=kx+C
∫xadx=xa+1a+1+C
∫1xdx=ln|x|+C
∫exdx=ex+C
∫axdx=axlna+C
∫cosxdx=sinx+C
∫sinxdx=−cosx+C
∫1cos2xdx=∫sec2xdx=tanx+C
∫1sin2xdx=∫csc2xdx=−cotx+C
∫11−x2√dx=arcsinx+C=−arccosx+C
∫11+x2dx=arctanx+C=−arccotx+C
∫secxtanxdx=secx+C
∫cscxcotxdx=−cscx+C
∫tanxdx=−ln|cosx|+C
∫cotxdx=ln|sinx|+C
∫secxdx=ln|secx+tanx|+C
∫cscxdx=ln|cscx−cotx|+C
∫shxdx=chx+C
∫chxdx=shx+C
∫1x2+a2dx=1aarctanxa+C
∫1x2−a2dx=12aln|x−ax+a|+C
∫1a2−x2√dx=arcsinxa+C
∫1x2−a2√dx=ln|x+x2−a2−−−−−−√|+C
∫1x2+a2√dx=ln|x+x2+a2−−−−−−√|+C
泰勒公式
用
f(n)(x)
表示f(x)的n阶导数。
只要让余项<EPS
即可计算指定函数到任意精确度。
特别取a=0时称为麦克劳林公式。
f(x)=f(a)+f(1)(a)(x−a)+f(2)(a)2!(x−a)2+…+f(n)(a)n!(x−a)n+Rn(x)
Rn(x)=o((x−a)n)
,佩亚诺余项
Rn(x)=1n!∫xa(x−t)nf(n+1)(t)dt
,积分余项
Rn(x)=f(n+1)(ξ)(n+1)!(x−a)n+1,a<ξ<x
,拉格朗日余项
Rn(x)=(x−a)n+1n!(1−θ)nf(n+1)(a+θ(x−a)),0<θ<1
,柯西余项
指数函数
(ex)(n)=ex
ex=1+x+x22!+x33!+…+xnn!+Rn(x)
Rn(x)=eθx(n+1)!xn+1,ξ=θx,0<θ<1
三角函数
(sinx)(n)=sin(x+nπ2)
sinx=x−x33!+x55!−x77!+…+(−1)k−1x2k−1(2k−1)!+R2k(x)
R2k(x)=(−1)kcosθx(2k+1)!x2k+1
(cosx)(n)=cos(x+nπ2)
cosx=1−x22!+x44!−x66!+…+(−1)k−1x2k−2(2k−2)!+R2k−1(x)
R2k−1(x)=(−1)kcosθx(2k)!x2k
对数函数
[ln(1+x)](n)=(−1)n−1(n−1)!(1+x)−n
ln(1+x)=x−x22+x33−x44+…+(−1)n−1xnn+Rn(x)
幂函数
[(1+x)a](n)=a(a−1)…(a−n+1)(1+x)a−n
(1+x)a=1+ax+a(a−1)2!x2+⋯+a(a−1)…(a−n+1)n!xn+Rn(x)
级数
调和级数
n→∞,∑ni=11i→lnn+r,r≈0.5772156649015328…
幂级数
∑ni=1i1=12n(n+1)
∑ni=1i2=16n(n+1)(2n+1)
∑ni=1i3=14[n(n+1)]2
∑ni=1i4=130n(n+1)(2n+1)(3n2+3n−1)
∑ni=1i5=112[n(n+1)]2(2n2+2n−1)
∑ni=1i6=142n(n+1)(2n+1)(3n4+6n3−3n+1)
插值法
拉格朗日插值法:插值多项式和插值基函数的形式对称,容易编程。但是,增加节点时,需要重新计算每一个插值基函数。要在
(modp)
意义下进行的话,那么p只能是质数。
牛顿插值法:当插值节点增加时,之前已计算的结果仍然能用,每增加一个节点,只要再增加一项即可,从而避免了重复性计算。如果要mod非质数的话,那么就要用牛顿插值法。
typedef complex<double> Coord;
#define X real()
#define Y imag()
double lagrange(const vector<Coord> &p,double x)
{
double ret=0;
for(int i=0; i<p.size(); ++i)
{
double tmp=p[i].Y;
for(int j=0; j<p.size(); ++j)
if(i!=j)tmp*=(x-p[j].X)/(p[i].X-p[j].X);
ret+=tmp;
}
return ret;
}
vector<double> lagrange(vector<Coord> p)
{
vector<double> ret(p.size()),sum(p.size());
ret[0]=p[0].Y,sum[0]=1;
for(int i=1; i<p.size(); ++i)
{
for(int j=p.size()-1; j>=i; --j)
p[j].Y=(p[j].Y-p[j-1].Y)/(p[j].X-p[j-i].X);
for(int j=i; ~j; --j)
sum[j]=(j?sum[j-1]:0)-sum[j]*p[i-1].X,
ret[j]+=sum[j]*p[i].Y;
}
return ret;
}
double DifferenceQuotient(const vector<Coord> &p,int k)
{
double ret=0;
for(int i=0; i<=k; ++i)
{
double tmp=p[i].Y;
for(int j=0; j<=k; ++j)
if(i!=j)tmp/=p[i].X-p[j].X;
ret+=tmp;
}
return ret;
}
double newton(const vector<Coord> &p,double x)
{
double ret=p[0].Y;
for(int i=1; i<p.size(); ++i)
{
double tmp=DifferenceQuotient(p,i);
for(int j=0; j<i; ++j)tmp*=x-p[j].X;
ret+=tmp;
}
return ret;
}