есть ли быстрая функция кругового сдвига для многомерного массива в R - PullRequest
0 голосов
/ 08 января 2020

У меня есть три массива 4x4x1000 A, B, C. Я хочу объединить каждые 4x4 из A, B, C, чтобы сгенерировать 1 миллиард комбинаций. В настоящее время я пытаюсь циклически сдвинуть массив B и C по 3-му измерению, но мой код (на R) очень медленный и занимает ~ 6 минут, в то время как аналогичный код на matlab занимает всего ~ 4 с. Тем не менее, все мои другие коды находятся в R, и мне интересно, есть ли более быстрый способ запустить это в R? Большое спасибо.

m=4
n=1000
a1=array(runif(m*m*n,0,1), c(m,m,n))
a2=a1
a3=a1
Sys.time()
for (i in 1:n) {
  for (j in 1:n) {
    a3 = abind(a3[,,2:n],a3[,,1])
  }
  a2 = abind(a2[,,2:n],a2[,,1])

}
Sys.time()

1 Ответ

0 голосов
/ 08 января 2020
# more simplified example:
m = 2
n = 3
a1 = array(1:(m*m*n), c(m,m,n))
a1

Чтобы сделать «круговой сдвиг», нам не нужно физически изменять данные n раз. Мы можем просто вычислить конечные индексы и подмножество данных один раз.

Например, мы хотим сдвинуть 2 раза:

n3 <- 2
new_ind <- c((1:n)[-(1:n3)], (1:n)[1:n3]) # calculate indices
new_ind
# [1] 3 1 2

a2_v2 = a1[,,new_ind] # one subset
a2_v2
# , , 1
# 
# [,1] [,2]
# [1,]    9   11
# [2,]   10   12
# 
# , , 2
# 
# [,1] [,2]
# [1,]    1    3
# [2,]    2    4
# 
# , , 3
# 
# [,1] [,2]
# [1,]    5    7
# [2,]    6    8

PS Нет смысла сдвигать n (3 `d размер размера) раз, так как мы получим исходные данные (это то, что вы сделали в вашем примере).

...