I want to construct a symmetric band matrix in the Matrix package from a matrix where the first column contains data for the main diagonal, the second column has data for the first subdiagonal/superdiagonal and so on. Since the Matrix will be 10^5 x 10^5 or so, with perhaps 10-20 non-zero elements above the diagonal per row, I can't do it by constructing a full matrix and then using the band() function to subset it to a band matrix. Any suggestions? -thomas Thomas Lumley Assoc. Professor, Biostatistics tlumley at u.washington.edu University of Washington, Seattle
If you can tolerate the subdiagonal and superdiagonal zero elements being populated, then perhaps this is useful. If there is a subset function as you suggest, then perhaps further reduction would be feasible from this as a starting point. At least it would reduce the size from 10^5 x 10^5 to 10^5 x 3: library(Matrix) xxx <- data.frame(x1 =1:5, y1=c(0,6,0,7,0) ) M= Matrix(0,5,5) M[row(M) == col(M)] <- xxx$x1 M[row(M)-1 == col(M)] <- xxx$y1[1:(length(xxx$y1)-1)] M[row(M) == col(M)-1] <- xxx$y1[1:(length(xxx$y1)-1)] > M 5 x 5 sparse Matrix of class "dgCMatrix" [1,] 1 6 . . . [2,] 6 2 7 . . [3,] . 7 3 8 . [4,] . . 8 4 9 [5,] . . . 9 5 -- David Winsemius On Feb 19, 2009, at 5:28 AM, Thomas Lumley wrote:> > I want to construct a symmetric band matrix in the Matrix package > from a matrix where the first column contains data for the main > diagonal, the second column has data for the first subdiagonal/ > superdiagonal and so on. > > Since the Matrix will be 10^5 x 10^5 or so, with perhaps 10-20 non- > zero elements above the diagonal per row, I can't do it by > constructing a full matrix and then using the band() function to > subset it to a band matrix. > > Any suggestions? > > -thomas > > Thomas Lumley Assoc. Professor, Biostatistics > tlumley at u.washington.edu University of Washington, Seattle > > ______________________________________________ > R-help at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code.
On Fri, 20 Feb 2009, David Winsemius wrote:> If you can tolerate the subdiagonal and superdiagonal zero elements being > populated, then perhaps this is useful. If there is a subset function as you > suggest, then perhaps further reduction would be feasible from this as a > starting point. At least it would reduce the size from 10^5 x 10^5 to 10^5 x 3: > > library(Matrix) > xxx <- data.frame(x1 =1:5, y1=c(0,6,0,7,0) ) > M= Matrix(0,5,5) > M[row(M) == col(M)] <- xxx$x1 > M[row(M)-1 == col(M)] <- xxx$y1[1:(length(xxx$y1)-1)] > M[row(M) == col(M)-1] <- xxx$y1[1:(length(xxx$y1)-1)]That provides the right structure, but row(M) and col(M) are dense matrices with 10^10 elements, so it still uses too much memory. -thomas Thomas Lumley Assoc. Professor, Biostatistics tlumley at u.washington.edu University of Washington, Seattle
Thomas Lumley <tlumley <at> u.washington.edu> writes:> I want to construct a symmetric band matrix in the Matrix > package from a matrix where the first column > contains data for the main diagonal, the second column > has data for the first subdiagonal/superdiagonal > and so on. > > Since the Matrix will be 10^5 x 10^5 or so, with perhaps > 10-20 non-zero elements above the diagonal per row, I > can't do it by constructing a full matrix and then using the band() > function to subset it to a band matrix. > > Any suggestions? > > -thomas > > Thomas Lumley Assoc. Professor, Biostatistics > tlumley <at> u.washington.edu University of Washington, Seattle >I'm not expert but just looking at the package, perhaps the spMatrix function (constructor) would do it. spMatrix(5, 5, c(2:5, 1:5, 1:4), c(1:4, 1:5, 2:5), rnorm(13)) 5 x 5 sparse Matrix of class "dgTMatrix" [1,] -1.7109379 -0.5576860 . . . [2,] -0.3219899 -0.9294558 0.001323253 . . [3,] . 0.4099070 0.646068453 0.5388224 . [4,] . . -1.007848357 -0.1117796 -0.5555834 [5,] . . . -0.6816979 -0.6052127 Ken -- Ken Knoblauch Inserm U846 Stem-cell and Brain Research Institute Department of Integrative Neurosciences 18 avenue du Doyen L?pine 69500 Bron France tel: +33 (0)4 72 91 34 77 fax: +33 (0)4 72 91 34 61 portable: +33 (0)6 84 10 64 10 http://www.sbri.fr/members/kenneth-knoblauch.html
Then? : xxx <- data.frame(x1 =rnorm(5), offd= c(1:4,0) ) M <-Matrix(0,5,5) rrr <- dim(M)[1] for (rr in 1:rrr){ M[rr,rr] <- xxx$x1[rr] } for (rr in 1:(rrr-1)){ M[rr+1,rr] <- xxx$offd[rr] ; M[rr,rr+1] <- xxx $offd[rr]} > M 5 x 5 sparse Matrix of class "dgCMatrix" [1,] -1.494930 1.0000000 . . . [2,] 1.000000 -0.6439328 2.000000 . . [3,] . 2.0000000 1.428798 3.0000000 . [4,] . . 3.000000 -0.3874097 4.00000000 [5,] . . . 4.0000000 -0.07082702 David Winsemius On Feb 20, 2009, at 8:49 AM, Thomas Lumley wrote:> On Fri, 20 Feb 2009, David Winsemius wrote: > >> If you can tolerate the subdiagonal and superdiagonal zero elements >> being populated, then perhaps this is useful. If there is a subset >> function as you suggest, then perhaps further reduction would be >> feasible from this as a starting point. At least it would reduce >> the size from 10^5 x 10^5 to 10^5 x 3: >> >> library(Matrix) >> xxx <- data.frame(x1 =1:5, y1=c(0,6,0,7,0) ) >> M= Matrix(0,5,5) >> M[row(M) == col(M)] <- xxx$x1 >> M[row(M)-1 == col(M)] <- xxx$y1[1:(length(xxx$y1)-1)] >> M[row(M) == col(M)-1] <- xxx$y1[1:(length(xxx$y1)-1)] > > That provides the right structure, but row(M) and col(M) are dense > matrices with 10^10 elements, so it still uses too much memory. > > -thomas > > Thomas Lumley Assoc. Professor, Biostatistics > tlumley at u.washington.edu University of Washington, Seattle > >