Title: | Fast QR Decomposition and Update |
---|---|
Description: | Efficient algorithms for performing, updating, and downdating 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, see the book by Golub and Van Loan (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.0.0 |
Built: | 2025-02-18 11:19:08 UTC |
Source: | https://github.com/cranhaven/cranhaven.r-universe.dev |
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))
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. |
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.
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)))