由qr.Q()神秘化:“紧凑”形式的正交矩阵是什么?

R有一个qr()函数,它使用LINPACK或LAPACK执行QR分解(在我的经验中,后者比快5%)。返回的主要对象是在上三角矩阵R(即R = qr [upper.tri(qr)])中包含的矩阵“qr”)。到现在为止还挺好。 qr的下三角形部分包含Q“紧凑形式”。可以使用qr.Q()从qr分解中提取Q。我想找到qr.Q()的逆。换句话说,我有Q和R,并希望把它们放在一个“qr”对象中。 R是微不足道的,但Q不是。目标是适用于qr.solve(),这比大型系统上的solve()要快得多。
介绍

默认情况下,R使用LINPACK dqrdc例程,或者在指定时使用LAPACK DGEQP3程序来计算QR分解。这两个例程都使用Householder反射计算分解。 m×n矩阵A被分解为m×n经济尺寸正交矩阵(Q)和n×n上三角矩阵(R),其中A = QR,其中Q可以通过t家庭反射矩阵的乘积来计算,t是较小的的m-1和n:Q = H1H2 … Ht。

每个反射矩阵H i可以由长度(m-1)向量表示。例如,H1需要用于紧凑存储的长度为m的向量。该向量的所有除一个条目都放置在输入矩阵的下三角形的第一列中(对角线由R因子使用)。因此,每个反射需要一个标量的存储,并且由辅助向量(在R的qr的结果中称为$ qraux)提供。

所使用的紧凑表示在LINPACK和LAPACK例程之间是不同的。

LINPACK方式

一个Householder反射计算为Hi = I – viviT / pi,其中I是单位矩阵,pi是$ qraux中的相应条目,vi如下:

> vi [1..i-1] = 0,
> vi [i] = pi
> vi [i 1:m] = A [i 1..m,i](即,调用qr后A的下三角形的列)

LINPACK示例

让我们通过example from the QR decomposition article维基百科在R.

正在分解的矩阵是

> A <- matrix(c(12, 6, -4, -51, 167, 24, 4, -68, -41), nrow=3)
> A
     [,1] [,2] [,3]
[1,]   12  -51    4
[2,]    6  167  -68
[3,]   -4   24  -41

我们做分解,结果最相关的部分如下所示:

> Aqr = qr(A)
> Aqr
$qr
            [,1]         [,2] [,3]
[1,] -14.0000000  -21.0000000   14
[2,]   0.4285714 -175.0000000   70
[3,]  -0.2857143    0.1107692  -35

[snip...]

$qraux
[1]  1.857143  1.993846 35.000000

[snip...]

通过计算两个Householder反射并将它们乘以A得到R,这个分解完成了(在封面下)。我们现在将从$ qr中的信息重新创建反射。

> p = Aqr$qraux   # for convenience
> v1 <- matrix(c(p[1], Aqr$qr[2:3,1]))
> v1
           [,1]
[1,]  1.8571429
[2,]  0.4285714
[3,] -0.2857143

> v2 <- matrix(c(0, p[2], Aqr$qr[3,2]))
> v2
          [,1]
[1,] 0.0000000
[2,] 1.9938462
[3,] 0.1107692

> I = diag(3)   # identity matrix
> H1 = I - v1 %*% t(v1)/p[1]   # I - v1*v1^T/p[1]
> H2 = I - v2 %*% t(v2)/p[2]   # I - v2*v2^T/p[2]

> Q = H1 %*% H2
> Q
           [,1]       [,2]        [,3]
[1,] -0.8571429  0.3942857  0.33142857
[2,] -0.4285714 -0.9028571 -0.03428571
[3,]  0.2857143 -0.1714286  0.94285714

现在我们来验证上面的Q是否正确:

> qr.Q(Aqr)
           [,1]       [,2]        [,3]
[1,] -0.8571429  0.3942857  0.33142857
[2,] -0.4285714 -0.9028571 -0.03428571
[3,]  0.2857143 -0.1714286  0.94285714

看起来不错!我们也可以验证QR等于A.

> R = qr.R(Aqr)   # extract R from Aqr$qr
> Q %*% R
     [,1] [,2] [,3]
[1,]   12  -51    4
[2,]    6  167  -68
[3,]   -4   24  -41

LAPACK方式

Householder反射计算为Hi = I-piviviT,其中I是单位矩阵,pi是$ qraux中的相应条目,vi如下:

> vi [1..i-1] = 0,
> vi [i] = 1
> vi [i 1:m] = A [i 1..m,i](即,调用qr后A的下三角形的列)

在R中使用LAPACK例程时,还有另一个扭曲:使用列旋转,因此分解解决了一个不同的相关问题:AP = QR,其中P是permutation matrix

LAPACK示例

此部分与以前相同。

> A <- matrix(c(12, 6, -4, -51, 167, 24, 4, -68, -41), nrow=3)
> Bqr = qr(A, LAPACK=TRUE)
> Bqr
$qr
            [,1]        [,2]       [,3]
[1,] 176.2554964 -71.1694118   1.668033
[2,]  -0.7348557  35.4388886  -2.180855
[3,]  -0.1056080   0.6859203 -13.728129

[snip...]

$qraux
[1] 1.289353 1.360094 0.000000

$pivot
[1] 2 3 1

attr(,"useLAPACK")
[1] TRUE

[snip...]

注意$ pivot字段;我们会回来现在我们从Aqr的信息生成Q。

> p = Bqr$qraux   # for convenience
> v1 = matrix(c(1, Bqr$qr[2:3,1]))
> v1
           [,1]
[1,]  1.0000000
[2,] -0.7348557
[3,] -0.1056080


> v2 = matrix(c(0, 1, Bqr$qr[3,2]))
> v2
          [,1]
[1,] 0.0000000
[2,] 1.0000000
[3,] 0.6859203


> H1 = I - p[1]*v1 %*% t(v1)   # I - p[1]*v1*v1^T
> H2 = I - p[2]*v2 %*% t(v2)   # I - p[2]*v2*v2^T
> Q = H1 %*% H2
           [,1]        [,2]       [,3]
[1,] -0.2893527 -0.46821615 -0.8348944
[2,]  0.9474882 -0.01602261 -0.3193891
[3,]  0.1361660 -0.88346868  0.4482655

再次,上面计算的Q与R提供的Q一致。

> qr.Q(Bqr)
           [,1]        [,2]       [,3]
[1,] -0.2893527 -0.46821615 -0.8348944
[2,]  0.9474882 -0.01602261 -0.3193891
[3,]  0.1361660 -0.88346868  0.4482655

最后,我们来计算QR。

> R = qr.R(Bqr)
> Q %*% R
     [,1] [,2] [,3]
[1,]  -51    4   12
[2,]  167  -68    6
[3,]   24  -41   -4

注意区别? QR为A,其列排列为Bqr $ pivot以上的顺序。

http://stackoverflow.com/questions/3031215/mystified-by-qr-q-what-is-an-orthonormal-matrix-in-compact-form

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:由qr.Q()神秘化:“紧凑”形式的正交矩阵是什么?