2017-11-27 6 views
3

일부 인접 행렬을 만드는 중이고 이상한 문제가 발생했습니다.동일한 스파 스 매트릭스, 다른 객체 크기

1 개의 행렬이 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 

가 그럼 난 호기심을 가지고 같은 문제로 실행하는 몇 가지 일반적인 예이다. 왜 이런 일이 일어나는 지 압니까?

답변

4

op1의 클래스는 dsCMatrix이고, op2dgCMatrix입니다. dsCMatrix은 대칭 행렬의 클래스이므로 상반부와 대각선 (전체 행렬의 절반 정도의 데이터) 만 저장하면됩니다.

고밀도 매트릭스를 고밀도 매트릭스로 변환하는 명령문은 대칭 행렬에 대해 대칭 클래스를 선택할 정도로 똑똑하기 때문에 절약 할 수 있습니다. 이 코드는 isSym <- isSymmetric(data) 테스트를 명시 적으로 수행하는 Matrix 코드에서 볼 수 있습니다. 반면에 속도를 최적화하고이 검사를 수행하지 않습니다.

%*%