数学分析 wu-kan

增长趋势

积分表

反读可得导数表,此处略。

积分求几何量

弧长

若简单闭曲线

端点处重合($x(\alpha)=x(\beta),y(\alpha)=y(\beta)$)且其他地方不自交,$x(t),y(t)$连续且满足

此时称曲线光滑,其长度

此式可对称推广到高维空间曲线。 极坐标下,

的长度为

面积

若简单闭曲线

端点处连续($x(\alpha)=x(\beta),y(\alpha)=y(\beta)$)且其他地方不自交,$x(t),y(t)$都逐段有连续微商,则此闭合曲线围起来的有界区域面积

等式右边称为曲线$\Gamma$上的积分,其计算方法是带入参数方程到定积分计算式中,积分上下限为始点与终点对应的参数值。下限并不总是小于上限,参数从下限到上限变化时对应曲线的正向(沿正向观察时,曲线所围的区域永远在左侧)。 极坐标下,连续非负曲线$r=r(\theta)$与向径$\theta=\alpha,\theta=\beta$,其中$0\leq\beta-\alpha\leq2\pi$所围成的平面图形面积

体积

记立体过 x 点且垂直于 x 轴的截面面积为$S(x)$,则其体积

连续曲线$y=f(x)\ge 0,x\in[a,b]$绕 x 轴旋转一周产生的旋转体体积

旋转体侧面积

若曲线由参数方程

给出,则其绕 x 轴旋转体的侧面积

方向导数

设三元函数$u=f(x,y,z)$在点$P_0(x_0,y_0,z_0)$的某邻域内有定义,任意给定始于点$P_0$的射线$l$,$P(x,y,z)$为 l 上且含于定义域内的点。若极限

存在,则称该极限值为函数$f$在点$P_0$沿方向$l$的方向导数,记为 $\frac{\partial f}{\partial l}\mid _{P_0}$或$\frac{\partial f(P_0)}{\partial l}$,$\frac{\Delta_lf(P_0)}{r(P,P_0)}$称为函数在$P_0$点沿$l$方向的增量。

特别地,$\frac{\partial f(P_0)}{\partial x}$就是函数在$P_0$点沿$x$轴正向的方向导数,$y,z$轴上的方向导数同理。若函数在$P_0$点可微,则其在$P_0$沿任何方向$l$的方向导数都存在,则有以下公式

其中$\vec{l_0}=(\cos\alpha,\cos\beta,cos\gamma)=\frac{1}{\rho}(\Delta x,\Delta y,\Delta z)$为$l$的方向余弦。

曲率

若曲线由参数方程

给出且有二阶微商,则其在一点的曲率

若$y=f(x)$,则

同时记$\frac{1}{K}$为曲率半径。

空间曲线的切线与法平面

若已知曲线上一点$P(x_0,y_0,z_0)$处的切向量为$\tau(x_0,y_0,z_0)=(A,B,C)$则曲线在该点的切线方程为

法平面方程为

当曲线由参数方程

给出时,曲线在 P 点的切向量为

更一般地,若曲线用两曲面的交线给出

且在 P 点的某邻域能确定函数组$y=y(x),z=z(x)$满足$y_0=y(x_0),z_0=z(x_0)$,且$y’(x),z’(x)$存在,则曲线在 P 点的切向量

空间曲面的切平面与法线

若已知曲面上一点$P(x_0,y_0,z_0)$处的切平面的法向量为$\vec n=(A’,B’,C’)$则曲线在该点的法线方程为

切平面方程为

当曲面方程为$\pi:F(x,y,z)=0$在曲面上任取一条过 P 的曲线,设其方程为

此时有$F(x(t),y(t),z(t))=0$令$t=t_0$两边对 t 求导,并写成向量的内积式,得

则曲线在 P 点的法向量为

若曲线由参数方程给出

则曲线在 P 点的法向量

高阶导数与泰勒公式

用$f^{(n)}(x)$表示 f(x)的 n 阶导数,只要让余项<EPS即可计算指定函数到任意精确度,特别取 a=0 时称为麦克劳林公式。

佩亚诺余项

积分余项

拉格朗日余项

柯西余项

对数函数

幂函数

三角函数

指数函数

二元函数

设$f(x,y)$在$P_0(x_0,y_0)$的某邻域$O(P_0)$内有直到$n+1$阶连续偏导数,则对$O(P_0)$内$\forall(x_0+\Delta x,y_0+\Delta y),\exists\theta\in(0,1)$,使得

其中

级数部分和

幂级数

快速计算幂级数的部分和$\sum_{i=1}^ni^k\mod M$可借助伯努利数,详见组合数学模板。

调和级数

二分求零点、三分求极值点

需要$f(x)$在区间$[l,r]$上单调/凹凸性唯一。

lf bs(lf l, lf r, lf f(lf x))
{
	if (r - l < EPS)
		return l;
	lf m = (l + r) / 2;
	return sgn(f(l) * f(m)) < 0 ? bs(l, m, f) : ts(m, r, f);
}
lf ts(lf l, lf r, lf f(lf x))
{
	if (r - l < EPS)
		return l;
	lf d = (r - l) / 3, lm = l + d, rm = r - d;
	return f(lm) < f(rm) ? ts(l, rm, f) : ts(lm, r, f); //极小值
}

自适应辛普森求积分

使用示例

这篇论文论证了加一个十五分之一的偏移收敛会比较快…

struct Simpson
{
	lf simpson(lf a, lf b, lf f(lf x))
	{
		return (f(a) + 4 * f((a + b) / 2) + f(b)) * (b - a) / 6;
	}
	lf ask(lf a, lf b, lf f(lf x), lf e = EPS)
	{
		lf c = (a + b) / 2, L = simpson(a, c, f), R = simpson(c, b, f), delta = (L + R - simpson(a, b, f)) / 15;
		return fabs(delta) < e ? L + R + delta : ask(a, c, f, e / 2) + ask(c, b, f, e / 2);
	}
};

插值法

拉格朗日插值法:插值多项式和插值基函数的形式对称,容易编程。但是,增加节点时,需要重新计算每一个插值基函数。要在$\pmod p$意义下进行的话,那么 p 只能是质数。 牛顿插值法:当插值节点增加时,之前已计算的结果仍然能用,每增加一个节点,只要再增加一项即可,从而避免了重复性计算。如果要 mod 非质数的话,那么就要用牛顿插值法。

typedef complex<lf> Coord;
#define X real()
#define Y imag()
struct Lagrange
{
	lf ask(const vector<Coord> &p, lf x) //返回p确定的多项式函数在x处的值
	{
		lf ret = 0;
		for (int i = 0; i < p.size(); ++i)
		{
			lf 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<lf> ask(vector<Coord> p) //返回p确定的多项式系数向量
	{
		vector<lf> 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;
	}
};
struct Newton
{
	lf differenceQuotient(const vector<Coord> &p, int k) //计算差商
	{
		lf ret = 0;
		for (int i = 0; i <= k; ++i)
		{
			lf 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;
	}
	lf ask(const vector<Coord> &p, lf x)
	{
		lf ret = p[0].Y;
		for (int i = 1; i < p.size(); ++i)
		{
			lf tmp = differenceQuotient(p, i); //多次求,可O(n^3)预处理优化
			for (int j = 0; j < i; ++j)
				tmp *= x - p[j].X;
			ret += tmp;
		}
		return ret;
	}
};