2015-02-14 2 views
1

Я не могу придумать способ сделать этот код быстрее. Есть ли функция приложения, которая будет работать быстрее? Теперь я использую для каждого цикла цикл, чтобы запустить этот цикл параллельно, и он все еще занимает ОЧЕНЬ долгое время.способ ускорения этого умножения матрицы/матрицы? в R

ndraws=20000 
nhousehold=18831 
m=12 


    elasticitydraws = array(0,c(m,ndraws,nhousehold)) 
    MAPelasticity = matrix(0,nhousehold,m) 
    medianpricemat = matrix(rnorm(12,15,1),12,1)         


# dim(out$betadraw) = 18831, 12, 20000 
# dim(medianpricemat) = 12, 1 

    library(foreach) 
    library(doMC) 
    registerDoMC(10) 

    elasticitylist = foreach(i=1:nhousehold) %dopar% { 

      pricedraws = out$betadraw[i,12,] 
      elasticitydraws[,,i]= probarray[,,i] %*% diag(pricedraws) 
      elasticitydraws[,,i] = elasticitydraws[,,i] * as.vector(medianpricemat) 
      MAPelasticity[i,] = apply(elasticitydraws[,,i],1,mean) 

    } 
+1

пару мелких вещей: создать 'vecmp <-as.vector (medianpricemat)' вне петли, чтобы избежать пересчета; и я подозреваю, что ваш 'apply (elasticitydraws [,, i], 1, mean)' is just 'rowMeans()' –

+0

Спасибо Карлу, я исправлю это. Я думаю, что реальными медленными шагами являются вычисления второй и третьей строк (в цикле.) Есть ли способ сделать это с помощью применения или одного типа преобразования, чтобы сделать его просто линейным, а не циклическим? Библиотека – robertevansanders

+2

(Матрица) - ваш друг. Ваша проблема - матричное умножение. diag (costraws) создает на каждой итерации 20000 * 20000 плотную матрицу. Просто используйте разреженную диагональную матрицу, вместо этого код должен работать примерно в 20000 раз быстрее. Цикл foreach, вероятно, ухудшит вашу проблему, так как у вас закончится нехватка памяти. – klash

ответ

2

Узким местом в коде является создание большой плотной диагональной матрицы и матричного умножения с этим. Лучше использовать разреженную матрицу и пакет Matrix. Это экономит память и вычислительное время. Я также включил комментарии Карла и создал несколько векторов вне цикла.

library(Matrix) 

medianpricemat <- as.vector(medianpricemat) 
D1 <- Diagonal(x=pricedraws) 

elasticitylist = foreach(i=1:nhousehold) %dopar% { 
    pricedraws = out$betadraw[i,12,] 
    tmp = probarray[,,i] %*% D1 
    elasticitydraws[,,i] = as.matrix(tmp) * medianpricemat 
    MAPelasticity[i,] = rowMeans(elasticitydraws[,,i]) 
} 

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

D2 <- rep(pricedraws, each=m) 

elasticitylist = foreach(i=1:nhousehold) %dopar% { 
    pricedraws = out$betadraw[i,12,] 
    tmp = probarray[,,i] * D2 # element wise multiplication 
    elasticitydraws[,,i] = as.matrix(tmp) * medianpricemat 
    MAPelasticity[i,] = rowMeans(elasticitydraws[,,i]) 
} 
Смежные вопросы