Условное моделирование (с Кригингом) в R с распараллеливанием? - PullRequest
0 голосов
/ 25 мая 2018

Я использую пакет gstat в R для генерации последовательных гауссовых симуляций.Мой компьютер имеет 4 ядра, и я попытался распараллелить функцию krige (), используя параллельный пакет, следуя сценарию, предоставленному Гусман , чтобы ответить на вопрос Как добиться параллельного кригинга в R, чтобы ускорить процесс? .

Полученные симуляции, однако, отличаются от тех, которые используют только одно ядро ​​одновременно (без распараллеливания).Это выглядит проблема геометрии, но я не могу найти, как это исправить.

Далее я приведу пример (с использованием 4 ядер), генерирующий 2 симуляции.Вы увидите, что после запуска кода моделируемые карты, полученные из распараллеливания, показывают некоторые артефакты (например, вертикальные линии) и отличаются от тех, которые используют только одно ядро ​​в то время.

Для кода нужны библиотеки gstat, sp, raster, parallel и spatstat.Если какая-либо из строк library() не работает, сначала запустите install.packages().

library(gstat)
library(sp)
library(raster)
library(parallel)
library(spatstat)

# create a regular grid
nx=100 # number of columns
ny=100 # number of rows
srgr <- expand.grid(1:ny, nx:1)
names(srgr) <- c('x','y')
gridded(srgr)<-~x+y

# generate a spatial process (unconditional simulation)
g<-gstat(formula=z~x+y, locations=~x+y, dummy=T, beta=15, model=vgm(psill=3, range=10, nugget=0,model='Exp'), nmax=20)
sim <- predict(g, newdata=srgr, nsim=1)
r<-raster(sim)

# generate sample data (Poisson process)  
int<-0.02
rpp<-rpoispp(int,win=owin(c(0,nx),c(0,ny)))
df<-as.data.frame(rpp)
coordinates(df)<-~x+y 

# assign raster values to sample data
dfpp <-raster::extract(r,df,df=TRUE)
smp<-cbind(coordinates(df),dfpp)
smp<-smp[complete.cases(smp), ]
coordinates(smp)<-~x+y

# fit variogram to sample data
vs <- variogram(sim1~1, data=smp)
m <- fit.variogram(vs, vgm("Exp"))
plot(vs, model = m)

# generate 2 conditional simulations with one core processor
one <- krige(formula = sim1~1, locations = smp, newdata = srgr, model = m,nmax=12,nsim=2)

# plot simulation 1 and 2: statistics (min, max) are ok, simulations are also ok.
spplot(one["sim1"], main = "conditional simulation")
spplot(one["sim2"], main = "conditional simulation")

# generate 2 conditional with parallel processing
no_cores<-detectCores()
cl<-makeCluster(no_cores)
parts <- split(x = 1:length(srgr), f = 1:no_cores)
clusterExport(cl = cl, varlist = c("smp", "srgr", "parts","m"), envir = .GlobalEnv)
clusterEvalQ(cl = cl, expr = c(library('sp'), library('gstat')))
par <- parLapply(cl = cl, X = 1:no_cores, fun = function(x) krige(formula=sim1~1, locations=smp, model=m, newdata=srgr[parts[[x]],],  nmax=12, nsim=2))
stopCluster(cl)

# merge all parts    
mergep <- maptools::spRbind(par[[1]], par[[2]])
mergep <- maptools::spRbind(mergep, par[[3]])
mergep <- maptools::spRbind(mergep, par[[4]])

# create SpatialPixelsDataFrame from mergep
mergep <- SpatialPixelsDataFrame(points = mergep, data = mergep@data)

# plot mergep: statistics (min, max) are ok, but simulated maps show "vertical lines". i don't understand why.
spplot(mergep[1], main = "conditional simulation")
spplot(mergep[2], main = "conditional simulation")

1 Ответ

0 голосов
/ 25 мая 2018

Я попробовал ваш код, и я думаю, что проблема заключается в том, как вы разбили работу:

parts <- split(x = 1:length(srgr), f = 1:no_cores)

На моей двухъядерной машине это означало, что все нечетные индексы в srgr обрабатывались одним процессом ивсе четные индексы обрабатываются другим процессом.Вероятно, это источник вертикальных артефактов, которые вы видите.

Лучше было бы разбить данные на последовательные фрагменты, например:

parts <- parallel::splitIndices(length(srgr), no_cores)

Использование этого разделения с остальнымиВаш код я получаю результаты, которые выглядят сопоставимыми с последовательными.По крайней мере, для моих неподготовленных глаз ...


Оригинальный ответ, который является лишь незначительным эффектом.Возможно, имеет смысл исправить начальное число с помощью set.seed для последовательной обработки и clusterSetRNGStream для параллельной обработки.

Из того, что я прочитал о Кригинге, требуется рисовать случайные числа.Эти случайные числа будут отличаться при параллельной обработке.Подробнее см. Раздел 6 параллельной виньетки (vignette("parallel")).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...