有时候,你需要用计算机计算阶乘函数 n ! n! n!。事实上它等于前 n n n个正整数的乘积。当你的算法里有这样的函数的时候,你似乎找不到比写一个for循环更合适的方法了。可是我们很容易就发现,这个for循环的次数很可能会很大。这就导致了算法的耗时不稳定性。虽然 n n n很小的时候算起来很快,但是对于稍大一点的 n n n就没这么理想了。这时候如果有人告诉你这样的一份公式:
n ! = ∫ 0 + ∞ e − t t n d t n!=\int_0^{+\infty}e^{-t}t^n{\rm d}t n!=∫0+∞e−ttndt
你会不会稍微开心一点?我通常会比较开心,因为我的程序一般不需要把 n ! n! n!计算的那么准确。如果我只需要四到六位有效数字,那无论这个 n n n有多大,我都可以用一个固定长度的for循环来计算结果。这保证了时间上的稳定性,每次计算的时间一定不会太长了。
如果你的算法中的 n n n要去适应非整数的情况呢,而其中又包含一个计算 n ! n! n!的函数怎么办?是不是看到上面的公式就更开心了,哈哈哈。
事实上,上面公式的右边就是欧拉发明的一种叫做伽马函数的东东。写成这样 Γ ( z ) \Gamma(z) Γ(z)的伽马函数的定义域是所有的复数,咳咳,但是不包括零和所有的负整数啊。不过那个积分只能在 z z z的实部大于零的时候才能用啊。完整版的定义长下面这样:
if ℜ z > 0 \Re z>0 ℜz>0
Γ ( z ) = ∫ 0 + ∞ e − t t z − 1 d t \Gamma(z)=\int_0^{+\infty}e^{-t}t^{z-1}{\rm d}t Γ(z)=∫0+∞e−ttz−1dt
else
Γ ( z ) = π sin ( π z ) Γ ( 1 − z ) \Gamma(z)=\frac{\pi}{\sin(\pi z)\Gamma(1-z)} Γ(z)=sin(πz)Γ(1−z)π
后面这半个定义叫做欧拉反射公式啊哈哈哈。这就把阶乘这个函数扩展到复平面上的绝大多数点上了。 n n n取自然数的情况反而成了特例:
n ! = Γ ( n + 1 ) n!=\Gamma(n+1) n!=Γ(n+1)
它还有个很有用的倒数函数长这样:
1 Γ ( x ) = x e γ x ∏ n = 1 + ∞ ( 1 + x n ) e − x / n \frac{1}{\Gamma(x)}=xe^{\gamma x}\prod_{n=1}^{+\infty}\left(1+\frac{x}{n}\right)e^{-x/n} Γ(x)1=xeγxn=1∏+∞(1+nx)e−x/n
那个常数 γ ≈ 0.5772 \gamma\approx0.5772 γ≈0.5772先别它。你把这个倒数分两次弄到欧拉反射公式里面去,就得到一个事情:
sin ( π x ) = π x ∏ n = 1 + ∞ ( 1 − x 2 n 2 ) \sin(\pi x)=\pi x\prod_{n=1}^{+\infty}\left(1-\frac{x^2}{n^2}\right) sin(πx)=πxn=1∏+∞(1−n2x2)
反正我是没看出来这个公式对程序员有什么用。但是吧,我们把它取对数再求个导函数:
π cot ( π x ) = d d t ln [ sin ( π x ) ] = lim n → + ∞ ∑ k = − n + n 1 x − k \pi\cot(\pi x)=\frac{{\rm d}}{{\rm d}t}\ln[\sin(\pi x)]=\lim_{n\to+\infty}\sum_{k=-n}^{+n}\frac{1}{x-k} πcot(πx)=dtdln[sin(πx)]=n→+∞limk=−n∑+nx−k1
是不是看出来有点用了?如果你遇到右边的有限个那样的项相加的算法而项数又很多,不要犹豫啦用左边的余切一算就好了哈哈哈!再赠送一个:
π sin ( π x ) = π [ cot ( π x 2 ) − cot ( π x ) ] = lim n → + ∞ ∑ k = − n + n ( − 1 ) k x − k \frac{\pi}{\sin(\pi x)}=\pi\left[\cot\left(\frac{\pi x}{2}\right)-\cot(\pi x)\right]=\lim_{n\to+\infty}\sum_{k=-n}^{+n}\frac{(-1)^k}{x-k} sin(πx)π=π[cot(2πx)−cot(πx)]=n→+∞limk=−n∑+nx−k(−1)k
也有点用吧!把这俩有点用的公式中的角度 π x \pi x πx增加或减少90度试试,变成这样:
π tan ( π x ) = lim n → + ∞ ∑ k = − n + n 1 k + 0.5 − x \pi\tan(\pi x)=\lim_{n\to+\infty}\sum_{k=-n}^{+n}\frac{1}{k+0.5-x} πtan(πx)=n→+∞limk=−n∑+nk+0.5−x1
π cos ( π x ) = lim n → + ∞ ∑ k = − n + n ( − 1 ) k k + 0.5 + x \frac{\pi}{\cos(\pi x)}=\lim_{n\to+\infty}\sum_{k=-n}^{+n}\frac{(-1)^k}{k+0.5+x} cos(πx)π=n→+∞limk=−n∑+nk+0.5+x(−1)k
记得把右边的算法优化到左边啊!最后再来一个,把那个余切求个导:
π 2 sin 2 ( π x ) = ∑ n = − ∞ + ∞ 1 ( x + n ) 2 \frac{\pi^2}{\sin^2(\pi x)}=\sum_{n=-\infty}^{+\infty}\frac{1}{(x+n)^2} sin2(πx)π2=n=−∞∑+∞(x+n)21
好吧,把那个常数 γ ≈ 0.5772 \gamma\approx0.5772 γ≈0.5772拽回来给大家介绍一下,它叫欧拉常数!!!