英文:
How to create a diagonal matrix from a sparse Vector
问题
假设 x
被定义为
x <- as(c(1,1,0,0,1,0), "sparseVector")
我想创建一个对角矩阵,其中对角元素由 x
中的条目给出。
我尝试过 Diagonal(x = x)
,但我收到以下错误。
Error in Diagonal(x = x) : 'x' has unsupported class "dsparseVector"
英文:
Suppose x
is defined as
x <- as(c(1,1,0,0,1,0), "sparseVector")
I want to create a diagonal matrix where the diagonal elements are given by the entries in x
.
I tried Diagonal(x = x)
, but I get the following error.
Error in Diagonal(x = x) : 'x' has unsupported class "dsparseVector"
答案1
得分: 3
我认为你正在寻找 sparseMatrix
。例如:
library(Matrix)
x <- c(1,1,0,0,1,0)
x <- sparseMatrix(i = seq(x), j = seq(x), x = x)
x
# 6 x 6 sparse Matrix of class "dgCMatrix"
#
# [1,] 1 . . . . .
# [2,] . 1 . . . .
# [3,] . . 0 . . .
# [4,] . . . 0 . .
# [5,] . . . . 1 .
# [6,] . . . . . 0
要将原始向量中的零视为稀疏元素:
x <- c(1,1,0,0,1,0)
x <- sparseMatrix(i = which(x!=0), j = which(x!=0), x = x[which(x!=0)],
dims = rep(length(x), 2))
x
# 6 x 6 sparse Matrix of class "dgCMatrix"
#
# [1,] 1 . . . . .
# [2,] . 1 . . . .
# [3,] . . . . . .
# [4,] . . . . . .
# [5,] . . . . 1 .
# [6,] . . . . . .
英文:
I think you are looking for sparseMatrix
. e.g.:
library(Matrix)
x <- c(1,1,0,0,1,0)
x <- sparseMatrix(i = seq(x), j = seq(x), x = x)
x
# 6 x 6 sparse Matrix of class "dgCMatrix"
#
# [1,] 1 . . . . .
# [2,] . 1 . . . .
# [3,] . . 0 . . .
# [4,] . . . 0 . .
# [5,] . . . . 1 .
# [6,] . . . . . 0
To treat zeros in the original vector as sparse elements:
x <- c(1,1,0,0,1,0)
x <- sparseMatrix(i = which(x!=0), j = which(x!=0), x = x[which(x!=0)],
dims = rep(length(x), 2))
x
# 6 x 6 sparse Matrix of class "dgCMatrix"
#
# [1,] 1 . . . . .
# [2,] . 1 . . . .
# [3,] . . . . . .
# [4,] . . . . . .
# [5,] . . . . 1 .
# [6,] . . . . . .
答案2
得分: 3
您可以将“Diagonal”矩阵与您的稀疏向量相乘:
Diagonal(length(x)) * x
#6 x 6 sparse Matrix of class "dgCMatrix"
#
#[1,] 1 . . . . .
#[2,] . 1 . . . .
#[3,] . . . . . .
#[4,] . . . . . .
#[5,] . . . . 1 .
#[6,] . . . . . .
英文:
You can multiply the Diagonal
matrix with your sparse vector:
Diagonal(length(x)) * x
#6 x 6 sparse Matrix of class "dgCMatrix"
#
#[1,] 1 . . . . .
#[2,] . 1 . . . .
#[3,] . . . . . .
#[4,] . . . . . .
#[5,] . . . . 1 .
#[6,] . . . . . .
答案3
得分: 2
可以使用sparseMatrix从x的组件构建它,创建一个dgCMatrix对象:
sparseMatrix(x@i, x@i, x = x@x, dims = c(x@length, x@length))
结果为:
6 x 6 稀疏矩阵,类别为 "dgCMatrix"
[1,] 1 . . . . .
[2,] . 1 . . . .
[3,] . . . . . .
[4,] . . . . . .
[5,] . . . . 1 .
[6,] . . . . . .
注意
library(Matrix)
x <- as(c(1, 1, 0, 0, 1, 0), "sparseVector")
英文:
It can be constructed from the components of x using sparseMatrix creating an object of dgCMatrix:
sparseMatrix(x@i, x@i, x = x@x, dims = c(x@length, x@length))
giving:
6 x 6 sparse Matrix of class "dgCMatrix"
[1,] 1 . . . . .
[2,] . 1 . . . .
[3,] . . . . . .
[4,] . . . . . .
[5,] . . . . 1 .
[6,] . . . . . .
Note
library(Matrix)
x <- as(c(1, 1, 0, 0, 1, 0), "sparseVector")
答案4
得分: 0
你想要 Diagonal(x = as.vector(<sparseVector>))
。话虽如此,可以合理地期望 Diagonal(x = <sparseVector>)
做相同的事情。也许这是对 Matrix 1.6-1 的功能请求...
无论如何,结果将是一个继承自 diagonalMatrix
并显式存储对角线上的零的对象。是的,这是"次优"的,但作为回报,您可以受益于高度优化的 diagonalMatrix
方法。
如果您只关心对象大小,为什么不保留 sparseVector
表示?
library(Matrix)
set.seed(0)
n <- 1e+06L
x0 <- sample(c(0, 1), size = n, replace = TRUE, prob = c(1000, 1))
x <- as(x0, "sparseVector")
l <- list(x0 = x0, x = x,
D = Diagonal(x = as.vector(x)),
C = sparseMatrix(i = x@i, j = x@i, x = x@x, dims = rep.int(x@length, 2L),
triangular = TRUE, repr = "C"),
R = sparseMatrix(i = x@i, j = x@i, x = x@x, dims = rep.int(x@length, 2L),
triangular = TRUE, repr = "R"),
T = sparseMatrix(i = x@i, j = x@i, x = x@x, dims = rep.int(x@length, 2L),
triangular = TRUE, repr = "T"))
cl <- vapply(l, class, "")
os <- vapply(l, object.size, 0)
data.frame(class = cl, bytes = os, ratio = os/min(os))
class bytes ratio
x0 numeric 8000048 651.894394
x dsparseVector 12272 1.000000
D ddiMatrix 8001240 651.991525
C dtCMatrix 4013064 327.009778
R dtRMatrix 4013064 327.009778
T dtTMatrix 16816 1.370274
n. <- as.double(n) # 避免在 rsparsematrix 中整数溢出... 修复
M <- rsparsematrix(n., n., 1/n.)
with(l, microbenchmark::microbenchmark(D %*% M, C %*% M, R %*% M, T %*% M))
Unit: milliseconds
expr min lq mean median uq max neval
D %*% M 6.028189 6.502477 6.89017 6.680889 7.13894 10.35902 100
C %*% M 20.564288 20.793950 21.03865 20.909795 21.07154 24.19648 100
R %*% M 21.509297 21.793222 22.63789 22.000969 22.49524 63.59588 100
T %*% M 22.943067 23.205651 24.18345 23.497592 24.09761 64.76713 100
英文:
You want Diagonal(x = as.vector(<sparseVector>))
. Having said that, it is reasonable to expect Diagonal(x = <sparseVector>)
to do the same thing. Maybe that is a feature request for Matrix 1.6-1 ...
In any case, the result will be an object inheriting from diagonalMatrix
and storing zeros on the diagonal explicitly. Yes, that is "suboptimal", but, in exchange, you benefit from highly optimized methods for diagonalMatrix
.
If you are only interested in object size, then why not keep the sparseVector
representation?
library(Matrix)
set.seed(0)
n <- 1e+06L
x0 <- sample(c(0, 1), size = n, replace = TRUE, prob = c(1000, 1))
x <- as(x0, "sparseVector")
l <- list(x0 = x0, x = x,
D = Diagonal(x = as.vector(x)),
C = sparseMatrix(i = x@i, j = x@i, x = x@x, dims = rep.int(x@length, 2L),
triangular = TRUE, repr = "C"),
R = sparseMatrix(i = x@i, j = x@i, x = x@x, dims = rep.int(x@length, 2L),
triangular = TRUE, repr = "R"),
T = sparseMatrix(i = x@i, j = x@i, x = x@x, dims = rep.int(x@length, 2L),
triangular = TRUE, repr = "T"))
cl <- vapply(l, class, "")
os <- vapply(l, object.size, 0)
data.frame(class = cl, bytes = os, ratio = os/min(os))
class bytes ratio
x0 numeric 8000048 651.894394
x dsparseVector 12272 1.000000
D ddiMatrix 8001240 651.991525
C dtCMatrix 4013064 327.009778
R dtRMatrix 4013064 327.009778
T dtTMatrix 16816 1.370274
n. <- as.double(n) # avoid integer overflow in rsparsematrix ... FIXME
M <- rsparsematrix(n., n., 1/n.)
with(l, microbenchmark::microbenchmark(D %*% M, C %*% M, R %*% M, T %*% M))
Unit: milliseconds
expr min lq mean median uq max neval
D %*% M 6.028189 6.502477 6.89017 6.680889 7.13894 10.35902 100
C %*% M 20.564288 20.793950 21.03865 20.909795 21.07154 24.19648 100
R %*% M 21.509297 21.793222 22.63789 22.000969 22.49524 63.59588 100
T %*% M 22.943067 23.205651 24.18345 23.497592 24.09761 64.76713 100
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论