2016-04-12 1 views
1

Je souhaite déterminer le produit scalaire entre la colonne i e dans une matrice et le i ème colonne dans une seconde matrice. Le résultat final sera un tableau contenant les produits i.calcul de produit scalaire-sage colonne entre deux matrices

Voici un exemple reproductible de ce que je veux faire:

#Generate two matrices with 10 columns each with 5 rows (thus i in this case is 10) 
m1 <- replicate(10, rnorm(5)) 
m2 <- replicate(10, rnorm(5)) 

#Inefficiently calculate dot product of ith column in m1 with ith column in m2 
d1 <- t(m1[,1]) %*% m2[,1] 
d2 <- t(m1[,2]) %*% m2[,2] 
... 
d10 <- t(m1[,10]) %*% m2[,10] 

#End with all dot products in array 
d.final <- c(d1, d2, d10) 

Toute aide ici sera appréciée!

Ken

+1

@ user20650 Arh J'ai mal lu son qn. Va supprimer le commentaire – chinsoon12

Répondre

2

Voici quelques options

L'option la plus claire (imo) est d'utiliser une boucle

out1 <- sapply(1:10, function(i) crossprod(m1[,i], m2[,i])) 

ou calculer le produit croisé pleine matrice

out2 <- diag(crossprod(m1, m2)) 

ou en additionnant la multiplication par éléments

out3 <- colSums(m1*m2) 

check

all.equal(out1, out2) 
all.equal(out3, out2) 

Un peu de référence

f1 <- function() sapply(1:ncol(m1), function(i) crossprod(m1[,i], m2[,i])) 
f2 <- function() diag(crossprod(m1, m2)) 
f3 <- function() colSums(m1*m2) 

# on your data 
microbenchmark::microbenchmark(f1(), f2(), f3()) 
# Unit: microseconds 
# expr min  lq  mean median  uq  max neval cld 
# f1() 62.508 65.2325 69.46337 66.873 70.9945 123.271 100 b 
# f2() 8.312 9.4290 12.05529 9.778 10.2670 229.708 100 a 
# f3() 11.385 12.4325 16.14248 12.921 13.5500 310.235 100 a 

# on bigger data 
m1 <- replicate(1000, rnorm(1000)) 
m2 <- replicate(1000, rnorm(1000)) 
all.equal(f1(), f2()) 
all.equal(f2(), f3()) 

microbenchmark::microbenchmark(f1(), f3()) #f2 took too long 
# Unit: milliseconds 
# expr  min  lq  mean median  uq  max neval cld 
# f1() 35.181220 38.065454 41.59141 39.93301 42.17569 82.13914 100 b 
# f3() 8.349807 9.220799 11.13763 10.19330 11.21829 53.57050 100 a 
+0

Ça l'a fait! Merci beaucoup. –

+0

vous êtes les bienvenus – user20650