距离上次更新已经 2200 天了,文章内容可能已经过时。

课程主页:https://graphics.stanford.edu/courses/cs205a-13-fall/schedule.html

这次回顾第四讲,这一讲结束了LU分解的内容,介绍敏感性和病态性。

Chapter 3 设计和分析线性系统

回归

假设我们的函数有如下形式

f(x)=i=1maifi(x)

如果我们有m个观测值,那么可以得到如下线性系统:

(f1(x(1))f2(x(1))fm(x(1))f1(x(2))f2(x(2))fm(x(2))f1(x(m))f2(x(m))fm(x(m)))(a1a2am)=(y(1)y(2)y(m))

我们的任务是求解(a1,,am)T,在继续之前,来看两个具体例子:

多项式回归

如果

f(x)=i=0naixi

那么此时称为多项式回归,对应的线性系统为:

(1x(1)(x(1))2(x(1))n1x(2)(x(2))2(x(2))n1x(n)(x(n))2(x(n))n)(a1a2an)=(y(1)y(2)y(n))

Mini-Fourier

另一种常见的形式为

f(x)=acos(x+ϕ)

最小二乘法

考虑上述问题,我们自然希望

Axb

这等价于

minx||Axb||

最小化上述问题等价于最小化

g(x)=||Axb||2

化简可得

g(x)=||Axb||2=(Axb)T(Axb)=xTATAxbTAxxTATb+bTb=xTATAx2xTATb+bTb

对上式关于x求梯度可得

xg(x)=x(xTATAx2xTATb+bTb)=2ATAx2ATb

令上式为0可得

ATAx=ATb

该方程被称为正规方程,下面对ATA这个矩阵做更多的讨论。

(半)正定矩阵和Cholesky分解

讨论之前先介绍一些基本概念:

对称性

BBT=B

显然ATA是对称矩阵。

(半)正定性

BxxTBx0Bx0xTBx>0

注意到

xTATAx=(Ax)T(Ax)=||Ax||220

所以ATA是半正定矩阵,事实上,如果A可逆,那么ATA是正定矩阵。

有了这些准备工作,考虑正定对称系统Cx=d的求解,假设CRn×nC是对称矩阵,将C写为分块形式:

C=(c11vTvC~)

其中vRn1,C~R(n1)×(n1)。由C的定义,不难得到:

e1TCe=(100)(c11vTvC~)(100)=c11>0

其中最后一个不等号是因为正定性。回顾高斯消元法,这说明我们不需要对第一列选主元,那么使用高斯消元法,我们可以找到forward substitution矩阵E,其中

E=(1/c110TrI(n1)×(n1))

使得

EC=(c11vT/c110D)

其中DR(n1)×(n1)。接着,由C的对称性,考虑使用列变换:

ECET=(c11vT/c110D)(1/c11r0TI(n1)×(n1))=(100D)

不难发现D也是正定对称矩阵,对D重复这个过程,最终不难得到

(Ek...E1)C(Ek...E1)T=IC=(Ek...E1)1((Ek...E1)1)T

L=(Ek...E1)1

那么

C=LLT

注意到上述L并不唯一——对于正交矩阵Q,我们有

C=LQQTLT=(LQ)(LQ)T

所以上述分解有无数种形式,特别的,如果我们取L为下三角矩阵,那么

C=LLT

被称为Cholesky分解,下面推导Cholesky分解的具体形式。

由定义,我们有

(L1100L21L2200Ln1Ln2Lnn)(L11L21Ln10L22L2n00Lnn)=C

考虑Cij,我们有

Cij=k=1jLikLkj=k=1jLikLjk,ji

所以

Lij=(Cijk=1j1LikLjk)/Ljj,j<i

以及

Lii=Ciik=1i1Lik2,j=i

所以,对i,j做循环即可计算得到Lij,伪代码如下:

cpp
// Takes as input an n-by -n matrix A[i,j]
// Edits A in place to obtain the Cholesky factorization in its lower triangle
for i from 1 to n {
    // Back - substitute to find l_i
    for j from 1 to i -1 { // element j of l_i
        sum = 0;
        for k from 1 to j -1
    		sum += A[i,k]*A[j,k];
    	A[i,j] = (A[i,j]-sum )/A[j,j];
    }
    // Apply the formula for l_kk
    normSquared = 0
    for k from 1 to i -1
    	normSquared += A[i,k ]^2;
    A[i,i] = sqrt (A[i,i] - normSquared );
}