简体   繁体   中英

How do I do a QR decomposition on an object of class "sparseMatrix" in the Matrix package?

I want to do a QR decomposition with the Matrix:::qr() function on a Matrix that I created with B<-as(A, "sparseMatrix") . I know that I can get the R matrix with Matrix:::qr.R() . However, I also need to the Q Matrix. There seems to be no qr.Q() function in the Matrix package. How do I get the Q matrix?

The Q matrix is actually stored in the V slot. It seems that the current R Matrix version contains a bug --- it just mysteriously adds zero rows into the matrix a before doing the qr decomposition. I wish the developers could come and explain it. Therefore the following codes help you recover both R and Q:

gx.qr.Q <- function(a){
  if(is(a, "qr")){
    return(qr.Q(a, complete = T))
  }else if(is(a, "sparseQR")){
    Q <- diag(nrow = a@V@Dim[1], ncol = a@V@Dim[1])
    for(i in rev(1:a@V@Dim[2])){
      Q <- Q - (a@V[ ,i] * a@beta[i]) %*% (a@V[ ,i] %*% Q)
    }
    return(Q[order(a@p), ][1:a@Dim[1], 1:a@Dim[1]])
  }else{
    stop(gettextf("gx.qr.Q() fails on class '%s'", class(a)[1]))
  }
}

gx.qr.R <- function(a){
  if(is(a, "qr")){
    return(qr.R(a, complete = T)[ ,order(a$pivot)])
  }else if(is(a, "sparseQR")){
    if(length(a@q) == 0){
      return(a@R[1:a@Dim[1], ])
    }else{
      return(a@R[1:a@Dim[1] ,order(a@q)])
    }
  }else{
    stop(gettextf("gx.qr.R() fails on class '%s'", class(a)[1]))
  }
}

I have tested by randomly set the matrix size and sparsity and they work smoothly. However this is of the style "just make it work without knowing why", and is posted here only for discussion. Because I have not hacked into the implementation details of the package "Matrix".

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM