2014-02-11 5 views
10

мне нужно только диагональные элементы матрицы умножения:вычислительные только диагональные матрицы умножения в R

enter image description here,

в R. Поскольку Z огромна, я хочу, чтобы избежать полного выхода умножения ... .

Z <- matrix(c(1,1,1,2,3,4), ncol = 2) 
Z 
#  [,1] [,2] 
#[1,] 1 2 
#[2,] 1 3 
#[3,] 1 4 

X <- matrix(c(10,-5,-5,20), ncol = 2) 
X 
#  [,1] [,2] 
#[1,] 10 -5 
#[2,] -5 20 

Z %*% D %*% t(Z) 
#  [,1] [,2] [,3] 
#[1,] 70 105 140 
#[2,] 105 160 215 
#[3,] 140 215 290 

diag(Z %*% D %*% t(Z)) 
#[1] 70 160 290 

X всегда небольшая квадратная матрица (2x2, 3x3 или 4x4), где Z будет иметь число столбцов, равное размерности X. есть функция доступна, чтобы сделать это?

ответ

15

Я не думаю, что вы можете избежать первого матричного умножения (т.е. ZX), но вы можете второй один, который является дорогой:

rowSums((Z %*% X) * Z) 
# [1] 70 160 290 

Второе умножение НЕ матрица умножения. Это намного быстрее:

library(microbenchmark) 
set.seed(1) 
X <- matrix(c(10,-5,-5,20), ncol = 2) 
Z <- matrix(sample(1:1000), ncol=2) # made Z a little bigger  

microbenchmark(
    res.new <- rowSums((Z %*% X) * Z), # this solution 
    res.old <- diag(Z %*% X %*% t(Z)) # original method 
) 
# Unit: microseconds 
#        expr  min  lq  mean median  uq  max neval 
# res.new <- rowSums((Z %*% X) * Z) 20.956 23.233 34.77693 29.6150 44.0025 67.852 100 
# res.old <- diag(Z %*% X %*% t(Z)) 571.214 699.247 1761.08885 760.4295 1188.4485 47488.543 100  

all.equal(res.new, res.old) 
# [1] TRUE 
+0

+1 Действительно хороший подход. –

+0

@Marcinthebox, спасибо. Пока вы не поддержали меня, мне было интересно, заметит ли кто-нибудь! – BrodieG

+0

Я должен был попробовать свои собственные пробные и поисковые ошибки на некоторое время, прежде чем я понял, что вы давно обнаружили. Опоси –

Смежные вопросы