여기에는 두 가지 문제가 있다고 생각합니다.
는 지금은
그런 다음이 작업을 수행하는 R 코드를 사용하지 않는 매우 큰 행렬 작업 할. R은 예상보다 훨씬 많은 메모리를 사용합니다. 다음 코드를 사용해보십시오 :
res.upper <- rnorm(4950)
res <- matrix(0, 100, 100)
tracemem(res) ## trace memory copies of `res`
res[upper.tri(res)] <- res.upper
rm(res.upper)
diag(res) <- 1
res[lower.tri(res)] <- t(res)[lower.tri(res)]
이 당신이 얻을 것이다 무엇 : R에서
> res.upper <- rnorm(4950) ## allocation of length 4950 vector
> res <- matrix(0, 100, 100) ## allocation of 100 * 100 matrix
> tracemem(res)
[1] "<0xc9e6c10>"
> res[upper.tri(res)] <- res.upper
tracemem[0xc9e6c10 -> 0xdb7bcf8]: ## allocation of 100 * 100 matrix
> rm(res.upper)
> diag(res) <- 1
tracemem[0xdb7bcf8 -> 0xdace438]: diag<- ## allocation of 100 * 100 matrix
> res[lower.tri(res)] <- t(res)[lower.tri(res)]
tracemem[0xdace438 -> 0xdb261d0]: ## allocation of 100 * 100 matrix
tracemem[0xdb261d0 -> 0xccc34d0]: ## allocation of 100 * 100 matrix
를 사용하면 이러한 작업을 완료 5 * (100 * 100) + 4950
두 단어를 사용합니다. C에서, 당신은 오직 4950 + 100 * 100
더블 단어 (사실, 100 * 100
전부가 필요합니다! 나중에 얘기 할 것입니다). 여분의 메모리 할당없이 R에서 객체를 직접 덮어 쓰는 것은 어렵습니다.
먼저 res
행렬을 초기화하지 않고 res.upper
을 대칭 행렬로 직접 변환 할 수있는 방법이 있습니까?
결국 res
에 메모리를 할당해야합니다. 그러나 res.upper
에 메모리를 할당 할 필요는 없습니다. 하단 삼각형을 동시에 채우면서 상단 삼각형을 초기화 할 수 있습니다. 다음 템플릿 고려해 성능이 저하 될 것이다 최 루프 어드레싱 정수 승산 j * n + i
을 사용하는 것으로,
#include <Rmath.h> // use: double rnorm(double a, double b)
#include <R.h> // use: getRNGstate() and putRNGstate() for randomness
#include <Rinternals.h> // SEXP data type
## N is matrix dimension, a length-1 integer vector in R
## this function returns the matrix you want
SEXP foo(SEXP N) {
int i, j, n = asInteger(N);
SEXP R_res = PROTECT(allocVector(REALSXP, n * n)); // allocate memory for `R_res`
double *res = REAL(R_res);
double tmp; // a local variable for register reuse
getRNGstate();
for (i = 0; i < n; i++) {
res[i * n + i] = 1.0; // diagonal is 1, as you want
for (j = i + 1; j < n; j++) {
tmp = rnorm(0, 1);
res[j * n + i] = tmp; // initialize upper triangular
res[i * n + j] = tmp; // fill lower triangular
}
}
putRNGstate();
UNPROTECT(1);
return R_res;
}
코드가 최적화되지 않았습니다. 그러나 내부 루프 외부로 곱셈을 이동하고 내부에 추가 만 남길 수 있다고 생각합니다.
필자는 컴파일 된 코드를 작성할 수 있으며 때로는 내 기능의 속도를 높이기 위해 수행합니다. 그러나, 나는 그것이 여분의 메모리를 사용하는 것을 피하는 방법을 정말로 이해하지 못한다. C/C++ 코드에서 위의 res와 같은 객체를 먼저 초기화합니다. 그것도 여분의 기억을 사용하지 않겠습니까? 또는 C/C++를 사용할 때 메모리 할당이이 언어에서 더 "지능적"이므로 문제가되지 않습니까? 그것은 어리석은 질문 일지 모르지만 저는 컴퓨터 과학자가 아닌 통계 학자입니다. 따라서 메모리 할당이 내부적으로 어떻게 작동하는지 모릅니다. – Lila
나를 위해 함수를 작성할 필요는 없지만 문제는 아닙니다. 나는 컴파일과 인라인 패키지에 익숙하다. 나는 그저 내 기억 문제를 해결하는 방법을 이해할 수있는 충분한 배경이 없다. 그러나 만약 당신이 그 기능을 쓰게 될 것이라고 확신한다면 (나는 코멘트 대신 답을 주면 답을 받아 들일 것입니다). – Lila
'bigmemory' 패키지에서'big.matrix'를 사용해 보셨습니까?메모리 제한 주위의 방법 일 수 있습니다 – konvas