ゲームに少し遅れましたが、誰かが最速と言いましたか?! これは、 のもう 1 つの有効な使い方ですRcpp
。この関数 ( と呼ばれるmmult
) は、デフォルトで、行列の各列をベクトルの連続する各要素で乗算しますが、 を設定することにより、列ごとにこれを行うオプションがありますbyrow = FALSE
。m
また、とv
がオプションで適切なサイズであることも確認しbyrow
ます。とにかく、それは速いです(最高のネイティブRの回答よりも約10〜12倍速いです)...
編集
@chrisは、これを機能させるために私が提起した別の質問に対して、この素晴らしい回答を提供RcppArmadillo
。ただし、Rcpp
ここに投稿した -only 関数は、それでも約 8 倍高速であり、OP メソッドよりも約 70 倍高速であるようです。@chris' 関数のコードのリンクをクリックしてください。これは非常にシンプルです。
ベンチマークを一番上に置きます..
require( microbenchmark )
m <- microbenchmark( mat %*% diag(v) , mmult( mat , v ) , sweep(mat, 2, v, FUN = "*") , chris( mat , v ) , t( t(mat) * v ) , times = 100L )
print( m , "relative" , order = "median" , digits = 3 )
Unit: relative
expr min lq median uq max neval
mmult(mat, v) 1.00 1.00 1.00 1.00 1.00 100
chris(mat, v) 10.74 9.31 8.15 7.27 10.44 100
t(t(mat) * v) 9.65 8.75 8.30 15.33 9.52 100
sweep(mat, 2, v, FUN = "*") 20.51 18.35 22.18 21.39 16.94 100
mat %*% diag(v) 80.44 70.11 73.12 70.68 54.96 100
ブラウズして、どのようにmmult
動作し、OP と同じ結果を返すかを確認してください...
require( Rcpp )
# Source code for our function
func <- 'NumericMatrix mmult( NumericMatrix m , NumericVector v , bool byrow = true ){
if( byrow );
if( ! m.nrow() == v.size() ) stop("Non-conformable arrays") ;
if( ! byrow );
if( ! m.ncol() == v.size() ) stop("Non-conformable arrays") ;
NumericMatrix out(m) ;
if( byrow ){
for (int j = 0; j < m.ncol(); j++) {
for (int i = 0; i < m.nrow(); i++) {
out(i,j) = m(i,j) * v[j];
}
}
}
if( ! byrow ){
for (int i = 0; i < m.nrow(); i++) {
for (int j = 0; j < m.ncol(); j++) {
out(i,j) = m(i,j) * v[i];
}
}
}
return out ;
}'
# Make it available
cppFunction( func )
# Use it
res1 <- mmult( m , v )
# OP function
res2 <- mat %*% diag(v)
# Same result?
identical( res1 , res2 ) # Yes!!
[1] TRUE