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

R 相同的稀疏矩阵,不同的对象大小,r,sparse-matrix,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(b

我当时正在创建一些邻接矩阵,突然发现了一个奇怪的问题

我有一个满是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

然后我开始好奇。有人知道为什么会发生这种情况吗?

op1的类是
dsCMatrix
,而op2是
dgCMatrix
dsCMatrix
是一个对称矩阵类,因此只需要存储上半部分加上对角线(大约是完整矩阵的一半)

将稠密矩阵转换为稀疏矩阵的
Matrix
语句足够聪明,可以为对称矩阵选择对称类,因此节省了时间。您可以在函数
Matrix
的代码中看到这一点,该函数显式执行测试
isSym