2017-05-08 98 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个数量级。