How to create a sparse diagonal matrix? - r

Might be a very silly question, but I cannot seem to find a proper way to create a sparse diagonal matrix in R.
I've found the functions:
diag.spam()
spdiags()
and used them with library Matrix and package spam downloaded, but R did not seem to recognize these functions. Does anyone know a function or library I need to download?
I need it because I want to create diagonal matrices larger than 256 by 256.

The Diagonal() function in the Matrix package. (Matrix is a "recommended" package, which means it is automatically available when you install R.)
library(Matrix)
m <- Diagonal(500)
image(m)
Diagonal(n) creates an n x n identity matrix. If you want to create a diagonal matrix with a specified diagonal x, use Diagonal(x=<your vector>)

Use bandSparse of the Matrix library.
to get an n-by-n matrix with m on its diagonal use, write:
bandSparse(n,n,0,list(rep(m, n+1)))

Related

Adjacent matrix from igraph package to be used for autologistic model in ngspatial package in R

I am interested on running an autologistic model in ngspatial package in R. My data objects are polygones. Usually, adjacency matrices for polygones are built up based on the coordinates of the polygones centroids. However, i have define my adjacency (0/1) based on a minimum distance criterium between polygones, measured from and to the border of each polygone. I have done this in arcmap, and then with igraph package i generated the Adjacency matrix:
g<-graph_from_data_frame(My data)
A<-as_adjacency_matrix(g, attr="Dist")
A
42 x 42 sparse Matrix of class "dgCMatrix"
[[ suppressing 42 column names ‘1’, ‘2’, ‘3’ ... ]]
My matrix is just 0 and 1 values, totally symmetric (42 x 42).
However, when i try to use it in a autologistic model in ngspatial i get an error messege:
ms_autolog<-autologistic(Occupancy~Area, A=A )
'You must supply a numeric and symmetric adjacency matrix'.
I supposed that dgCMatrix is just not compatible with ngspatial, but havent found how to convert it. I have also tried directly to shape my data.csv file as a matrix, read it as a matrix, but still it cannot be read by the autologistic model.
Does anybody has any idea how can i solve this?
Many thanks in advance!
Ana María.
It's difficult to check this without a minimal working example but you could try this:
A <- as_adjacency_matrix(g, attr = "Dist", sparse = F)
This way you get a binary matrix with 0 and 1 instead of a sparse matrix.

Huge diaginal matrix in R

The following code causes a memory error:
diag(1:100000)
Is there any alternative for diag which allows producing a huge diagonal matrix?
Longer answer: I suggest not creating a diagonal matrix, because in most situations you can do without it. To make that clear, consider the most typical matrix operations:
Multiply the diagonal matrix D by a vector v to produce Dv. Instead of maintaining a matrix, keep your "matrix" as a vector d of the diagonal elements, and then multiply d elementwise by v. Same result.
Invert the matrix. Again, easy: invert each element (of course, only for diagonal matrices is this generally the correct inverse).
Various decompositions/eigenvalues/determinants/trace. Again, these can all be done on the vector d.
In short, though it requires a bit of attention in your code, you can always represent a diagonal matrix as a vector, and that should solve your memory issues.
Shorter answer: Now, having said all that, of course people have already implemented the above steps implicitly using sparse matrices, which does the above steps under the hood. In R, the Matrix package is nice for sparse matrices: https://cran.r-project.org/web/packages/Matrix/Matrix.pdf

An efficient way to diagonalize a sparse vector in R

I'm working with a vector (~14000x1) of various values that I would like to put on the diagonal of a sparse matrix where I'm using the library Matrix. I want to do this while avoiding the need of creating a full matrix and then converting back to a sparse matrix after.
So far I can do this with a for loop but it takes a long time. Can you think of a more efficient and least memory-intense way of doing it?
Here's a simple reproducible example:
library(Matrix)
x = Matrix(matrix(1,14000,1),sparse=TRUE)
X = Diagonal(14000)
for(i in 1:13383){
X[i,i]=aa[i]
print(i)
}

Preallocate sparse matrix with max nonzeros in R

I'm looking to preallocate a sparse matrix in R (using simple_triplet_matrix) by providing the dimensions of the matrix, m x n, and also the number of non-zero elements I expect to have. Matlab has the function "spalloc" (see below), but I have not been able to find an equivalent in R. Any suggestions?
S = spalloc(m,n,nzmax) creates an all zero sparse matrix S of size m-by-n with room to hold nzmax nonzeros.
Whereas it may make sense to preallocate a traditional dense matrix in R (in the same way it is much more efficient to preallocate a regular (atomic) vector rather than increasing its size one by one,
I'm pretty sure it will not pay to preallocate sparse matrices in R, in most situations.
Why?
For dense matrices, you allocate and then assign "piece by piece", e.g.,
m[i,j] <- value
For sparse matrices, however that is very different: If you do something like
S[i,j] <- value
the internal code has to check if [i,j] is an existing entry (typically non-zero) or not. If it is, it can change the value, but otherwise, one way or the other, the triplet (i,j, value) needs to be stored and that means extending the current structure etc. If you do this piece by piece, it is inefficient... mostly irrespectively if you had done some preallocation or not.
If, on the other hand, you already know in advance all the [i,j] combinations which will contain non-zeroes, you could "pre-allocate", but in this case,
just store the vector i and j of length nnzero, say. And then use your underlying "algorithm" to also construct a vector x of the same length which contains all the corresponding values, i.e., entries.
Now, indeed, as #Pafnucy suggested, use spMatrix() or sparseMatrix(), two slightly different versions of the same functionality: Constructing a sparse matrix, given its contents.
I am happy to help further, as I am the maintainer of the Matrix package.

convert simple triplet matrix(slam) to sparse matrix(Matrix) in R

Is there a built-in function in either slam package or Matrix package to convert a sparse matrix in simple triplet matrix form (from slam package) to a sparse matrix in dgTMatrix/dgCMatrix form (from Matrix package) ?
And is there a built-in way to access non-zero entries from simple triplet matrix ?
I'm working in R
Actually, there is a built-in way:
simple_triplet_matrix_sparse <- sparseMatrix(i=simple_triplet_matrix_sparse$i, j=simple_triplet_matrix_sparse$j, x=simple_triplet_matrix_sparse$v,
dims=c(simple_triplet_matrix_sparse$nrow, simple_triplet_matrix_sparse$ncol))
From my own experience, this trick saved me tons of time and miseries, and computer crashing doing large-scale text mining using tm package. This question doesn't really need a reproducible example. A simple triplet matrix is a simple triplet matrix no matter what data it contains. This question is merely asking if there's a built-in function in either package to support conversion between the two.
slight modification. sparseMatrix takes integers as inputs, whereas slam takes i, j, as factors and v can be anything
as.sparseMatrix <- function(simple_triplet_matrix_sparse) {
sparseMatrix(
i = simple_triplet_matrix_sparse$i,
j = simple_triplet_matrix_sparse$j,
x = simple_triplet_matrix_sparse$v,
dims = c(
simple_triplet_matrix_sparse$nrow,
simple_triplet_matrix_sparse$ncol
),
dimnames = dimnames(simple_triplet_matrix_sparse)
)
}

Resources