相同的稀疏矩阵,不同的对象大小

时间:2017-11-27 17:07:24

标签: r sparse-matrix

我正在努力创建一些邻接矩阵,偶然发现了一个奇怪的问题。

我有一个矩阵满1和0。我希望将它的转置乘以它(t(X) %*% X),然后运行其他一些东西。由于例程开始变得非常慢,我将其转换为稀疏矩阵,显然变得更快。

然而,稀疏矩阵的大小是我将矩阵转换为稀疏格式时的两倍。

以下是一些遇到同一问题的通用示例

set.seed(666)
nr = 10000
nc = 1000

bb = matrix(rnorm(nc *nr), ncol = nc, nrow = nr)
bb = apply(bb, 2, function(x) x = as.numeric(x > 0))

# Slow and unintelligent method
op1  = t(bb) %*% bb
op1  = Matrix(op1, sparse = TRUE) 

# Fast method
B   = Matrix(bb, sparse = TRUE) 
op2 = t(B) %*% B

# weird
identical(op1, op2) # returns FALSE
object.size(op2)
#12005424 bytes
object.size(op1) # almost half the size
#6011632 bytes

# now it works...
ott1 = as.matrix(op1)
ott2 = as.matrix(op2)

identical(ott1, ott2) # returns TRUE

然后我好奇。有人知道为什么会这样吗?

1 个答案:

答案 0 :(得分:4)

op1的班级为dsCMatrix,而op2dgCMatrixdsCMatrix是对称矩阵的类,因此只需要存储上半部分和对角线(大约是整个矩阵的一半数据)。

将密集转换为稀疏矩阵的Matrix语句足够智能,可以为对称矩阵选择对称类,从而节省成本。您可以在函数Matrix的代码中看到这一点,该函数显式执行测试isSym <- isSymmetric(data)

另一方面,

%*%针对速度进行了优化,但未执行此检查。