2017-05-08 95 views
1

在R中,函數%*%是做矩陣乘法運算。 例如,定義一個函數,如'%*%`在R中操作矩陣R

A = matrix(c(1,2,1,1), ncol=2) 
B = matrix(c(3,0,1,0), ncol=2) 
C = A %*% B 

A 
    [,1] [,2] 
[1,] 1 1 
[2,] 2 1 
B 
    [,1] [,2] 
[1,] 3 1 
[2,] 0 0 
C 
    [,1] [,2] 
[1,] 3 1 
[2,] 6 2 

所以,C [1,1] = A [1,1] * B [1,1] + A [1,2] * B [2,1]。 C的其他元素也是以這種方式獲得的。

該功能的速度非常快。我想這個函數是用C或C++編寫的。

現在,我要定義一個名爲%!%使用R安置另一個功能,使d = A%%B. d的期望的結果應該是如下:

D = matrix(c(3,1,2,2), ncol=2, byrow=T) 
D 
    [,1] [,2] 
[1,] 3 1 
[2,] 2 2 

其中,

D[1, 1] = abs(A[1,1]-B[1,1]) + abs(A[1,2]-B[2,1]) 

D的其他條目的計算方式與第1條相同。

的分子式:

enter image description here

A的尺寸爲m乘n。 B的尺寸是n乘p。而m可能等於n。 n可能等於p。

那麼,如何定義這個%!%函數?目前,我已使用sapply定義了此功能。但是我的功能速度比%*%慢很多,我想知道是否還有其他更有效的方法。

這是我的定義。

`%!%` <- function(A, B) { 
    E <- sapply(1:ncol(t(A)), function(x){ 
    colSums(abs(B - t(A)[,x]), na.rm=TRUE) 
    }) 
    return(t(E)) 
} 
+0

Thx爲您的信息。 @李哲源ZheyuanLi –

+0

你沒有指定你的功能。你已經告訴我們在2x2的情況下有什麼1條目,其他3條未指定,而其他維度未定義。我大概可以解開它,但是我寧願你給出一個明確的定義而不是一個例子。 –

+0

其他條目的計算方式與第1條相同。查看我的更新。謝謝。 @JohnColeman –

回答

2

這是一個嘗試:

sum.abs.dif <- function(u,v){sum(abs(as.vector(u)-as.vector(v)))} 

`%!%` <- function(A,B){ 
    m <- nrow(A) 
    n <- ncol(A) #assumed == nrow(A) 
    p <- ncol(B) 
    indices <- expand.grid(1:m,1:p) 
    vals <- apply(indices,1,function(v) sum.abs.dif(A[v[1],],B[,v[2]])) 
    matrix(vals,nrow = m) 
} 

爲了比較的目的,我把你的代碼,並戲稱它%?%,然後跑了微基準(你的樣品A,B):

> library(microbenchmark) 
> microbenchmark(A %!% B, A %?% B) 
Unit: microseconds 
    expr  min  lq  mean median  uq  max neval 
A %!% B 180.142 188.813 196.50320 193.7675 198.8990 332.677 100 
A %?% B 43.532 47.602 54.55985 55.0340 57.3345 131.656 100 

因此,你的代碼是我的4倍。這讓我懷疑,你不太可能比現在有效得多(當然這並不是說它不能改進)。 %*%運行優化的編譯代碼。除非你做了C++擴展,否則你應該預期它比你所擁有的要快1或2個數量級。