Введение
R использует LINPACK dqrdc
по умолчанию или LAPACK DGEQP3
подпрограмма, если указана, для вычисления разложения QR.Обе процедуры вычисляют разложение, используя отражения Домохозяина.Матрица mxn A раскладывается на ортогональную матрицу mxn экономичного размера (Q) и верхнюю треугольную матрицу nxn (R) как A = QR, где Q может быть вычислено как произведение t матриц отражения Домохозяина, причем t является наименьшимm-1 и n: Q = H 1 H 2 ... H t .
Каждая матрица отражений H i может быть представлен вектором длины (m-i + 1).Например, H 1 требует вектора длины m для компактного хранения.Все записи этого вектора, кроме одной, помещаются в первый столбец нижнего треугольника входной матрицы (диагональ используется коэффициентом R).Следовательно, каждому отражению требуется еще один скаляр памяти, и это обеспечивается вспомогательным вектором (называемым $qraux
в результате R * qr
).
Используемое компактное представление отличается междупроцедуры LINPACK и LAPACK.
Путь LINPACK
Отражение домохозяина вычисляется как H i = I - v i v i T / p i , где I - единичная матрица, p i - соответствующая запись в $qraux
, а v i выглядит следующим образом:
- v i [1..i-1] = 0,
- v i [i] = p i
- v i [i + 1: m] = A [i + 1..m, i] (т.е., столбец нижнего треугольника A после вызова
qr
)
Пример LINPACK
Давайте рассмотрим пример из статьи QR-декомпозиции в Википедиив 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...]
Это разложение было выполнено (под одеялом) путем вычисления двух отражений Домохозяина и умножения их на 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
Отражение домохозяина вычисляется как H i = I - p i v i v i T , где I - единичная матрица, p i - соответствующая запись в $qraux
и v i выглядит следующим образом:
- v i [1..i-1] = 0,
- v i [i] = 1
- v i [i + 1: m] = A [i + 1..m, i] (то есть столбецнижний треугольник A после вызова
qr
)
При использовании подпрограммы LAPACK в R используется другой поворот: используется поворот столбца, поэтому декомпозиция решает другую связанную проблему: AP =QR, где P - матрица перестановок .
Пример 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...]
Обратите внимание на *Поле 1134 *;мы вернемся к этому.Теперь мы генерируем Q из информации Aqr
.
> 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
выше.