如何从稀疏向量创建对角矩阵

3
假设定义了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"
4个回答

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,] . . . . . .

是否可以获取沿对角线元素的稀疏表示。这就是我想要得到的(当前输出显示0而不是点)。 - shani
是否可以同时获得对角元素的稀疏表示?这就是我想要得到的(当前输出显示0而不是点)。 - shani
2
更新了将零视为稀疏元素的示例 - Marc in the box
2
更新了将零视为稀疏元素的示例。 - Marc in the box

3
你可以将对角矩阵与稀疏向量相乘:
Diagonal(length(x)) * x
#6 x 6 sparse Matrix of class "dgCMatrix"
#                
#[1,] 1 . . . . .
#[2,] . 1 . . . .
#[3,] . . . . . .
#[4,] . . . . . .
#[5,] . . . . 1 .
#[6,] . . . . . .

2
可以使用sparseMatrix函数从x的组件构建一个dgCMatrix对象。
sparseMatrix(x@i, x@i, x = x@x, dims = c(x@length, x@length))

提供:

6 x 6 sparse Matrix of class "dgCMatrix"
                
[1,] 1 . . . . .
[2,] . 1 . . . .
[3,] . . . . . .
[4,] . . . . . .
[5,] . . . . 1 .
[6,] . . . . . .

注意
library(Matrix)
x <- as(c(1, 1, 0, 0, 1, 0), "sparseVector")

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) # 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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接