Я хочу умножить несколько матриц одинакового размера на начальный вектор.В приведенном ниже примере p.state
является вектором m
элементов, а tran.mat
является списком, где каждый элемент является m x m
матрицей.
for (i in 1:length(tran.mat)){
p.state <- p.state %*% tran.mat[[i]]
}
Приведенный выше код дает правильный ответ, но может быть медленным, если length(tran.mat)
велико.Мне было интересно, есть ли более эффективный способ сделать это?
Ниже приведен пример с m=3
и length(mat)=10
, который может генерировать это:
p.state <- c(1,0,0)
tran.mat<-lapply(1:10,function(y){apply(matrix(runif(9),3,3),1,function(x){x/sum(x)})})
for (i in 1:length(tran.mat)){
p.state <- p.state %*% tran.mat[[i]]
}
print(p.state)
NB: tran.mat
не обязательно должен быть списком, он просто записан как единое целое.
Редактировать после нескольких комментариев:
Reduce
полезно, когда m
мало.Однако при m=6
выход из цикла выполнил оба вышеупомянутых решения.библиотека (rbenchmark)
p.state1 <- p.state <- c(1,0,0,0,0,0)
tran.mat<-lapply(1:10000,function(y){t(apply(matrix(runif(36),6,6),1,function(x){x/sum(x)}))})
tst<-do.call(c, list(list(p.state), tran.mat))
benchmark(
'loop' = {
for (i in 1:length(tran.mat)){
p.state <- p.state %*% tran.mat[[i]]
}
},
'reduce' = {
p.state1 %*% Reduce('%*%', tran.mat)
},
'reorder' = {
Reduce(`%*%`,tran.mat,p.state1)
}
)
В результате
test replications elapsed relative user.self sys.self user.child sys.child
1 loop 100 0.87 1.000 0.87 0 NA NA
2 reduce 100 1.41 1.621 1.39 0 NA NA
3 reorder 100 1.00 1.149 1.00 0 NA NA