Ускорение расчета симметричных матриц;использование внешнего - PullRequest
0 голосов
/ 18 сентября 2018

Мне нужно ускорить расчет, который дает симметричную матрицу.В настоящее время у меня есть что-то вроде этого:

X <- 1:50
Y<- 1:50
M <- outer(X, Y, FUN = myfun)

, где myfun - довольно сложная, векторизованная, но симметричная функция (myfun (x, y) = myfun (y, x)).

Так что мой код излишне тратит время на вычисление нижней треугольной матрицы, а также верхней треугольной матрицы.

Как можно избежать такого дублирования без использования медленных циклов for?

1 Ответ

0 голосов
/ 18 сентября 2018

Если ваша функция медленная и время масштабируется в зависимости от размера ее ввода, вы можете использовать combn:

X <- 1:50
Y <- 1:50

#a slow function
myfun <- function(x, y) {
  res <- x * NA
  for (i in seq_along(x)) {
    Sys.sleep(0.01)
    res[i] <- x[i] * y[i]
    }
  res
}

system.time(M <- outer(X, Y, FUN = myfun))
#user  system elapsed 
#0.00    0.00   26.41 

system.time({
  inds <- combn(seq_len(length(X)), 2)
  M1 <- matrix(ncol = length(X), nrow = length(Y))

  M1[lower.tri(M1)] <-  myfun(X[inds[1,]], Y[inds[2,]])
  M1[upper.tri(M1)] <- t(M1)[upper.tri(M1)]
  diag(M1) <- myfun(X, Y)
})
#user  system elapsed 
#0.00    0.00   13.41

all.equal(M, M1)
#[1] TRUE

Однако, возможно, лучшее решение - реализовать это в C ++ через Rcpp.

...