我正在努力创建一些邻接矩阵,偶然发现了一个奇怪的问题。
我有一个矩阵满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
然后我好奇。有人知道为什么会这样吗?
答案 0 :(得分:4)
op1
的班级为dsCMatrix
,而op2
为dgCMatrix
。 dsCMatrix
是对称矩阵的类,因此只需要存储上半部分和对角线(大约是整个矩阵的一半数据)。
将密集转换为稀疏矩阵的Matrix
语句足够智能,可以为对称矩阵选择对称类,从而节省成本。您可以在函数Matrix
的代码中看到这一点,该函数显式执行测试isSym <- isSymmetric(data)
。
%*%
针对速度进行了优化,但未执行此检查。