2014-02-11 24 views
10

Ich brauche nur die Diagonalelemente aus einer Matrix-Multiplikation:berechnet nur Diagonalen der Matrix-Multiplikation in R

enter image description here,

in R. Da Z ist riesig ich die volle out Multiplikation vermeiden will ...

.
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 ist immer eine kleine quadratische Matrix (2x2, 3x3 oder 4x4), wobei Z die Anzahl der Spalten gleich die Dimension von X. gibt es eine Funktion zur Verfügung, dies zu tun hat?

Antwort

15

Das glaube ich nicht, dass Sie die erste Matrixmultiplikation vermeiden kann (dh ZX), aber man kann die zweite, die die teuer ist:

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

Die zweite Multiplikation ist NICHT eine Matrixmultiplikation. Dies ist viel schneller:

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 Wirklich nette Vorgehensweise. –

+0

@Marcinthebox, danke. Bis Sie upvoted ich fragte mich, ob jemand es bemerken würde! – BrodieG

+0

Ich musste meine eigenen Trial and Error-Erkundungen für eine Weile ausprobieren, bevor ich realisierte, was du lange entdeckt hast. Requisiten –

Verwandte Themen