对于无法使用生成的矩阵,您无能为力。这是一个巨大的密集矩阵。您可以通过存储一些结果而不是重新计算和使用 tcrossprod 来加速 rdist.earth 函数:
library(fields)
rdist.earth2 <- function(x1, x2, miles = TRUE, R = NULL){
if (is.null(R)) {
if (miles)
R <- 3963.34
else R <- 6378.388
}
x1 <- x1 / 180
x2 <- x2 / 180
x1cs <- cbind(cospi(x1), sinpi(x1))
x2cs <- cbind(cospi(x2), sinpi(x2))
pp <- tcrossprod(cbind(x1cs[,1] * x1cs[,2], x1cs[,2] * x1cs[,3], x1cs[,4]),
cbind(x2cs[,1] * x2cs[,2], x2cs[,2] * x2cs[,3], x2cs[,4]))
pp <- pmin(pmax(-1, pp), 1)
matrix(R * acos(pp), nrow = nrow(x1), ncol = nrow(x2))
}
rlat <- function(n) runif(n, -90, 90)
rlong <- function(n) runif(n, -180, 180)
rlatlong <- function(n) cbind(rlong(n), rlat(n))
x1 <- rlatlong(1000)
x2 <- rlatlong(1000)
system.time(ans1 <- rdist.earth(x1, x2))
system.time(ans2 <- rdist.earth2(x1, x2))
identical(all.equal(ans1, ans2), TRUE)
我的速度提高了大约 30%,而且内存效率似乎也提高了一点。你也可以把它拆分并尝试并行。
library(iterator)
library(foreach)
ans3 <- foreach(b = iter(x1, by = 'row', chunksize = 100000L ), .combine='rbind') %do% rdist.earth2(b, x2)
identical(all.equal(ans1, ans3), TRUE)
您必须注册一个并行后端并将我的 %do% 替换为 %dopar%。这对速度没有多大帮助,但它可能会让您在您的机器上而不是在服务器上执行此操作,具体取决于您拥有多少内存。我可以在我的机器上用 16 Gb 的 RAM 做 1000000 * 1000。