2016-02-02 1 views
1

Я применяю 100 различных имитаций модели до 83 точек данных и изучая диапазон оценок от каждой моделируемой модели для каждой точки данных.Ускорение взятия точечного произведения всех пар строк и добавление термина перехвата

Каждый расчет сам по себе является произведением 342 переменных, умноженных на 342 коэффициента плюс добавленный перехват. Код, который я написал ниже, правильно вычисляет значения, но ужасно медленный. Есть ли способ улучшить скорость обработки?

spec = read.csv(spectra) 
coef = read.csv(coefficents) 

shell  = matrix(data=NA,ncol=101,nrow=nrow(spec)) 
shell  = as.data.frame(shell) 
heading = paste("Sim_",seq(1,100,1),sep="") 
names(shell)[1] = "Filename" 
names(shell)[2:101] = heading 

shell[1] = spec[1] 

for (i in 1:nrow(spec)) 
{ 
    for (j in 1:100) 
    { 
    shell[i,j+1] = sum(spec[i,2:341]*coef[j,3:342]) + coef[j,2] 
    } 
} 
+0

возможно дубликат http://stackoverflow.com/questions/2908822/speed-up-the-loop-operation-in-r – Megha

+2

http://stackoverflow.com/ Вопросы/5963269/How-to-make-a-great-r-воспроизводимый пример стоит прочитать первым - у нас нет 'spec'' shell' или 'coef', и поэтому он не может делать никаких конкретных предложений без представительные данные для воспроизведения. – thelatemail

+1

Вы добавили новые неизвестные объекты: 'спектры' и' коэффициенты' –

ответ

4

Действительно вы выполняете матричного умножения spec с транспонированной coef, а затем добавить константу для каждого столбца. Вы должны получить ускорение, используя встроенные функции умножения матриц %*% и векторизованные операции масштабирования столбцов:

out <- cbind(spec[,1], t(t(spec[,2:341] %*% t(coef[1:100,3:342])) + coef[1:100,2])) 

Выход этого 1-вкладыша идентичен выходу коды в исходном сообщении (слегка изменен, чтобы принять и выходные матрицы, а не устанавливать какие-либо имена):

OP <- function(spec, coef) { 
    shell = matrix(data=NA,ncol=101,nrow=nrow(spec)) 
    shell[,1] <- spec[,1] 
    for (i in 1:nrow(spec)) { 
    for (j in 1:100) { 
     shell[i,j+1] = sum(spec[i,2:341]*coef[j,3:342]) + coef[j,2] 
    } 
    } 
    shell 
} 
all.equal(out, OP(spec, coef)) 
# [1] TRUE 

с точки зрения времени работы, векторизованных операции дают значительную выгоду (38x), даже для этого относительно небольшого примера (1000 строк в spec):

system.time(cbind(spec[,1], t(t(spec[,2:341] %*% t(coef[1:100,3:342])) + coef[1:100,2]))) 
# user system elapsed 
# 0.028 0.001 0.030 
system.time(OP(spec, coef)) 
# user system elapsed 
# 0.927 0.224 1.161 

данных:

set.seed(144) 
spec <- matrix(rnorm(1000*341), nrow=1000) 
coef <- matrix(rnorm(100*342), nrow=100)