常系数齐次线性递推的黑科技及其证明

之前在多项式里面讲过这个...不过感觉很不严谨啊。现在我们就来严谨的说明一波这个科技到底是怎么来的。

常系数齐次线性递推是指这样一个问题,给你一个数k,接着对于i=1,2,...,k,给出ai,代表递推的系数。再对于i=0,1,2,...,k−1,给出fi作为初始值,对于i≥k,数列f满足:

fi=∑j=1kaj∗fi−j

最后给你一个数n,需要求出fn。n的范围很大。

在k比较小的时候,显然可以直接用矩阵快速幂来解决,转移矩阵如下:

A=[0100⋯00010⋯00001⋯00000⋯0⋮⋮⋮⋮⋱⋮a1a2a3a4⋯ak]

如此一来,如果向量v=(fi,fi+1,⋯,fi+k−1)T,那么Av=(fi+1,fi+2,⋯,fi+k)T,于是只要计算An即可,复杂度O(k3log⁡n)。

但是如果k=103,甚至k=105,那么就无法使用矩阵快速幂了。我们来思考一下怎么样让线性递推更快。

为了方便,我们设向量v^=(f0,f1,...,fk−1)。

我们考虑假设我们能够构造一个以矩阵为参数的多项式g,满足:

∑i=0kgiAi=0

那么显然我们可以把An用A0,A1,...,Ak−1线性表示出来——我们只需要计算Anmodg即可,此处的取模应为多项式取模,假设取模以后得到的多项式为r,于是我们有:

An=∑i=0k−1riAi

但是实际上我们不需要保留矩阵,我们只是想知道(Anv^)0,因此这个式子实际上可以转化为:

(Anv^)0=∑i=0k−1ri(Aiv^)0

而对于任意的i,我们有(Aiv^)0=fi,因此:

fn=∑i=0k−1rifi

于是我们只要求xnmodg,再将前k项已知的值代入即可计算,复杂度O(klog⁡klog⁡n)。

说得好听,那g到底该怎么求呢?

前方大量线性代数和数学证明出没。

为了方便,现在起我们在没有说明的情况下,默认矩阵的规模为n×n。

引理1:对于任意一个满秩的矩阵A,复数域内恰好存在n个数λ,满足det(λI−A)=0。

证明:恰好存在n个λ是很容易证明的,考虑将det(λI−A)看做一个以λ为参数的多项式,显然它是一个n+1次多项式,那么它在复数域内应该有n个根,同时要注意这里可能会有重根,但实际上这是没有关系的,不过我感觉具体的证明有点繁琐,所以就不放在这里了。一个比较直观的理解是你可以对输入进行很小的随机扰动使其没有重根,这不影响我们接下来的证明。

upd:严谨的证明请看这里 (opens new window)。

引理2:对于某个满足det(λI−A)=0的λ,存在一个对应的非零向量v,使得(λI−A)v=0。并且对于所有n个λ,他们对应的n个v是线性无关的。

证明:我们先来证明这样的v是存在的。我们求v的过程其实就等价于解(λI−A)v=0这个线性方程组,然而这个矩阵的行列式为0因此它是不满秩的,这意味着这个方程一定存在多解。如此一来,零向量就不可能是它的唯一解,因此我们一定可以找到这样的一个非零向量v。

接着,我们再来证明任意一对v不可能线性相关,注意这不代表n个v是线性无关的,因此这只是一个子问题。采用反证法,我们假设存在λ1,λ2,使得(λ1I−A)v=0且(λ2I−A)v=0,则我们有:

(λ1I−A)v−(λ2I−A)v=0

等价于:

(λ1I−λ2I)v=(λ1−λ2)Iv=0

因为λ1≠λ2,因此在两边除以λ1−λ2,得到:

Iv=0

而Iv=v,这就推出了v是零向量。然而v不是零向量,于是这就与前提矛盾,于是得证。

最后来证明n个v都是线性无关的。采用反证法,不失一般性,我们假设:

vn=∑i=1n−1kivi

其中ki为某特定常数。因为任意(λI−A)v=0,于是我们有:

(λnI−A)vn−∑i=1n−1((λiI−A)kivi)=0

再推导一下:

λnIvn−∑i=1n−1(λiIkivi)+A(∑i=1n−1kivi)−Avn=0

由于vn=∑i=1n−1kivi,后两项可以抵消,再将第一项转化一下,得:

∑i=1n−1(λnIkivi)−∑i=1n−1(λiIkivi)=∑i=1n−1((λn−λi)Ikivi)=0

由于Iv=v,因此我们消去单位矩阵,得到:

∑i=1n−1((λn−λi)kivi)=0

于是我们得到了前n−1个向量也是线性相关的,以此类推,我们可以推到前2个向量也是线性相关的,然而这和我们之前证明出的结论矛盾,于是推翻了假设。我们证明了n个v是线性无关的。

引理3:∏i=1n(λiI−A)=0。

证明:我们不妨证明这个矩阵乘以任意向量都为0,这和它是零矩阵是等价的(比较显然)。我们已知n个vi都是线性无关的,那么对于任意向量v^,它一定可以表示为∑i=1nkivi,其中ki表示某一特定的常数。于是我们得到:

(∏i=1n(λiI−A))v^=∑i=1n(ki(∏i=1n(λiI−A))vi)

我们只需要证明任意(∏i=1n(λiI−A))v=0即可,考虑这个∏的顺序是可以交换的,因为(λ1I−A)(λ2I−A)=λ1λ2I−λ1A−λ2A+A2=(λ2I−A)(λ1I−A)。那么不妨考虑将与v对应的(λI−A)放到最后,先与v相乘,于是就得到了零向量,零向量乘以任意矩阵都会得到零向量,于是就证明了引理。

通过这三个引理,我们再进行深一步的思考。其实我们我们已经得到了一个满足条件的g(把A看作未知数):

∏i=1n(λiI−A)

然而直接求解需要我们求出所有的特征值λ,这很不可行。不妨来考虑这个多项式的下面两个特点:

1、这是一个n+1次的多项式。

2、最高次的系数为1,并且可以很方便的求出其所有零点,即λ1、λ2、⋯、λn。

同时我们可以知道我们只要找到一个满足上述条件的多项式,则这个多项式一定和∏i=1n(λiI−A)相等。

仔细思考一下有没有什么之前提到的多项式满足这个条件。

有没有电光一闪的感觉?

det(λI−A)

没错就是它,次数界相同,零点也完全相同,只不过未知数换成了λ而已。

至此我们完成了我们的证明,det(λI−A)就是合法的满足g(A)=0的多项式g。

最后我们来回头解决线性递推问题。考虑手膜λI−A的行列式多项式:

λI−A=[λ−100⋯00λ−10⋯000λ−1⋯0000λ⋯0⋮⋮⋮⋮⋱⋮−a1−a2−a3−a4⋯λ−ak]

显然只有最后一行需要变换,稍微手推一下,发现最后一行最后一个数最终就是:

λ−∑i=1kaiλk−i

接着需要乘以λk−1得到最终的行列式,就是:

λk−∑i=1kai∗λi−1

其实结论还是非常简单的...

参考链接:shadowice1984的博客 (opens new window) 感谢这篇文章的作者让我了解了这个黑科技。