| Title: | Fast QR Decomposition and Update |
|---|---|
| Description: | Efficient algorithms for performing, updating, and removing rows or columns from the QR decomposition, R decomposition, or the inverse of the R decomposition of a matrix as rows or columns are added or removed. It also includes functions for solving linear systems of equations, normal equations for linear regression models, and normal equations for linear regression with a RIDGE penalty. For a detailed introduction to these methods, the monograph Matrix Computations (2013, <doi:10.1007/978-3-319-05089-8>) for complete introduction to the methods. |
| Authors: | Mauro Bernardi [aut, cre], Claudio Busatto [aut], Manuela Cattelan [aut] |
| Maintainer: | Mauro Bernardi <[email protected]> |
| License: | GPL (>= 2) |
| Version: | 1.1.4 |
| Built: | 2026-05-24 08:37:38 UTC |
| Source: | https://github.com/cran/fastQR |
qr provides the QR factorization of the matrix with . The QR factorization of the matrix returns the matrices and such that . See Golub and Van Loan (2013) for further details on the method.
X |
a |
type |
either "givens" or "householder". |
nb |
integer. Defines the number of block in the block recursive QR decomposition. See Golud and van Loan (2013). |
complete |
logical expression of length 1. Indicates whether an arbitrary orthogonal completion of the |
A named list containing
the Q matrix.
the R matrix.
Golub GH, Van Loan CF (2013). Matrix computations, Johns Hopkins Studies in the Mathematical Sciences, Fourth edition. Johns Hopkins University Press, Baltimore, MD. ISBN 978-1-4214-0794-4; 1-4214-0794-9; 978-1-4214-0859-0.
Björck Å (2015). Numerical methods in matrix computations, volume 59 of Texts in Applied Mathematics. Springer, Cham. ISBN 978-3-319-05088-1; 978-3-319-05098-8. doi:10.1007/978-3-319-05089-8.
Björck Å (2024). Numerical Methods for Least Squares Problems: Second Edition. Society for Industrial and Applied Mathematics, Philadelphia, PA. doi:10.1137/1.9781611977950. https://doi.org/10.1137/1.9781611977950.
Bernardi M, Busatto C, Cattelan M (2024). “Fast QR updating methods for statistical applications.” 2412.05905, https://arxiv.org/abs/2412.05905.
## generate sample data set.seed(1234) n <- 10 p <- 6 X <- matrix(rnorm(n * p, 1), n, p) ## QR factorization via Givens rotation output <- qr(X, type = "givens", complete = TRUE) Q <- output$Q R <- output$R ## check round(Q %*% R - X, 5) max(abs(Q %*% R - X)) ## QR factorization via Householder rotation output <- qr(X, type = "householder", complete = TRUE) Q <- output$Q R <- output$R ## check round(Q %*% R - X, 5) max(abs(Q %*% R - X))## generate sample data set.seed(1234) n <- 10 p <- 6 X <- matrix(rnorm(n * p, 1), n, p) ## QR factorization via Givens rotation output <- qr(X, type = "givens", complete = TRUE) Q <- output$Q R <- output$R ## check round(Q %*% R - X, 5) max(abs(Q %*% R - X)) ## QR factorization via Householder rotation output <- qr(X, type = "householder", complete = TRUE) Q <- output$Q R <- output$R ## check round(Q %*% R - X, 5) max(abs(Q %*% R - X))
Computes the coefficient vector solving the
least-squares problem ,
using a QR decomposition stored in compact (Householder) form.
qr_coef(qr, tau, y, pivot = NULL, rank = NULL)qr_coef(qr, tau, y, pivot = NULL, rank = NULL)
qr |
numeric matrix containing the QR decomposition of |
tau |
numeric vector of Householder coefficients. |
y |
numeric response vector of length |
pivot |
optional integer vector of length |
rank |
optional integer specifying the numerical rank of |
The coefficients are obtained by first computing
and then solving the resulting upper-triangular system involving
the matrix . The orthogonal matrix is never formed
explicitly.
a numeric vector of regression coefficients.
set.seed(1) n <- 10; p <- 4 X <- matrix(rnorm(n * p), n, p) y <- rnorm(n) qr_res <- fastQR::qr_fast(X) coef1 <- fastQR::qr_coef(qr = qr_res$qr, tau = qr_res$qraux, y = y) ## reference computation coef2 <- base::qr.coef(base::qr(X), y) max(abs(coef1 - coef2))set.seed(1) n <- 10; p <- 4 X <- matrix(rnorm(n * p), n, p) y <- rnorm(n) qr_res <- fastQR::qr_fast(X) coef1 <- fastQR::qr_coef(qr = qr_res$qr, tau = qr_res$qraux, y = y) ## reference computation coef2 <- base::qr.coef(base::qr(X), y) max(abs(coef1 - coef2))
qr_fast provides the fast QR factorization of the matrix with . The full QR factorization of the matrix returns the matrices and the upper triangular matrix such that . See Golub and Van Loan (2013) for further details on the method.
qr_fast(X, tol = NULL, pivot = NULL)qr_fast(X, tol = NULL, pivot = NULL)
X |
a |
tol |
the tolerance for detecting linear dependencies in the columns of |
pivot |
a logical value indicating whether to pivot the columns of |
The QR decomposition plays an important role in many statistical techniques. In particular it can be used to solve the equation for given matrix and vectors and . It is useful for computing regression coefficients and in applying the Newton-Raphson algorithm.
A named list containing
a matrix with the same dimensions as . The upper triangle contains the of the decomposition and the lower triangle contains information on the of the decomposition (stored in compact form).
a vector of length ncol(x) which contains additional information on .
the rank of as computed by the decomposition.
information on the pivoting strategy used during the decomposition.
a boolean variable returning one if the pivoting has been performed and zero otherwise.
Golub GH, Van Loan CF (2013). Matrix computations, Johns Hopkins Studies in the Mathematical Sciences, Fourth edition. Johns Hopkins University Press, Baltimore, MD. ISBN 978-1-4214-0794-4; 1-4214-0794-9; 978-1-4214-0859-0.
Björck Å (2015). Numerical methods in matrix computations, volume 59 of Texts in Applied Mathematics. Springer, Cham. ISBN 978-3-319-05088-1; 978-3-319-05098-8. doi:10.1007/978-3-319-05089-8.
Björck Å (2024). Numerical Methods for Least Squares Problems: Second Edition. Society for Industrial and Applied Mathematics, Philadelphia, PA. doi:10.1137/1.9781611977950. https://doi.org/10.1137/1.9781611977950.
Bernardi M, Busatto C, Cattelan M (2024). “Fast QR updating methods for statistical applications.” 2412.05905, https://arxiv.org/abs/2412.05905.
## generate sample data set.seed(1234) n <- 12 p <- 5 X <- matrix(rnorm(n * p), n, p) ## get the full QR decomposition with pivot qr_res <- fastQR::qr_fast(X = X, tol = sqrt(.Machine$double.eps), pivot = TRUE) ## reconstruct the reduced Q and R matrices ## reduced Q matrix Q1 <- qr_Q(qr = qr_res$qr, tau = qr_res$qraux, rank = qr_res$rank, complete = FALSE) Q1 ## check the Q matrix (orthogonality) max(abs(crossprod(Q1)-diag(1, p))) ## complete Q matrix Q2 <- qr_Q(qr = qr_res$qr, tau = qr_res$qraux, rank = NULL, complete = TRUE) Q2 ## check the Q matrix (orthogonality) max(abs(crossprod(Q2)-diag(1, n))) ## reduced R matrix R1 <- qr_R(qr = qr_res$qr, rank = NULL, complete = FALSE) ## check that X^TX = R^TR ## get the permutation matrix P <- qr_pivot2perm(pivot = qr_res$pivot) max(abs(crossprod(R1 %*% P) - crossprod(X))) max(abs(crossprod(R1) - crossprod(X %*% t(P)))) ## complete R matrix R2 <- qr_R(qr = qr_res$qr, rank = NULL, complete = TRUE) ## check that X^TX = R^TR ## get the permutation matrix P <- qr_pivot2perm(pivot = qr_res$pivot) max(abs(crossprod(R2 %*% P) - crossprod(X))) max(abs(crossprod(R2) - crossprod(X %*% t(P)))) ## check that X = Q %*% R max(abs(Q2 %*% R2 %*% P - X)) max(abs(Q1 %*% R1 %*% P - X)) ## create data: n > p set.seed(1234) n <- 120 p <- 75 X <- matrix(rnorm(n * p), n, p) ## get the full QR decomposition with pivot qr_res <- fastQR::qr_fast(X = X, pivot = FALSE) ## reconstruct the reduced Q and R matrices ## reduced Q matrix Q1 <- qr_Q(qr = qr_res$qr, tau = qr_res$qraux, rank = p, complete = FALSE) ## check the Q matrix (orthogonality) max(abs(crossprod(Q1)-diag(1, p))) ## complete Q matrix Q2 <- qr_Q(qr = qr_res$qr, tau = qr_res$qraux, rank = NULL, complete = TRUE) ## check the Q matrix (orthogonality) max(abs(crossprod(Q2)-diag(1, n))) ## reduced R matrix R1 <- qr_R(qr = qr_res$qr, rank = NULL, complete = FALSE) ## check that X^TX = R^TR max(abs(crossprod(R1) - crossprod(X))) ## complete R matrix R2 <- qr_R(qr = qr_res$qr, rank = NULL, complete = TRUE) ## check that X^TX = R^TR max(abs(crossprod(R2) - crossprod(X))) ## check that X^TX = R^TR max(abs(crossprod(R2) - crossprod(X))) max(abs(crossprod(R2) - crossprod(X))) max(abs(crossprod(R1) - crossprod(X))) # check that X = Q %*% R max(abs(Q2 %*% R2 - X)) max(abs(Q1 %*% R1 - X))## generate sample data set.seed(1234) n <- 12 p <- 5 X <- matrix(rnorm(n * p), n, p) ## get the full QR decomposition with pivot qr_res <- fastQR::qr_fast(X = X, tol = sqrt(.Machine$double.eps), pivot = TRUE) ## reconstruct the reduced Q and R matrices ## reduced Q matrix Q1 <- qr_Q(qr = qr_res$qr, tau = qr_res$qraux, rank = qr_res$rank, complete = FALSE) Q1 ## check the Q matrix (orthogonality) max(abs(crossprod(Q1)-diag(1, p))) ## complete Q matrix Q2 <- qr_Q(qr = qr_res$qr, tau = qr_res$qraux, rank = NULL, complete = TRUE) Q2 ## check the Q matrix (orthogonality) max(abs(crossprod(Q2)-diag(1, n))) ## reduced R matrix R1 <- qr_R(qr = qr_res$qr, rank = NULL, complete = FALSE) ## check that X^TX = R^TR ## get the permutation matrix P <- qr_pivot2perm(pivot = qr_res$pivot) max(abs(crossprod(R1 %*% P) - crossprod(X))) max(abs(crossprod(R1) - crossprod(X %*% t(P)))) ## complete R matrix R2 <- qr_R(qr = qr_res$qr, rank = NULL, complete = TRUE) ## check that X^TX = R^TR ## get the permutation matrix P <- qr_pivot2perm(pivot = qr_res$pivot) max(abs(crossprod(R2 %*% P) - crossprod(X))) max(abs(crossprod(R2) - crossprod(X %*% t(P)))) ## check that X = Q %*% R max(abs(Q2 %*% R2 %*% P - X)) max(abs(Q1 %*% R1 %*% P - X)) ## create data: n > p set.seed(1234) n <- 120 p <- 75 X <- matrix(rnorm(n * p), n, p) ## get the full QR decomposition with pivot qr_res <- fastQR::qr_fast(X = X, pivot = FALSE) ## reconstruct the reduced Q and R matrices ## reduced Q matrix Q1 <- qr_Q(qr = qr_res$qr, tau = qr_res$qraux, rank = p, complete = FALSE) ## check the Q matrix (orthogonality) max(abs(crossprod(Q1)-diag(1, p))) ## complete Q matrix Q2 <- qr_Q(qr = qr_res$qr, tau = qr_res$qraux, rank = NULL, complete = TRUE) ## check the Q matrix (orthogonality) max(abs(crossprod(Q2)-diag(1, n))) ## reduced R matrix R1 <- qr_R(qr = qr_res$qr, rank = NULL, complete = FALSE) ## check that X^TX = R^TR max(abs(crossprod(R1) - crossprod(X))) ## complete R matrix R2 <- qr_R(qr = qr_res$qr, rank = NULL, complete = TRUE) ## check that X^TX = R^TR max(abs(crossprod(R2) - crossprod(X))) ## check that X^TX = R^TR max(abs(crossprod(R2) - crossprod(X))) max(abs(crossprod(R2) - crossprod(X))) max(abs(crossprod(R1) - crossprod(X))) # check that X = Q %*% R max(abs(Q2 %*% R2 - X)) max(abs(Q1 %*% R1 - X))
Computes the fitted values for a linear
least-squares problem using a QR decomposition stored in compact
(Householder) form.
qr_fitted(qr, tau, y)qr_fitted(qr, tau, y)
qr |
Numeric matrix containing the QR decomposition of |
tau |
numeric vector of Householder coefficients. |
y |
numeric response vector of length |
The fitted values are computed as
without explicitly forming the orthogonal matrix . The
computation relies on the Householder reflectors stored in
qr and tau.
a numeric vector of fitted values .
set.seed(1) n <- 10; p <- 4 X <- matrix(rnorm(n * p), n, p) y <- rnorm(n) qr_res <- fastQR::qr_fast(X) yhat1 <- fastQR::qr_fitted(qr = qr_res$qr, tau = qr_res$qraux, y = y) ## reference computation yhat2 <- base::qr.fitted(base::qr(X), y) max(abs(yhat1 - yhat2))set.seed(1) n <- 10; p <- 4 X <- matrix(rnorm(n * p), n, p) y <- rnorm(n) qr_res <- fastQR::qr_fast(X) yhat1 <- fastQR::qr_fitted(qr = qr_res$qr, tau = qr_res$qraux, y = y) ## reference computation yhat2 <- base::qr.fitted(base::qr(X), y) max(abs(yhat1 - yhat2))
qr_lm, or LS for linear regression models, solves the following optimization problem
for and witn , to obtain a coefficient vector . The design matrix
contains the observations for each regressor.
qr_lm(y, X, X_test = NULL)qr_lm(y, X, X_test = NULL)
y |
a vector of length- |
X |
an |
X_test |
an |
A named list containing
a length- vector containing the solution for the parameters .
a length- vector containing the standard errors for the estimated regression parameters .
a length- vector of fitted values, .
a length- vector of residuals, .
the squared L2-norm of the residuals,
the squared L2-norm of the response variable,
the upper triangular matrix of the QR decomposition.
the inverse of the upper triangular matrix of the QR decomposition .
the Gram matrix of the least squares problem.
the inverse of the Gram matrix of the least squares problem .
A vector equal to , the cross-product of the design matrix with the response vector .
An estimate of the error variance , computed as the residual sum of squares divided by the residual degrees of freedom
The residual degrees of freedom, given by , where is the number of observations and is the number of estimated parameters.
, coefficient of determination, measure of goodness-of-fit of the model.
predicted values for the test set, . It is only available if X_test is not NULL.
## generate sample data ## create data: n > p set.seed(1234) n <- 12 n0 <- 3 p <- 7 X <- matrix(rnorm(n * p), n, p) b <- rep(1, p) sig2 <- 0.25 y <- X %*% b + sqrt(sig2) * rnorm(n) summary(lm(y~X)) ## test X_test <- matrix(rnorm(n0 * p), n0, p) ## lm qr_lm(y = y, X = X, X_test = X_test) qr_lm(y = y, X = X)## generate sample data ## create data: n > p set.seed(1234) n <- 12 n0 <- 3 p <- 7 X <- matrix(rnorm(n * p), n, p) b <- rep(1, p) sig2 <- 0.25 y <- X %*% b + sqrt(sig2) * rnorm(n) summary(lm(y~X)) ## test X_test <- matrix(rnorm(n0 * p), n0, p) ## lm qr_lm(y = y, X = X, X_test = X_test) qr_lm(y = y, X = X)
Computes the coefficient vector solving the
least-squares problem ,
using a QR decomposition computed internally.
qr_lse_coef(X, y)qr_lse_coef(X, y)
X |
numeric matrix of dimension |
y |
numeric response vector of length |
The QR decomposition of is computed internally. The coefficients
are obtained by first computing and then solving the
resulting upper-triangular system involving the matrix .
The orthogonal matrix is never formed explicitly.
This function is intended as a convenience wrapper for least-squares estimation when the explicit QR factors are not required.
a numeric vector of regression coefficients.
set.seed(1) n <- 10; p <- 4 X <- matrix(rnorm(n * p), n, p) y <- rnorm(n) coef1 <- fastQR::qr_lse_coef(X, y) ## reference computation coef2 <- base::qr.coef(base::qr(X), y) max(abs(coef1 - coef2))set.seed(1) n <- 10; p <- 4 X <- matrix(rnorm(n * p), n, p) y <- rnorm(n) coef1 <- fastQR::qr_lse_coef(X, y) ## reference computation coef2 <- base::qr.coef(base::qr(X), y) max(abs(coef1 - coef2))
Computes the fitted values for a linear
least-squares problem using a QR decomposition computed internally.
qr_lse_fitted(X, y)qr_lse_fitted(X, y)
X |
numeric matrix of dimension |
y |
numeric response vector of length |
The QR decomposition of is computed internally. The fitted
values are obtained as
without explicitly forming the orthogonal matrix .
This function is intended as a convenience wrapper for least-squares computations when the explicit QR factors are not required.
a numeric vector of fitted values .
set.seed(1) n <- 10; p <- 4 X <- matrix(rnorm(n * p), n, p) y <- rnorm(n) yhat1 <- fastQR::qr_lse_fitted(X, y) ## reference computation yhat2 <- base::qr.fitted(base::qr(X), y) max(abs(yhat1 - yhat2))set.seed(1) n <- 10; p <- 4 X <- matrix(rnorm(n * p), n, p) y <- rnorm(n) yhat1 <- fastQR::qr_lse_fitted(X, y) ## reference computation yhat2 <- base::qr.fitted(base::qr(X), y) max(abs(yhat1 - yhat2))
Computes the product , where is the orthogonal
matrix from the QR decomposition of the design matrix .
qr_lse_Qty(X, y)qr_lse_Qty(X, y)
X |
numeric matrix of dimension |
y |
numeric response vector of length |
The QR decomposition of is computed internally, and the
orthogonal matrix is never formed explicitly. The product
is evaluated efficiently using Householder reflectors.
This function is intended as a convenience wrapper for least-squares computations when the explicit QR factors are not required.
a numeric vector equal to .
set.seed(1) n <- 10; p <- 4 X <- matrix(rnorm(n * p), n, p) y <- rnorm(n) res1 <- fastQR::qr_lse_Qty(X, y) ## reference computation res2 <- crossprod(base::qr.Q(base::qr(X), complete = TRUE), y) max(abs(res1 - drop(res2)))set.seed(1) n <- 10; p <- 4 X <- matrix(rnorm(n * p), n, p) y <- rnorm(n) res1 <- fastQR::qr_lse_Qty(X, y) ## reference computation res2 <- crossprod(base::qr.Q(base::qr(X), complete = TRUE), y) max(abs(res1 - drop(res2)))
Computes the product , where is the orthogonal
matrix from the QR decomposition of the design matrix .
qr_lse_Qy(X, y)qr_lse_Qy(X, y)
X |
numeric matrix of dimension |
y |
numeric response vector of length |
The QR decomposition of is computed internally, and the
orthogonal matrix is never formed explicitly. The product
is evaluated efficiently using Householder reflectors.
This function is intended as a convenience wrapper for least-squares computations when the explicit QR factors are not required.
a numeric vector equal to .
set.seed(1) n <- 10; p <- 4 X <- matrix(rnorm(n * p), n, p) y <- rnorm(n) res1 <- fastQR::qr_lse_Qy(X, y) ## reference computation res2 <- base::qr.Q(base::qr(X), complete = TRUE) %*% y max(abs(res1 - drop(res2)))set.seed(1) n <- 10; p <- 4 X <- matrix(rnorm(n * p), n, p) y <- rnorm(n) res1 <- fastQR::qr_lse_Qy(X, y) ## reference computation res2 <- base::qr.Q(base::qr(X), complete = TRUE) %*% y max(abs(res1 - drop(res2)))
Computes the residual vector for a linear
least-squares problem using a QR decomposition computed internally.
qr_lse_resid(X, y)qr_lse_resid(X, y)
X |
numeric matrix of dimension |
y |
numeric response vector of length |
The QR decomposition of is computed internally. The residuals
are obtained as
without explicitly forming the orthogonal matrix .
This function is intended as a convenience wrapper for least-squares computations when the explicit QR factors are not required.
a numeric vector of residuals.
set.seed(1) n <- 10; p <- 4 X <- matrix(rnorm(n * p), n, p) y <- rnorm(n) r1 <- fastQR::qr_lse_resid(X, y) ## reference computation r2 <- base::qr.resid(base::qr(X), y) max(abs(r1 - r2))set.seed(1) n <- 10; p <- 4 X <- matrix(rnorm(n * p), n, p) y <- rnorm(n) r1 <- fastQR::qr_lse_resid(X, y) ## reference computation r2 <- base::qr.resid(base::qr(X), y) max(abs(r1 - r2))
returns the permutation matrix for the QR decomposition.
qr_pivot2perm(pivot)qr_pivot2perm(pivot)
pivot |
a vector of dimension |
the perumutation matrix of dimension .
Golub GH, Van Loan CF (2013). Matrix computations, Johns Hopkins Studies in the Mathematical Sciences, Fourth edition. Johns Hopkins University Press, Baltimore, MD. ISBN 978-1-4214-0794-4; 1-4214-0794-9; 978-1-4214-0859-0.
Björck Å (2015). Numerical methods in matrix computations, volume 59 of Texts in Applied Mathematics. Springer, Cham. ISBN 978-3-319-05088-1; 978-3-319-05098-8. doi:10.1007/978-3-319-05089-8.
Björck Å (2024). Numerical Methods for Least Squares Problems: Second Edition. Society for Industrial and Applied Mathematics, Philadelphia, PA. doi:10.1137/1.9781611977950. https://doi.org/10.1137/1.9781611977950.
Bernardi M, Busatto C, Cattelan M (2024). “Fast QR updating methods for statistical applications.” 2412.05905, https://arxiv.org/abs/2412.05905.
## generate sample data set.seed(1234) n <- 12 p <- 5 X <- matrix(rnorm(n * p), n, p) ## get the full QR decomposition with pivot qr_res <- fastQR::qr_fast(X = X, tol = sqrt(.Machine$double.eps), pivot = TRUE) ## get the pivot matrix P <- qr_pivot2perm(qr_res$pivot)## generate sample data set.seed(1234) n <- 12 p <- 5 X <- matrix(rnorm(n * p), n, p) ## get the full QR decomposition with pivot qr_res <- fastQR::qr_fast(X = X, tol = sqrt(.Machine$double.eps), pivot = TRUE) ## get the pivot matrix P <- qr_pivot2perm(qr_res$pivot)
returns the matrix of the full QR decomposition. If , then only the reduced matrix is returned.
qr_Q(qr, tau, rank = NULL, complete = NULL)qr_Q(qr, tau, rank = NULL, complete = NULL)
qr |
object representing a QR decomposition. This will typically have come from a previous call to qr. |
tau |
a vector of length |
rank |
the rank of x as computed by the decomposition. |
complete |
logical flag (length 1). Indicates whether to compute the full |
returns part or all of , the order- orthogonal (unitary) transformation represented by qr. If complete is TRUE, has columns. If complete is FALSE, has columns.
Golub GH, Van Loan CF (2013). Matrix computations, Johns Hopkins Studies in the Mathematical Sciences, Fourth edition. Johns Hopkins University Press, Baltimore, MD. ISBN 978-1-4214-0794-4; 1-4214-0794-9; 978-1-4214-0859-0.
Björck Å (2015). Numerical methods in matrix computations, volume 59 of Texts in Applied Mathematics. Springer, Cham. ISBN 978-3-319-05088-1; 978-3-319-05098-8. doi:10.1007/978-3-319-05089-8.
Björck Å (2024). Numerical Methods for Least Squares Problems: Second Edition. Society for Industrial and Applied Mathematics, Philadelphia, PA. doi:10.1137/1.9781611977950. https://doi.org/10.1137/1.9781611977950.
Bernardi M, Busatto C, Cattelan M (2024). “Fast QR updating methods for statistical applications.” 2412.05905, https://arxiv.org/abs/2412.05905.
## generate sample data set.seed(1234) n <- 12 p <- 5 X <- matrix(rnorm(n * p), n, p) ## get the full QR decomposition with pivot qr_res <- fastQR::qr_fast(X = X, tol = sqrt(.Machine$double.eps), pivot = TRUE) ## get the full Q matrix Q1 <- qr_Q(qr_res$qr, qr_res$qraux, complete = TRUE) ## check the Q matrix (orthogonality) max(abs(crossprod(Q1)-diag(1, n))) ## get the reduced Q matrix Q2 <- qr_Q(qr_res$qr, qr_res$qraux, qr_res$rank, complete = FALSE) ## check the Q matrix (orthogonality) max(abs(crossprod(Q2)-diag(1, p)))## generate sample data set.seed(1234) n <- 12 p <- 5 X <- matrix(rnorm(n * p), n, p) ## get the full QR decomposition with pivot qr_res <- fastQR::qr_fast(X = X, tol = sqrt(.Machine$double.eps), pivot = TRUE) ## get the full Q matrix Q1 <- qr_Q(qr_res$qr, qr_res$qraux, complete = TRUE) ## check the Q matrix (orthogonality) max(abs(crossprod(Q1)-diag(1, n))) ## get the reduced Q matrix Q2 <- qr_Q(qr_res$qr, qr_res$qraux, qr_res$rank, complete = FALSE) ## check the Q matrix (orthogonality) max(abs(crossprod(Q2)-diag(1, p)))
returns the full matrix.
qr_Q_full(qr, tau)qr_Q_full(qr, tau)
qr |
object representing a QR decomposition. This will typically have come from a previous call to qr. |
tau |
a vector of length |
returns the matrix .
Golub GH, Van Loan CF (2013). Matrix computations, Johns Hopkins Studies in the Mathematical Sciences, Fourth edition. Johns Hopkins University Press, Baltimore, MD. ISBN 978-1-4214-0794-4; 1-4214-0794-9; 978-1-4214-0859-0.
Björck Å (2015). Numerical methods in matrix computations, volume 59 of Texts in Applied Mathematics. Springer, Cham. ISBN 978-3-319-05088-1; 978-3-319-05098-8. doi:10.1007/978-3-319-05089-8.
Björck Å (2024). Numerical Methods for Least Squares Problems: Second Edition. Society for Industrial and Applied Mathematics, Philadelphia, PA. doi:10.1137/1.9781611977950. https://doi.org/10.1137/1.9781611977950.
Bernardi M, Busatto C, Cattelan M (2024). “Fast QR updating methods for statistical applications.” 2412.05905, https://arxiv.org/abs/2412.05905.
## create data: n > p set.seed(1234) n <- 12 p <- 7 X <- matrix(rnorm(n * p), n, p) ## get the full QR decomposition with pivot qr_res <- fastQR::qr_fast(X = X, tol = sqrt(.Machine$double.eps), pivot = TRUE) ## complete the reduced Q matrix Q <- fastQR::qr_Q_full(qr = qr_res$qr, tau = qr_res$qraux) ## check the Q matrix (orthogonality) max(abs(crossprod(Q)-diag(1, n)))## create data: n > p set.seed(1234) n <- 12 p <- 7 X <- matrix(rnorm(n * p), n, p) ## get the full QR decomposition with pivot qr_res <- fastQR::qr_fast(X = X, tol = sqrt(.Machine$double.eps), pivot = TRUE) ## complete the reduced Q matrix Q <- fastQR::qr_Q_full(qr = qr_res$qr, tau = qr_res$qraux) ## check the Q matrix (orthogonality) max(abs(crossprod(Q)-diag(1, n)))
returns the full matrix.
qr_Q_reduced2full(Q)qr_Q_reduced2full(Q)
Q |
a |
a orthogonal matrix .
Golub GH, Van Loan CF (2013). Matrix computations, Johns Hopkins Studies in the Mathematical Sciences, Fourth edition. Johns Hopkins University Press, Baltimore, MD. ISBN 978-1-4214-0794-4; 1-4214-0794-9; 978-1-4214-0859-0.
Björck Å (2015). Numerical methods in matrix computations, volume 59 of Texts in Applied Mathematics. Springer, Cham. ISBN 978-3-319-05088-1; 978-3-319-05098-8. doi:10.1007/978-3-319-05089-8.
Björck Å (2024). Numerical Methods for Least Squares Problems: Second Edition. Society for Industrial and Applied Mathematics, Philadelphia, PA. doi:10.1137/1.9781611977950. https://doi.org/10.1137/1.9781611977950.
Bernardi M, Busatto C, Cattelan M (2024). “Fast QR updating methods for statistical applications.” 2412.05905, https://arxiv.org/abs/2412.05905.
## create data: n > p set.seed(1234) n <- 12 p <- 7 X <- matrix(rnorm(n * p), n, p) ## get the full QR decomposition with pivot qr_res <- fastQR::qr_fast(X = X, tol = sqrt(.Machine$double.eps), pivot = TRUE) ## reconstruct the reduced Q matrix Q1 <- qr_Q(qr = qr_res$qr, tau = qr_res$qraux, rank = qr_res$rank, complete = FALSE) ## complete the reduced Q matrix Q2 <- fastQR::qr_Q_reduced2full(Q = Q1) R <- fastQR::qr_R(qr = qr_res$qr, rank = NULL, complete = TRUE) X1 <- qr_X(Q = Q2, R = R, pivot = qr_res$pivot) max(abs(X - X1))## create data: n > p set.seed(1234) n <- 12 p <- 7 X <- matrix(rnorm(n * p), n, p) ## get the full QR decomposition with pivot qr_res <- fastQR::qr_fast(X = X, tol = sqrt(.Machine$double.eps), pivot = TRUE) ## reconstruct the reduced Q matrix Q1 <- qr_Q(qr = qr_res$qr, tau = qr_res$qraux, rank = qr_res$rank, complete = FALSE) ## complete the reduced Q matrix Q2 <- fastQR::qr_Q_reduced2full(Q = Q1) R <- fastQR::qr_R(qr = qr_res$qr, rank = NULL, complete = TRUE) X1 <- qr_X(Q = Q2, R = R, pivot = qr_res$pivot) max(abs(X - X1))
Computes , where is the orthogonal matrix from the
QR decomposition stored in compact (Householder) form.
qr_Qty(qr, tau, y)qr_Qty(qr, tau, y)
qr |
numeric matrix containing the QR decomposition in compact form
(as returned by |
tau |
numeric vector of Householder coefficients. |
y |
numeric vector of length |
The orthogonal matrix is not formed explicitly. The product
is computed efficiently using the Householder reflectors
stored in qr and tau.
a numeric vector equal to .
set.seed(1) n <- 10; p <- 4 X <- matrix(rnorm(n * p), n, p) y <- rnorm(n) qr_res <- fastQR::qr_fast(X) res1 <- fastQR::qr_Qty(qr = qr_res$qr, tau = qr_res$qraux, y = y) ## reference computation Q <- base::qr.Q(base::qr(X), complete = TRUE) res2 <- crossprod(Q, y) max(abs(res1 - drop(res2)))set.seed(1) n <- 10; p <- 4 X <- matrix(rnorm(n * p), n, p) y <- rnorm(n) qr_res <- fastQR::qr_fast(X) res1 <- fastQR::qr_Qty(qr = qr_res$qr, tau = qr_res$qraux, y = y) ## reference computation Q <- base::qr.Q(base::qr(X), complete = TRUE) res2 <- crossprod(Q, y) max(abs(res1 - drop(res2)))
Computes , where is the orthogonal matrix from the
QR decomposition stored in compact (Householder) form.
qr_Qy(qr, tau, y)qr_Qy(qr, tau, y)
qr |
numeric matrix containing the QR decomposition in compact form
(as returned by |
tau |
numeric vector of Householder coefficients. |
y |
numeric vector of length |
The orthogonal matrix is not formed explicitly. The product
is computed efficiently using the Householder reflectors
stored in qr and tau.
a numeric vector equal to .
set.seed(1) n <- 10; p <- 4 X <- matrix(rnorm(n * p), n, p) y <- rnorm(n) qr_res <- fastQR::qr_fast(X) res1 <- fastQR::qr_Qy(qr = qr_res$qr, tau = qr_res$qraux, y = y) ## reference computation Q <- base::qr.Q(base::qr(X), complete = TRUE) res2 <- Q %*% y max(abs(res1 - drop(res2)))set.seed(1) n <- 10; p <- 4 X <- matrix(rnorm(n * p), n, p) y <- rnorm(n) qr_res <- fastQR::qr_fast(X) res1 <- fastQR::qr_Qy(qr = qr_res$qr, tau = qr_res$qraux, y = y) ## reference computation Q <- base::qr.Q(base::qr(X), complete = TRUE) res2 <- Q %*% y max(abs(res1 - drop(res2)))
returns the matrix of the full QR decomposition. If , then only the reduced matrix is returned.
qr_R(qr, rank = NULL, pivot = NULL, complete = NULL)qr_R(qr, rank = NULL, pivot = NULL, complete = NULL)
qr |
object representing a QR decomposition. This will typically have come from a previous call to qr. |
rank |
the rank of x as computed by the decomposition. |
pivot |
a vector of length |
complete |
logical flag (length 1). Indicates whether the |
returns part or all of . If complete is TRUE, has rows. If complete is FALSE, has rows.
Golub GH, Van Loan CF (2013). Matrix computations, Johns Hopkins Studies in the Mathematical Sciences, Fourth edition. Johns Hopkins University Press, Baltimore, MD. ISBN 978-1-4214-0794-4; 1-4214-0794-9; 978-1-4214-0859-0.
Björck Å (2015). Numerical methods in matrix computations, volume 59 of Texts in Applied Mathematics. Springer, Cham. ISBN 978-3-319-05088-1; 978-3-319-05098-8. doi:10.1007/978-3-319-05089-8.
Björck Å (2024). Numerical Methods for Least Squares Problems: Second Edition. Society for Industrial and Applied Mathematics, Philadelphia, PA. doi:10.1137/1.9781611977950. https://doi.org/10.1137/1.9781611977950.
Bernardi M, Busatto C, Cattelan M (2024). “Fast QR updating methods for statistical applications.” 2412.05905, https://arxiv.org/abs/2412.05905.
## generate sample data set.seed(1234) n <- 12 p <- 5 X <- matrix(rnorm(n * p), n, p) ## get the full QR decomposition with pivot qr_res <- fastQR::qr_fast(X = X, tol = sqrt(.Machine$double.eps), pivot = TRUE) ## get the full R matrix R1 <- qr_R(qr_res$qr, complete = TRUE) ## check that X^TX = R^TR ## get the permutation matrix P <- qr_pivot2perm(pivot = qr_res$pivot) max(abs(crossprod(R1 %*% P) - crossprod(X))) max(abs(crossprod(R1) - crossprod(X %*% t(P)))) ## get the reduced R matrix R2 <- qr_R(qr_res$qr, qr_res$rank, complete = FALSE) ## check that X^TX = R^TR ## get the permutation matrix P <- qr_pivot2perm(pivot = qr_res$pivot) max(abs(crossprod(R2 %*% P) - crossprod(X))) max(abs(crossprod(R2) - crossprod(X %*% t(P))))## generate sample data set.seed(1234) n <- 12 p <- 5 X <- matrix(rnorm(n * p), n, p) ## get the full QR decomposition with pivot qr_res <- fastQR::qr_fast(X = X, tol = sqrt(.Machine$double.eps), pivot = TRUE) ## get the full R matrix R1 <- qr_R(qr_res$qr, complete = TRUE) ## check that X^TX = R^TR ## get the permutation matrix P <- qr_pivot2perm(pivot = qr_res$pivot) max(abs(crossprod(R1 %*% P) - crossprod(X))) max(abs(crossprod(R1) - crossprod(X %*% t(P)))) ## get the reduced R matrix R2 <- qr_R(qr_res$qr, qr_res$rank, complete = FALSE) ## check that X^TX = R^TR ## get the permutation matrix P <- qr_pivot2perm(pivot = qr_res$pivot) max(abs(crossprod(R2 %*% P) - crossprod(X))) max(abs(crossprod(R2) - crossprod(X %*% t(P))))
Computes the residual vector for a linear
least-squares problem using a QR decomposition stored in compact
(Householder) form.
qr_resid(qr, tau, y)qr_resid(qr, tau, y)
qr |
numeric matrix containing the QR decomposition of |
tau |
numeric vector of Householder coefficients. |
y |
numeric response vector of length |
The residuals are computed as
without explicitly forming the orthogonal matrix . The
computation relies on the Householder reflectors stored in
qr and tau.
a numeric vector of residuals of dimension .
set.seed(1) n <- 10; p <- 4 X <- matrix(rnorm(n * p), n, p) y <- rnorm(n) qr_res <- fastQR::qr_fast(X) r1 <- fastQR::qr_resid(qr = qr_res$qr, tau = qr_res$qraux, y = y) ## reference computation r2 <- base::qr.resid(base::qr(X), y) max(abs(r1 - r2))set.seed(1) n <- 10; p <- 4 X <- matrix(rnorm(n * p), n, p) y <- rnorm(n) qr_res <- fastQR::qr_fast(X) r1 <- fastQR::qr_resid(qr = qr_res$qr, tau = qr_res$qraux, y = y) ## reference computation r2 <- base::qr.resid(base::qr(X), y) max(abs(r1 - r2))
qr_thin provides the thin QR factorization of the matrix with . The thin QR factorization of the matrix returns the matrices and the upper triangular matrix such that . See Golub and Van Loan (2013) for further details on the method.
qr_thin(X)qr_thin(X)
X |
a |
A named list containing
the Q matrix.
the R matrix.
Golub GH, Van Loan CF (2013). Matrix computations, Johns Hopkins Studies in the Mathematical Sciences, Fourth edition. Johns Hopkins University Press, Baltimore, MD. ISBN 978-1-4214-0794-4; 1-4214-0794-9; 978-1-4214-0859-0.
Björck Å (2015). Numerical methods in matrix computations, volume 59 of Texts in Applied Mathematics. Springer, Cham. ISBN 978-3-319-05088-1; 978-3-319-05098-8. doi:10.1007/978-3-319-05089-8.
Björck Å (2024). Numerical Methods for Least Squares Problems: Second Edition. Society for Industrial and Applied Mathematics, Philadelphia, PA. doi:10.1137/1.9781611977950. https://doi.org/10.1137/1.9781611977950.
Bernardi M, Busatto C, Cattelan M (2024). “Fast QR updating methods for statistical applications.” 2412.05905, https://arxiv.org/abs/2412.05905.
## generate sample data set.seed(1234) n <- 12 p <- 5 X <- matrix(rnorm(n * p), n, p) ## get the thin QR factorization output <- qr_thin(X = X) Q <- output$Q R <- output$R ## check max(abs(Q %*% R - X))## generate sample data set.seed(1234) n <- 12 p <- 5 X <- matrix(rnorm(n * p), n, p) ## get the thin QR factorization output <- qr_thin(X = X) Q <- output$Q R <- output$R ## check max(abs(Q %*% R - X))
from the Q and R matrices of the QR decomposition.returns the matrix.
qr_X(Q, R, pivot = NULL)qr_X(Q, R, pivot = NULL)
Q |
either the reduced |
R |
either the reduced |
pivot |
a vector of length |
returns the matrix .
Golub GH, Van Loan CF (2013). Matrix computations, Johns Hopkins Studies in the Mathematical Sciences, Fourth edition. Johns Hopkins University Press, Baltimore, MD. ISBN 978-1-4214-0794-4; 1-4214-0794-9; 978-1-4214-0859-0.
Björck Å (2015). Numerical methods in matrix computations, volume 59 of Texts in Applied Mathematics. Springer, Cham. ISBN 978-3-319-05088-1; 978-3-319-05098-8. doi:10.1007/978-3-319-05089-8.
Björck Å (2024). Numerical Methods for Least Squares Problems: Second Edition. Society for Industrial and Applied Mathematics, Philadelphia, PA. doi:10.1137/1.9781611977950. https://doi.org/10.1137/1.9781611977950.
Bernardi M, Busatto C, Cattelan M (2024). “Fast QR updating methods for statistical applications.” 2412.05905, https://arxiv.org/abs/2412.05905.
## generate sample data set.seed(1234) n <- 12 p <- 5 X <- matrix(rnorm(n * p), n, p) ## get the full QR decomposition with pivot qr_res <- fastQR::qr_fast(X = X, tol = sqrt(.Machine$double.eps), pivot = TRUE) ## get the full QR decomposition with pivot qr_res <- fastQR::qr_fast(X = X, pivot = TRUE) ## get the Q and R matrices Q <- qr_Q(qr = qr_res$qr, tau = qr_res$qraux, rank = qr_res$rank, complete = TRUE) R <- qr_R(qr = qr_res$qr, rank = qr_res$rank, complete = TRUE) X1 <- qr_X(Q = Q, R = R, pivot = qr_res$pivot) max(abs(X1 - X)) ## get the full QR decomposition without pivot qr_res <- fastQR::qr_fast(X = X, pivot = FALSE) ## get the Q and R matrices Q <- qr_Q(qr = qr_res$qr, tau = qr_res$qraux, rank = p, complete = FALSE) R <- qr_R(qr = qr_res$qr, rank = NULL, complete = FALSE) X1 <- qr_X(Q = Q, R = R, pivot = NULL) max(abs(X1 - X))## generate sample data set.seed(1234) n <- 12 p <- 5 X <- matrix(rnorm(n * p), n, p) ## get the full QR decomposition with pivot qr_res <- fastQR::qr_fast(X = X, tol = sqrt(.Machine$double.eps), pivot = TRUE) ## get the full QR decomposition with pivot qr_res <- fastQR::qr_fast(X = X, pivot = TRUE) ## get the Q and R matrices Q <- qr_Q(qr = qr_res$qr, tau = qr_res$qraux, rank = qr_res$rank, complete = TRUE) R <- qr_R(qr = qr_res$qr, rank = qr_res$rank, complete = TRUE) X1 <- qr_X(Q = Q, R = R, pivot = qr_res$pivot) max(abs(X1 - X)) ## get the full QR decomposition without pivot qr_res <- fastQR::qr_fast(X = X, pivot = FALSE) ## get the Q and R matrices Q <- qr_Q(qr = qr_res$qr, tau = qr_res$qraux, rank = p, complete = FALSE) R <- qr_R(qr = qr_res$qr, rank = NULL, complete = FALSE) X1 <- qr_X(Q = Q, R = R, pivot = NULL) max(abs(X1 - X))
qrchol, provides the Cholesky decomposition of the symmetric and positive definite matrix , where is the input matrix.
qrchol(X, nb = NULL)qrchol(X, nb = NULL)
X |
an |
nb |
number of blocks for the recursive block QR decomposition, default is NULL. |
an upper triangular matrix of dimension which represents the Cholesky decomposition of .
qrdowndate provides the update of the QR factorization after the deletion of rows or columns to the matrix with . The QR factorization of the matrix returns the matrices and such that . The and matrices are factorized as and , with , such that and upper triangular matrix and . qrupdate accepts in input the matrices and either the complete matrix or the reduced one, . See Golub and Van Loan (2013) for further details on the method.
qrdowndate(Q, R, k, m = NULL, type = NULL, fast = NULL, complete = NULL)qrdowndate(Q, R, k, m = NULL, type = NULL, fast = NULL, complete = NULL)
Q |
a |
R |
a |
k |
position where the columns or the rows are removed. |
m |
number of columns or rows to be removed. Default is |
type |
either 'row' of 'column', for deleting rows or columns. Default is 'column'. |
fast |
fast mode: disable to check whether the provided matrices are valid inputs. Default is FALSE. |
complete |
logical expression of length 1. Indicates whether an arbitrary orthogonal completion of the |
A named list containing
the updated Q matrix.
the updated R matrix.
Golub GH, Van Loan CF (2013). Matrix computations, Johns Hopkins Studies in the Mathematical Sciences, Fourth edition. Johns Hopkins University Press, Baltimore, MD. ISBN 978-1-4214-0794-4; 1-4214-0794-9; 978-1-4214-0859-0.
Björck Å (2015). Numerical methods in matrix computations, volume 59 of Texts in Applied Mathematics. Springer, Cham. ISBN 978-3-319-05088-1; 978-3-319-05098-8. doi:10.1007/978-3-319-05089-8.
Björck Å (2024). Numerical Methods for Least Squares Problems: Second Edition. Society for Industrial and Applied Mathematics, Philadelphia, PA. doi:10.1137/1.9781611977950. https://doi.org/10.1137/1.9781611977950.
Bernardi M, Busatto C, Cattelan M (2024). “Fast QR updating methods for statistical applications.” 2412.05905, https://arxiv.org/abs/2412.05905.
## Remove one column ## generate sample data set.seed(10) n <- 10 p <- 6 X <- matrix(rnorm(n * p, 1), n, p) ## get the initial QR factorization output <- fastQR::qr(X, type = "householder", nb = NULL, complete = TRUE) Q <- output$Q R <- output$R ## select the column to be deleted ## from X and update X k <- 2 X1 <- X[, -k] ## downdate the QR decomposition out <- fastQR::qrdowndate(Q = Q, R = R, k = k, m = 1, type = "column", fast = FALSE, complete = TRUE) ## check round(out$Q %*% out$R - X1, 5) max(abs(out$Q %*% out$R - X1)) ## Remove m columns ## generate sample data set.seed(10) n <- 10 p <- 6 X <- matrix(rnorm(n * p, 1), n, p) ## get the initial QR factorization output <- fastQR::qr(X, type = "householder", nb = NULL, complete = TRUE) Q <- output$Q R <- output$R ## select the column to be deleted from X ## and update X m <- 2 k <- 2 X1 <- X[, -c(k,k+m-1)] ## downdate the QR decomposition out <- fastQR::qrdowndate(Q = Q, R = R, k = k, m = 2, type = "column", fast = TRUE, complete = FALSE) ## check round(out$Q %*% out$R - X1, 5) max(abs(out$Q %*% out$R - X1)) ## Remove one row ## generate sample data set.seed(10) n <- 10 p <- 6 X <- matrix(rnorm(n * p, 1), n, p) ## get the initial QR factorization output <- fastQR::qr(X, type = "householder", nb = NULL, complete = TRUE) Q <- output$Q R <- output$R ## select the row to be deleted from X and update X k <- 5 X1 <- X[-k,] ## downdate the QR decomposition out <- fastQR::qrdowndate(Q = Q, R = R, k = k, m = 1, type = "row", fast = FALSE, complete = TRUE) ## check round(out$Q %*% out$R - X1, 5) max(abs(out$Q %*% out$R - X1)) ## Remove m rows ## generate sample data set.seed(10) n <- 10 p <- 6 X <- matrix(rnorm(n * p, 1), n, p) ## get the initial QR factorization output <- fastQR::qr(X, type = "householder", nb = NULL, complete = TRUE) Q <- output$Q R <- output$R ## select the rows to be deleted from X and update X k <- 5 m <- 2 X1 <- X[-c(k,k+1),] ## downdate the QR decomposition out <- fastQR::qrdowndate(Q = Q, R = R, k = k, m = m, type = "row", fast = FALSE, complete = TRUE) ## check round(out$Q %*% out$R - X1, 5) max(abs(out$Q %*% out$R - X1))## Remove one column ## generate sample data set.seed(10) n <- 10 p <- 6 X <- matrix(rnorm(n * p, 1), n, p) ## get the initial QR factorization output <- fastQR::qr(X, type = "householder", nb = NULL, complete = TRUE) Q <- output$Q R <- output$R ## select the column to be deleted ## from X and update X k <- 2 X1 <- X[, -k] ## downdate the QR decomposition out <- fastQR::qrdowndate(Q = Q, R = R, k = k, m = 1, type = "column", fast = FALSE, complete = TRUE) ## check round(out$Q %*% out$R - X1, 5) max(abs(out$Q %*% out$R - X1)) ## Remove m columns ## generate sample data set.seed(10) n <- 10 p <- 6 X <- matrix(rnorm(n * p, 1), n, p) ## get the initial QR factorization output <- fastQR::qr(X, type = "householder", nb = NULL, complete = TRUE) Q <- output$Q R <- output$R ## select the column to be deleted from X ## and update X m <- 2 k <- 2 X1 <- X[, -c(k,k+m-1)] ## downdate the QR decomposition out <- fastQR::qrdowndate(Q = Q, R = R, k = k, m = 2, type = "column", fast = TRUE, complete = FALSE) ## check round(out$Q %*% out$R - X1, 5) max(abs(out$Q %*% out$R - X1)) ## Remove one row ## generate sample data set.seed(10) n <- 10 p <- 6 X <- matrix(rnorm(n * p, 1), n, p) ## get the initial QR factorization output <- fastQR::qr(X, type = "householder", nb = NULL, complete = TRUE) Q <- output$Q R <- output$R ## select the row to be deleted from X and update X k <- 5 X1 <- X[-k,] ## downdate the QR decomposition out <- fastQR::qrdowndate(Q = Q, R = R, k = k, m = 1, type = "row", fast = FALSE, complete = TRUE) ## check round(out$Q %*% out$R - X1, 5) max(abs(out$Q %*% out$R - X1)) ## Remove m rows ## generate sample data set.seed(10) n <- 10 p <- 6 X <- matrix(rnorm(n * p, 1), n, p) ## get the initial QR factorization output <- fastQR::qr(X, type = "householder", nb = NULL, complete = TRUE) Q <- output$Q R <- output$R ## select the rows to be deleted from X and update X k <- 5 m <- 2 X1 <- X[-c(k,k+1),] ## downdate the QR decomposition out <- fastQR::qrdowndate(Q = Q, R = R, k = k, m = m, type = "row", fast = FALSE, complete = TRUE) ## check round(out$Q %*% out$R - X1, 5) max(abs(out$Q %*% out$R - X1))
qrls, or LS for linear regression models, solves the following optimization problem
for and , to obtain a coefficient vector . The design matrix
contains the observations for each regressor.
qrls(y, X, X_test = NULL, type = NULL)qrls(y, X, X_test = NULL, type = NULL)
y |
a vector of length- |
X |
an |
X_test |
an |
type |
either "QR" or "R". Specifies the type of decomposition to use: "QR" for the QR decomposition or "R" for the Cholesky factorization of |
A named list containing
a length- vector containing the solution for the parameters .
a length- vector of fitted values, .
a length- vector of residuals, .
the L2-norm of the residuals,
the L2-norm of the response variable.
matrix of the QR decomposition of the matrix .
matrix of the QR decomposition of the matrix .
, where matrix of the QR decomposition of the matrix .
, coefficient of determination, measure of goodness-of-fit of the model.
predicted values for the test set, . It is only available if X_test is not NULL.
## generate sample data set.seed(10) n <- 30 p <- 6 X <- matrix(rnorm(n * p, 1), n, p) X[,1] <- 1 eps <- rnorm(n, sd = 0.5) beta <- rep(0, p) beta[1:3] <- 1 beta[4:5] <- 2 y <- X %*% beta + eps X_test <- matrix(rnorm(5 * p, 1), 5, p) output <- fastQR::qrls(y = y, X = X, X_test = X_test) output$coeff## generate sample data set.seed(10) n <- 30 p <- 6 X <- matrix(rnorm(n * p, 1), n, p) X[,1] <- 1 eps <- rnorm(n, sd = 0.5) beta <- rep(0, p) beta[1:3] <- 1 beta[4:5] <- 2 y <- X %*% beta + eps X_test <- matrix(rnorm(5 * p, 1), 5, p) output <- fastQR::qrls(y = y, X = X, X_test = X_test) output$coeff
qrmls, or LS for linear multivariate regression models, solves the following optimization problem
for and , to obtain a coefficient matrix . The design matrix
contains the observations for each regressor.
Y |
a matrix of dimension |
X |
an |
X_test |
an |
type |
either "QR" or "R". Specifies the type of decomposition to use: "QR" for the QR decomposition or "R" for the Cholesky factorization of |
A named list containing
a matrix of dimension containing the solution for the parameters .
a matrix of dimension of fitted values, .
a matrix of dimension of residuals, .
the matrix .
a matrix of dimension containing the estimated residual variance-covariance matrix.
degrees of freedom.
matrix of the QR decomposition of the matrix .
.
, coefficient of determination, measure of goodness-of-fit of the model.
predicted values for the test set, . It is only available if X_test is not NULL.
## generate sample data set.seed(10) n <- 30 p <- 6 q <- 3 X <- matrix(rnorm(n * p, 1), n, p) X[,1] <- 1 eps <- matrix(rnorm(n*q), n, q) B <- matrix(0, p, q) B[,1] <- rep(1, p) B[,2] <- rep(2, p) B[,3] <- rep(-1, p) Y <- X %*% B + eps X_test <- matrix(rnorm(5 * p, 1), 5, p) output <- fastQR::qrmls(Y = Y, X = X, X_test = X_test, type = "QR") output$coeff## generate sample data set.seed(10) n <- 30 p <- 6 q <- 3 X <- matrix(rnorm(n * p, 1), n, p) X[,1] <- 1 eps <- matrix(rnorm(n*q), n, q) B <- matrix(0, p, q) B[,1] <- rep(1, p) B[,2] <- rep(2, p) B[,3] <- rep(-1, p) Y <- X %*% B + eps X_test <- matrix(rnorm(5 * p, 1), 5, p) output <- fastQR::qrmls(Y = Y, X = X, X_test = X_test, type = "QR") output$coeff
qrmridge, or LS for linear multivariate regression models, solves the following optimization problem
for and , to obtain a coefficient matrix . The design matrix
contains the observations for each regressor.
Y |
a matrix of dimension |
X |
an |
lambda |
a vector of lambdas. |
X_test |
an |
type |
either "QR" or "R". Specifies the type of decomposition to use: "QR" for the QR decomposition or "R" for the Cholesky factorization of |
A named list containing
a matrix of dimension containing the solution for the parameters .
a matrix of dimension of fitted values, .
a matrix of dimension of residuals, .
the matrix .
a matrix of dimension containing the estimated residual variance-covariance matrix.
degrees of freedom.
matrix of the QR decomposition of the matrix .
.
, coefficient of determination, measure of goodness-of-fit of the model.
predicted values for the test set, . It is only available if X_test is not NULL.
## generate sample data set.seed(10) n <- 30 p <- 6 q <- 3 X <- matrix(rnorm(n * p, 1), n, p) X[,1] <- 1 eps <- matrix(rnorm(n*q), n, q) B <- matrix(0, p, q) B[,1] <- rep(1, p) B[,2] <- rep(2, p) B[,3] <- rep(-1, p) Y <- X %*% B + eps X_test <- matrix(rnorm(5 * p, 1), 5, p) output <- fastQR::qrmridge(Y = Y, X = X, lambda = 1, X_test = X_test, type = "QR") output$coeff## generate sample data set.seed(10) n <- 30 p <- 6 q <- 3 X <- matrix(rnorm(n * p, 1), n, p) X[,1] <- 1 eps <- matrix(rnorm(n*q), n, q) B <- matrix(0, p, q) B[,1] <- rep(1, p) B[,2] <- rep(2, p) B[,3] <- rep(-1, p) Y <- X %*% B + eps X_test <- matrix(rnorm(5 * p, 1), 5, p) output <- fastQR::qrmridge(Y = Y, X = X, lambda = 1, X_test = X_test, type = "QR") output$coeff
qrmridge_cv, or LS for linear multivariate regression models, solves the following optimization problem
for and , to obtain a coefficient matrix . The design matrix
contains the observations for each regressor.
Y |
a matrix of dimension |
X |
an |
lambda |
a vector of lambdas. |
k |
an integer vector defining the number of groups for CV. |
seed |
ad integer number defining the seed for random number generation. |
X_test |
an |
type |
either "QR" or "R". Specifies the type of decomposition to use: "QR" for the QR decomposition or "R" for the Cholesky factorization of |
A named list containing
a matrix of dimension containing the solution for the parameters .
a matrix of dimension of fitted values, .
a matrix of dimension of residuals, .
the matrix .
a matrix of dimension containing the estimated residual variance-covariance matrix.
degrees of freedom.
matrix of the QR decomposition of the matrix .
.
, coefficient of determination, measure of goodness-of-fit of the model.
predicted values for the test set, . It is only available if X_test is not NULL.
## generate sample data set.seed(10) n <- 30 p <- 6 q <- 3 X <- matrix(rnorm(n * p, 1), n, p) X[,1] <- 1 eps <- matrix(rnorm(n*q), n, q) B <- matrix(0, p, q) B[,1] <- rep(1, p) B[,2] <- rep(2, p) B[,3] <- rep(-1, p) Y <- X %*% B + eps X_test <- matrix(rnorm(5 * p, 1), 5, p) output <- fastQR::qrmridge_cv(Y = Y, X = X, lambda = c(1,2), k = 5, seed = 12, X_test = X_test, type = "QR") output$coeff## generate sample data set.seed(10) n <- 30 p <- 6 q <- 3 X <- matrix(rnorm(n * p, 1), n, p) X[,1] <- 1 eps <- matrix(rnorm(n*q), n, q) B <- matrix(0, p, q) B[,1] <- rep(1, p) B[,2] <- rep(2, p) B[,3] <- rep(-1, p) Y <- X %*% B + eps X_test <- matrix(rnorm(5 * p, 1), 5, p) output <- fastQR::qrmridge_cv(Y = Y, X = X, lambda = c(1,2), k = 5, seed = 12, X_test = X_test, type = "QR") output$coeff
lmridge, or RIDGE for linear regression models, solves the following penalized optimization problem
to obtain a coefficient vector . The design matrix
contains the observations for each regressor.
qrridge(y, X, lambda, X_test = NULL, type = NULL)qrridge(y, X, lambda, X_test = NULL, type = NULL)
y |
a vector of length- |
X |
an |
lambda |
a vector of lambdas. |
X_test |
an |
type |
either "QR" or "R". Specifies the type of decomposition to use: "QR" for the QR decomposition or "R" for the Cholesky factorization of |
A named list containing
mean of the response variable.
a length- vector containing the mean of each column of the design matrix.
the whole path of estimated regression coefficients.
explained sum of squares for the whole path of estimated coefficients.
generalized cross-validation for the whole path of lambdas.
minimum value of GCV.
inded corresponding to the minimum values of GCV.
a length- vector containing the solution for the parameters which corresponds to the minimum of GCV.
the vector of lambdas.
the vector of standard deviations of each column of the design matrix.
## generate sample data set.seed(10) n <- 30 p <- 6 X <- matrix(rnorm(n * p, 1), n, p) X[,1] <- 1 eps <- rnorm(n, sd = 0.5) beta <- rep(0, p) beta[1:3] <- 1 beta[4:5] <- 2 y <- X %*% beta + eps X_test <- matrix(rnorm(5 * p, 1), 5, p) output <- fastQR::qrridge(y = y, X = X, lambda = 0.2, X_test = X_test) output$coeff## generate sample data set.seed(10) n <- 30 p <- 6 X <- matrix(rnorm(n * p, 1), n, p) X[,1] <- 1 eps <- rnorm(n, sd = 0.5) beta <- rep(0, p) beta[1:3] <- 1 beta[4:5] <- 2 y <- X %*% beta + eps X_test <- matrix(rnorm(5 * p, 1), 5, p) output <- fastQR::qrridge(y = y, X = X, lambda = 0.2, X_test = X_test) output$coeff
qrridge_cv, or LS for linear multivariate regression models, solves the following optimization problem
for and , to obtain a coefficient matrix . The design matrix
contains the observations for each regressor.
y |
a vector of length- |
X |
an |
lambda |
a vector of lambdas. |
k |
an integer vector defining the number of groups for CV. |
seed |
ad integer number defining the seed for random number generation. |
X_test |
an |
type |
either "QR" or "R". Specifies the type of decomposition to use: "QR" for the QR decomposition or "R" for the Cholesky factorization of |
A named list containing
a length- vector containing the solution for the parameters .
a length- vector of fitted values, .
a length- vector of residuals, .
the L2-norm of the residuals,
the L2-norm of the response variable.
the matrix .
.
estimated residual variance.
degrees of freedom.
matrix of the QR decomposition of the matrix .
matrix of the QR decomposition of the matrix .
, where matrix of the QR decomposition of the matrix .
, coefficient of determination, measure of goodness-of-fit of the model.
predicted values for the test set, . It is only available if X_test is not NULL.
## generate sample data set.seed(10) n <- 30 p <- 6 X <- matrix(rnorm(n * p, 1), n, p) X[,1] <- 1 eps <- rnorm(n) beta <- rep(1, p) y <- X %*% beta + eps X_test <- matrix(rnorm(5 * p, 1), 5, p) output <- fastQR::qrridge_cv(y = y, X = X, lambda = c(1,2), k = 5, seed = 12, X_test = X_test, type = "QR") output$coeff## generate sample data set.seed(10) n <- 30 p <- 6 X <- matrix(rnorm(n * p, 1), n, p) X[,1] <- 1 eps <- rnorm(n) beta <- rep(1, p) y <- X %*% beta + eps X_test <- matrix(rnorm(5 * p, 1), 5, p) output <- fastQR::qrridge_cv(y = y, X = X, lambda = c(1,2), k = 5, seed = 12, X_test = X_test, type = "QR") output$coeff
solves systems of equations , for and , via the QR decomposition.
qrsolve(A, b, type = NULL, nb = NULL)qrsolve(A, b, type = NULL, nb = NULL)
A |
an |
b |
a vector of dimension |
type |
either "QR" or "R". Specifies the type of decomposition to use: "QR" for the QR decomposition or "R" for the Cholesky factorization of |
nb |
number of blocks for the recursive block QR decomposition, default is NULL. |
x a vector of dimension that satisfies .
Golub GH, Van Loan CF (2013). Matrix computations, Johns Hopkins Studies in the Mathematical Sciences, Fourth edition. Johns Hopkins University Press, Baltimore, MD. ISBN 978-1-4214-0794-4; 1-4214-0794-9; 978-1-4214-0859-0.
Björck Å (2015). Numerical methods in matrix computations, volume 59 of Texts in Applied Mathematics. Springer, Cham. ISBN 978-3-319-05088-1; 978-3-319-05098-8. doi:10.1007/978-3-319-05089-8.
Björck Å (2024). Numerical Methods for Least Squares Problems: Second Edition. Society for Industrial and Applied Mathematics, Philadelphia, PA. doi:10.1137/1.9781611977950. https://doi.org/10.1137/1.9781611977950.
Bernardi M, Busatto C, Cattelan M (2024). “Fast QR updating methods for statistical applications.” 2412.05905, https://arxiv.org/abs/2412.05905.
## generate sample data set.seed(1234) n <- 10 p <- 4 A <- matrix(rnorm(n * p, 1), n, p) b <- rnorm(n) ## solve the system of linear equations using qr x1 <- fastQR::qrsolve(A = A, b = b) x1 ## solve the system of linear equations using rb qr x2 <- fastQR::qrsolve(A = A, b = b, nb = 2) x2 ## check round(x1 - solve(crossprod(A)) %*% crossprod(A, b), 5) round(x2 - solve(crossprod(A)) %*% crossprod(A, b), 5)## generate sample data set.seed(1234) n <- 10 p <- 4 A <- matrix(rnorm(n * p, 1), n, p) b <- rnorm(n) ## solve the system of linear equations using qr x1 <- fastQR::qrsolve(A = A, b = b) x1 ## solve the system of linear equations using rb qr x2 <- fastQR::qrsolve(A = A, b = b, nb = 2) x2 ## check round(x1 - solve(crossprod(A)) %*% crossprod(A, b), 5) round(x2 - solve(crossprod(A)) %*% crossprod(A, b), 5)
qrupdate provides the update of the QR factorization after the addition of rows or columns to the matrix with . The QR factorization of the matrix returns the matrices and such that . The and matrices are factorized as and , with , such that and upper triangular matrix and . qrupdate accepts in input the matrices and either the complete matrix or the reduced one, . See Golub and Van Loan (2013) for further details on the method.
qrupdate(Q, R, k, U, type = NULL, fast = NULL, complete = NULL)qrupdate(Q, R, k, U, type = NULL, fast = NULL, complete = NULL)
Q |
a |
R |
a |
k |
position where the columns or the rows are added. |
U |
either a |
type |
either 'row' of 'column', for adding rows or columns. Default is 'column'. |
fast |
fast mode: disable to check whether the provided matrices are valid inputs. Default is FALSE. |
complete |
logical expression of length 1. Indicates whether an arbitrary orthogonal completion of the |
A named list containing
the updated Q matrix.
the updated R matrix.
Golub GH, Van Loan CF (2013). Matrix computations, Johns Hopkins Studies in the Mathematical Sciences, Fourth edition. Johns Hopkins University Press, Baltimore, MD. ISBN 978-1-4214-0794-4; 1-4214-0794-9; 978-1-4214-0859-0.
Björck Å (2015). Numerical methods in matrix computations, volume 59 of Texts in Applied Mathematics. Springer, Cham. ISBN 978-3-319-05088-1; 978-3-319-05098-8. doi:10.1007/978-3-319-05089-8.
Björck Å (2024). Numerical Methods for Least Squares Problems: Second Edition. Society for Industrial and Applied Mathematics, Philadelphia, PA. doi:10.1137/1.9781611977950. https://doi.org/10.1137/1.9781611977950.
Bernardi M, Busatto C, Cattelan M (2024). “Fast QR updating methods for statistical applications.” 2412.05905, https://arxiv.org/abs/2412.05905.
## Add one column ## generate sample data set.seed(1234) n <- 12 p <- 5 X <- matrix(rnorm(n * p, 1), n, p) ## get the initial QR factorization output <- qr(X, complete = TRUE) Q <- output$Q R <- output$R ## create column u to be added k <- p+1 u <- matrix(rnorm(n), n, 1) X1 <- cbind(X, u) ## update the QR decomposition out <- fastQR::qrupdate(Q = Q, R = R, k = k, U = u, type = "column", fast = FALSE, complete = TRUE) ## check round(out$Q %*% out$R - X1, 5) max(abs(out$Q %*% out$R - X1)) ## Add m columns ## create data: n > p set.seed(1234) n <- 10 p <- 5 X <- matrix(rnorm(n * p, 1), n, p) ## get the initial QR factorization output <- fastQR::qr(X, complete = TRUE) Q <- output$Q R <- output$R ## create the matrix of two columns to be added ## in position 2 k <- 2 m <- 2 U <- matrix(rnorm(n*m), n, m) X1 <- cbind(X[,1:(k-1)], U, X[,k:p]) # update the QR decomposition out <- fastQR::qrupdate(Q = Q, R = R, k = k, U = U, type = "column", fast = FALSE, complete = TRUE) ## check round(out$Q %*% out$R - X1, 5) max(abs(out$Q %*% out$R - X1)) ## Add one row ## create data: n > p set.seed(1234) n <- 12 p <- 5 X <- matrix(rnorm(n * p, 1), n, p) ## get the initial QR factorization output <- fastQR::qr(X, complete = TRUE) Q <- output$Q R <- output$R R1 <- R[1:p,] ## create the row u to be added u <- matrix(data = rnorm(p), p, 1) k <- n+1 if (k<=n) { X1 <- rbind(rbind(X[1:(k-1), ], t(u)), X[k:n, ]) } else { X1 <- rbind(rbind(X, t(u))) } ## update the QR decomposition out <- fastQR::qrupdate(Q = Q, R = R, k = k, U = u, type = "row", complete = TRUE) ## check round(out$Q %*% out$R - X1, 5) max(abs(out$Q %*% out$R - X1)) ## Add m rows ## create data: n > p set.seed(1234) n <- 12 p <- 5 X <- matrix(rnorm(n * p, 1), n, p) ## get the initial QR factorization output <- fastQR::qr(X, complete = TRUE) Q <- output$Q R <- output$R R1 <- R[1:p,] ## create the matrix of rows U to be added: ## two rows in position 5 m <- 2 U <- matrix(data = rnorm(p*m), p, m) k <- 5 if (k<=n) { X1 <- rbind(rbind(X[1:(k-1), ], t(U)), X[k:n, ]) } else { X1 <- rbind(rbind(X, t(U))) } ## update the QR decomposition out <- fastQR::qrupdate(Q = Q, R = R, k = k, U = U, type = "row", complete = FALSE) ## check round(out$Q %*% out$R - X1, 5) max(abs(out$Q %*% out$R - X1))## Add one column ## generate sample data set.seed(1234) n <- 12 p <- 5 X <- matrix(rnorm(n * p, 1), n, p) ## get the initial QR factorization output <- qr(X, complete = TRUE) Q <- output$Q R <- output$R ## create column u to be added k <- p+1 u <- matrix(rnorm(n), n, 1) X1 <- cbind(X, u) ## update the QR decomposition out <- fastQR::qrupdate(Q = Q, R = R, k = k, U = u, type = "column", fast = FALSE, complete = TRUE) ## check round(out$Q %*% out$R - X1, 5) max(abs(out$Q %*% out$R - X1)) ## Add m columns ## create data: n > p set.seed(1234) n <- 10 p <- 5 X <- matrix(rnorm(n * p, 1), n, p) ## get the initial QR factorization output <- fastQR::qr(X, complete = TRUE) Q <- output$Q R <- output$R ## create the matrix of two columns to be added ## in position 2 k <- 2 m <- 2 U <- matrix(rnorm(n*m), n, m) X1 <- cbind(X[,1:(k-1)], U, X[,k:p]) # update the QR decomposition out <- fastQR::qrupdate(Q = Q, R = R, k = k, U = U, type = "column", fast = FALSE, complete = TRUE) ## check round(out$Q %*% out$R - X1, 5) max(abs(out$Q %*% out$R - X1)) ## Add one row ## create data: n > p set.seed(1234) n <- 12 p <- 5 X <- matrix(rnorm(n * p, 1), n, p) ## get the initial QR factorization output <- fastQR::qr(X, complete = TRUE) Q <- output$Q R <- output$R R1 <- R[1:p,] ## create the row u to be added u <- matrix(data = rnorm(p), p, 1) k <- n+1 if (k<=n) { X1 <- rbind(rbind(X[1:(k-1), ], t(u)), X[k:n, ]) } else { X1 <- rbind(rbind(X, t(u))) } ## update the QR decomposition out <- fastQR::qrupdate(Q = Q, R = R, k = k, U = u, type = "row", complete = TRUE) ## check round(out$Q %*% out$R - X1, 5) max(abs(out$Q %*% out$R - X1)) ## Add m rows ## create data: n > p set.seed(1234) n <- 12 p <- 5 X <- matrix(rnorm(n * p, 1), n, p) ## get the initial QR factorization output <- fastQR::qr(X, complete = TRUE) Q <- output$Q R <- output$R R1 <- R[1:p,] ## create the matrix of rows U to be added: ## two rows in position 5 m <- 2 U <- matrix(data = rnorm(p*m), p, m) k <- 5 if (k<=n) { X1 <- rbind(rbind(X[1:(k-1), ], t(U)), X[k:n, ]) } else { X1 <- rbind(rbind(X, t(U))) } ## update the QR decomposition out <- fastQR::qrupdate(Q = Q, R = R, k = k, U = U, type = "row", complete = FALSE) ## check round(out$Q %*% out$R - X1, 5) max(abs(out$Q %*% out$R - X1))
rchol, provides the Cholesky decomposition of the symmetric and positive definite matrix , where is the input matrix.
X |
an |
an upper triangular matrix of dimension which represents the Cholesky decomposition of .
Golub GH, Van Loan CF (2013). Matrix computations, Johns Hopkins Studies in the Mathematical Sciences, Fourth edition. Johns Hopkins University Press, Baltimore, MD. ISBN 978-1-4214-0794-4; 1-4214-0794-9; 978-1-4214-0859-0.
Björck Å (2015). Numerical methods in matrix computations, volume 59 of Texts in Applied Mathematics. Springer, Cham. ISBN 978-3-319-05088-1; 978-3-319-05098-8. doi:10.1007/978-3-319-05089-8.
Björck Å (2024). Numerical Methods for Least Squares Problems: Second Edition. Society for Industrial and Applied Mathematics, Philadelphia, PA. doi:10.1137/1.9781611977950. https://doi.org/10.1137/1.9781611977950.
Bernardi M, Busatto C, Cattelan M (2024). “Fast QR updating methods for statistical applications.” 2412.05905, https://arxiv.org/abs/2412.05905.
set.seed(1234) n <- 10 p <- 6 X <- matrix(rnorm(n * p, 1), n, p) ## compute the Cholesky decomposition of X^TX S <- fastQR::rchol(X = X) S ## check round(S - chol(crossprod(X)), 5)set.seed(1234) n <- 10 p <- 6 X <- matrix(rnorm(n * p, 1), n, p) ## compute the Cholesky decomposition of X^TX S <- fastQR::rchol(X = X) S ## check round(S - chol(crossprod(X)), 5)
rdowndate provides the update of the thin R matrix of the QR factorization after the deletion of rows or columns to the matrix with . The R factorization of the matrix returns the upper triangular matrix such that . See Golub and Van Loan (2013) for further details on the method.
rdowndate(R, k = NULL, m = NULL, U = NULL, fast = NULL, type = NULL)rdowndate(R, k = NULL, m = NULL, U = NULL, fast = NULL, type = NULL)
R |
a |
k |
position where the columns or the rows are removed. |
m |
number of columns or rows to be removed. It is not required when deleting columns. If NULL, it defaults to the number of columns in |
U |
a |
fast |
fast mode: disable to check whether the provided matrices are valid inputs. Default is FALSE. |
type |
either 'row' of 'column', for removing rows or columns. |
R the updated R matrix.
Golub GH, Van Loan CF (2013). Matrix computations, Johns Hopkins Studies in the Mathematical Sciences, Fourth edition. Johns Hopkins University Press, Baltimore, MD. ISBN 978-1-4214-0794-4; 1-4214-0794-9; 978-1-4214-0859-0.
Björck Å (2015). Numerical methods in matrix computations, volume 59 of Texts in Applied Mathematics. Springer, Cham. ISBN 978-3-319-05088-1; 978-3-319-05098-8. doi:10.1007/978-3-319-05089-8.
Björck Å (2024). Numerical Methods for Least Squares Problems: Second Edition. Society for Industrial and Applied Mathematics, Philadelphia, PA. doi:10.1137/1.9781611977950. https://doi.org/10.1137/1.9781611977950.
Bernardi M, Busatto C, Cattelan M (2024). “Fast QR updating methods for statistical applications.” 2412.05905, https://arxiv.org/abs/2412.05905.
## Remove one column ## generate sample data set.seed(10) n <- 10 p <- 6 X <- matrix(rnorm(n * p, 1), n, p) ## get the initial QR factorization output <- fastQR::qr(X, type = "householder", nb = NULL, complete = TRUE) Q <- output$Q R <- output$R R1 <- R[1:p,] ## select the column to be deleted from X and update X k <- 2 X1 <- X[, -k] ## downdate the R decomposition R2 <- fastQR::rdowndate(R = R1, k = k, m = 1, type = "column") ## check max(abs(crossprod(R2) - crossprod(X1))) ## Remove m columns ## generate sample data set.seed(10) n <- 10 p <- 6 X <- matrix(rnorm(n * p, 1), n, p) ## get the initial QR factorization output <- fastQR::qr(X, type = "householder", nb = NULL, complete = TRUE) Q <- output$Q R <- output$R R1 <- R[1:p,] ## select the column to be deleted from X and update X k <- 2 X1 <- X[, -c(k,k+1)] ## downdate the R decomposition R2 <- fastQR::rdowndate(R = R1, k = k, m = 2, type = "column") ## check max(abs(crossprod(R2) - crossprod(X1))) ## Remove one row ## generate sample data set.seed(10) n <- 10 p <- 6 X <- matrix(rnorm(n * p, 1), n, p) ## get the initial QR factorization output <- fastQR::qr(X, type = "householder", nb = NULL, complete = TRUE) Q <- output$Q R <- output$R R1 <- R[1:p,] # select the row to be deleted from X and update X k <- 5 X1 <- X[-k,] U <- as.matrix(X[k,], p, 1) ## downdate the R decomposition R2 <- rdowndate(R = R1, k = k, m = 1, U = U, fast = FALSE, type = "row") ## check max(abs(crossprod(R2) - crossprod(X1))) ## Remove m rows ## create data: n > p set.seed(10) n <- 10 p <- 6 X <- matrix(rnorm(n * p, 1), n, p) output <- fastQR::qr(X, type = "householder", nb = NULL, complete = TRUE) Q <- output$Q R <- output$R R1 <- R[1:p,] ## select the rows to be deleted from X and update X k <- 2 m <- 2 X1 <- X[-c(k,k+m-1),] U <- t(X[k:(k+m-1), ]) ## downdate the R decomposition R2 <- rdowndate(R = R1, k = k, m = m, U = U, fast = FALSE, type = "row") ## check max(abs(crossprod(R2) - crossprod(X1)))## Remove one column ## generate sample data set.seed(10) n <- 10 p <- 6 X <- matrix(rnorm(n * p, 1), n, p) ## get the initial QR factorization output <- fastQR::qr(X, type = "householder", nb = NULL, complete = TRUE) Q <- output$Q R <- output$R R1 <- R[1:p,] ## select the column to be deleted from X and update X k <- 2 X1 <- X[, -k] ## downdate the R decomposition R2 <- fastQR::rdowndate(R = R1, k = k, m = 1, type = "column") ## check max(abs(crossprod(R2) - crossprod(X1))) ## Remove m columns ## generate sample data set.seed(10) n <- 10 p <- 6 X <- matrix(rnorm(n * p, 1), n, p) ## get the initial QR factorization output <- fastQR::qr(X, type = "householder", nb = NULL, complete = TRUE) Q <- output$Q R <- output$R R1 <- R[1:p,] ## select the column to be deleted from X and update X k <- 2 X1 <- X[, -c(k,k+1)] ## downdate the R decomposition R2 <- fastQR::rdowndate(R = R1, k = k, m = 2, type = "column") ## check max(abs(crossprod(R2) - crossprod(X1))) ## Remove one row ## generate sample data set.seed(10) n <- 10 p <- 6 X <- matrix(rnorm(n * p, 1), n, p) ## get the initial QR factorization output <- fastQR::qr(X, type = "householder", nb = NULL, complete = TRUE) Q <- output$Q R <- output$R R1 <- R[1:p,] # select the row to be deleted from X and update X k <- 5 X1 <- X[-k,] U <- as.matrix(X[k,], p, 1) ## downdate the R decomposition R2 <- rdowndate(R = R1, k = k, m = 1, U = U, fast = FALSE, type = "row") ## check max(abs(crossprod(R2) - crossprod(X1))) ## Remove m rows ## create data: n > p set.seed(10) n <- 10 p <- 6 X <- matrix(rnorm(n * p, 1), n, p) output <- fastQR::qr(X, type = "householder", nb = NULL, complete = TRUE) Q <- output$Q R <- output$R R1 <- R[1:p,] ## select the rows to be deleted from X and update X k <- 2 m <- 2 X1 <- X[-c(k,k+m-1),] U <- t(X[k:(k+m-1), ]) ## downdate the R decomposition R2 <- rdowndate(R = R1, k = k, m = m, U = U, fast = FALSE, type = "row") ## check max(abs(crossprod(R2) - crossprod(X1)))
updates the R factorization when rows or columns are added to the matrix , where . The R factorization of produces an upper triangular matrix such that . For more details on this method, refer to Golub and Van Loan (2013). Columns can only be added in positions through , while the position of added rows does not need to be specified.
X |
the current |
R |
a |
U |
either a |
type |
either 'row' of 'column', for adding rows or columns. |
fast |
fast mode: disable to check whether the provided matrices are valid inputs. Default is FALSE. |
R the updated R matrix.
Golub GH, Van Loan CF (2013). Matrix computations, Johns Hopkins Studies in the Mathematical Sciences, Fourth edition. Johns Hopkins University Press, Baltimore, MD. ISBN 978-1-4214-0794-4; 1-4214-0794-9; 978-1-4214-0859-0.
Björck Å (2015). Numerical methods in matrix computations, volume 59 of Texts in Applied Mathematics. Springer, Cham. ISBN 978-3-319-05088-1; 978-3-319-05098-8. doi:10.1007/978-3-319-05089-8.
Björck Å (2024). Numerical Methods for Least Squares Problems: Second Edition. Society for Industrial and Applied Mathematics, Philadelphia, PA. doi:10.1137/1.9781611977950. https://doi.org/10.1137/1.9781611977950.
Bernardi M, Busatto C, Cattelan M (2024). “Fast QR updating methods for statistical applications.” 2412.05905, https://arxiv.org/abs/2412.05905.
## Add one column ## generate sample data set.seed(1234) n <- 12 p <- 5 X <- matrix(rnorm(n * p, 1), n, p) ## get the initial QR factorization output <- fastQR::qr(X, complete = TRUE) Q <- output$Q R <- output$R R1 <- R[1:p,] ## create column to be added u <- matrix(rnorm(n), n, 1) X1 <- cbind(X, u) ## update the R decomposition R2 <- fastQR::rupdate(X = X, R = R1, U = u, fast = FALSE, type = "column") ## check max(abs(crossprod(R2) - crossprod(X1))) ## Add m columns ## generate sample data set.seed(1234) n <- 10 p <- 5 X <- matrix(rnorm(n * p, 1), n, p) ## get the initial QR factorization output <- fastQR::qr(X, complete = TRUE) Q <- output$Q R <- output$R R1 <- R[1:p,] ## create the matrix of columns to be added m <- 2 U <- matrix(rnorm(n*m), n, m) X1 <- cbind(X, U) # QR update R2 <- fastQR::rupdate(X = X, R = R1, U = U, fast = FALSE, type = "column") ## check max(abs(crossprod(R2) - crossprod(X1))) ## Add one row ## generate sample data set.seed(1234) n <- 12 p <- 5 X <- matrix(rnorm(n * p, 1), n, p) ## get the initial QR factorization output <- fastQR::qr(X, complete = TRUE) Q <- output$Q R <- output$R R1 <- R[1:p,] ## create the row u to be added u <- matrix(data = rnorm(p), p, 1) k <- 5 if (k<=n) { X1 <- rbind(rbind(X[1:(k-1), ], t(u)), X[k:n, ]) } else { X1 <- rbind(rbind(X, t(u))) } ## update the R decomposition R2 <- fastQR::rupdate(R = R1, X = X, U = u, type = "row") ## check max(abs(crossprod(R2) - crossprod(X1))) ## Add m rows ## generate sample data set.seed(1234) n <- 12 p <- 5 X <- matrix(rnorm(n * p, 1), n, p) ## get the initial QR factorization output <- fastQR::qr(X, complete = TRUE) Q <- output$Q R <- output$R R1 <- R[1:p,] ## create the matrix of rows to be added m <- 2 U <- matrix(data = rnorm(p*m), p, m) k <- 5 if (k<=n) { X1 <- rbind(rbind(X[1:(k-1), ], t(U)), X[k:n, ]) } else { X1 <- rbind(rbind(X, t(U))) } ## update the R decomposition R2 <- fastQR::rupdate(R = R1, X = X, U = U, fast = FALSE, type = "row") ## check max(abs(crossprod(R2) - crossprod(X1)))## Add one column ## generate sample data set.seed(1234) n <- 12 p <- 5 X <- matrix(rnorm(n * p, 1), n, p) ## get the initial QR factorization output <- fastQR::qr(X, complete = TRUE) Q <- output$Q R <- output$R R1 <- R[1:p,] ## create column to be added u <- matrix(rnorm(n), n, 1) X1 <- cbind(X, u) ## update the R decomposition R2 <- fastQR::rupdate(X = X, R = R1, U = u, fast = FALSE, type = "column") ## check max(abs(crossprod(R2) - crossprod(X1))) ## Add m columns ## generate sample data set.seed(1234) n <- 10 p <- 5 X <- matrix(rnorm(n * p, 1), n, p) ## get the initial QR factorization output <- fastQR::qr(X, complete = TRUE) Q <- output$Q R <- output$R R1 <- R[1:p,] ## create the matrix of columns to be added m <- 2 U <- matrix(rnorm(n*m), n, m) X1 <- cbind(X, U) # QR update R2 <- fastQR::rupdate(X = X, R = R1, U = U, fast = FALSE, type = "column") ## check max(abs(crossprod(R2) - crossprod(X1))) ## Add one row ## generate sample data set.seed(1234) n <- 12 p <- 5 X <- matrix(rnorm(n * p, 1), n, p) ## get the initial QR factorization output <- fastQR::qr(X, complete = TRUE) Q <- output$Q R <- output$R R1 <- R[1:p,] ## create the row u to be added u <- matrix(data = rnorm(p), p, 1) k <- 5 if (k<=n) { X1 <- rbind(rbind(X[1:(k-1), ], t(u)), X[k:n, ]) } else { X1 <- rbind(rbind(X, t(u))) } ## update the R decomposition R2 <- fastQR::rupdate(R = R1, X = X, U = u, type = "row") ## check max(abs(crossprod(R2) - crossprod(X1))) ## Add m rows ## generate sample data set.seed(1234) n <- 12 p <- 5 X <- matrix(rnorm(n * p, 1), n, p) ## get the initial QR factorization output <- fastQR::qr(X, complete = TRUE) Q <- output$Q R <- output$R R1 <- R[1:p,] ## create the matrix of rows to be added m <- 2 U <- matrix(data = rnorm(p*m), p, m) k <- 5 if (k<=n) { X1 <- rbind(rbind(X[1:(k-1), ], t(U)), X[k:n, ]) } else { X1 <- rbind(rbind(X, t(U))) } ## update the R decomposition R2 <- fastQR::rupdate(R = R1, X = X, U = U, fast = FALSE, type = "row") ## check max(abs(crossprod(R2) - crossprod(X1)))