Householder Triangularization
To code the Householder algorithm
> library(Matrix) > set.seed(12345) > A <- matrix(runif(16), nrow = 4, ncol = 4) > Y <- A > m <- dim(A)[1] > n <- dim(A)[2] > k <- 1 > norm2 <- function(x) { + sqrt(sum(x^2)) + } > Q <- matrix(data = 0, nrow = 16, ncol = 4) > Q[seq(1, 16, 4), 1] <- 1 > Q[seq(2, 16, 4), 2] <- 1 > Q[seq(3, 16, 4), 3] <- 1 > Q[seq(4, 16, 4), 4] <- 1 > for (k in 1:n) { + Qt <- diag(4) + x <- A[k:m, k] + e1 <- c(1, rep(0, (length(x) - 1))) + Vk <- sign(x[1]) * norm2(x) * e1 + x + Vk <- Vk/norm2(Vk) + A[k:m, k:n] <- A[k:m, k:n] - 2 * Vk %*% t(Vk) %*% A[k:m, + k:n] + Qt[k:m, k:n] <- diag(length(x)) - 2 * Vk %*% t(Vk) + Q[(4 * k - 3):(4 * k), ] <- Qt + } |
R - the upper triangular matrix
> print(round(A, 8)) [,1] [,2] [,3] [,4] [1,] -1.628187 -0.7206857 -0.9536335 -0.7608957 [2,] 0.000000 0.2857674 -0.3555428 0.5260942 [3,] 0.000000 0.0000000 0.7054906 0.1160929 [4,] 0.000000 0.0000000 0.0000000 0.1973830 |
- How to compute Q
> Qf <- Q[1:4, ] %*% Q[5:8, ] %*% Q[9:12, ] %*% Q[13:16, ] > print(round(Qf, 8)) [,1] [,2] [,3] [,4] [1,] -0.4427649 0.48076393 0.6752776 0.3417974 [2,] -0.5378825 -0.77430980 0.2856081 -0.1719148 [3,] -0.4673803 -0.04107847 -0.6035221 0.6446932 [4,] -0.5442401 0.40941780 -0.3133516 -0.6618085 |
Verifty QR = A
> print(round(Qf %*% A, 8)) [,1] [,2] [,3] [,4] [1,] 0.7209039 0.4564810 0.72770525 0.73568495 [2,] 0.8757732 0.1663718 0.98973694 0.00113659 [3,] 0.7609823 0.3250954 0.03453544 0.39120334 [4,] 0.8861246 0.5092243 0.15237349 0.46249465 > print(round(Y, 8)) [,1] [,2] [,3] [,4] [1,] 0.7209039 0.4564810 0.72770525 0.73568495 [2,] 0.8757732 0.1663718 0.98973694 0.00113659 [3,] 0.7609823 0.3250954 0.03453544 0.39120334 [4,] 0.8861246 0.5092243 0.15237349 0.46249465 |
Q contains Qn … Q2, Q1 Q*A = R Q* = Qn … Q2, Q1
> for (k in n:1) { + w <- as.vector(V[[3]]) + w %*% t(w) %*% c(1, 0) + } |