我想就如何加快以下操作提出意见。
我有两个矩阵说A和B有n行3列;对于A的任何行向量,我想比较它与B的任何行向量的差异。因此,它是两个矩阵的所有行向量之间的成对差异。然后,得到的矩阵是n * n矩阵。然后我想将一个函数应用于我在该示例中编写的biharm()函数的任何元素。问题在于,对于小矩阵我没有问题,我有必要将这个操作应用于非常大的矩阵,如1000 * 3。在我写的sigm()函数中,我首先初始化S然后我写了两个为循环编写的。但是,对于大型矩阵来说这很慢。有没有人知道如何加快这个?我认为使用apply()但我无法弄清楚正确的方法。下面是一个完全可重复的例子。提前感谢任何建议。最好的,保罗。
biharm<-function(vec1,vec2){
reso<-norm(as.matrix(vec1)-as.matrix(vec2),type="F")^2*log(norm((as.matrix(vec1)-as.matrix(vec2)),type="F"))
reso
}
sigm<-function(mat1,mat2=NULL){
tt<-mat1
if(is.null(mat2)){yy<-mat1}else{yy<-mat2}
k<-nrow(yy)
m<-ncol(yy)
SGMr<-matrix(rep(0,k^2),ncol=k)
for(i in 1:k){
for(j in 1: k){
SGMr[i,j]<-biharm(yy[i,],tt[j,])
}}
SGMr<-replace(SGMr,which(SGMr=="NaN",arr.ind=T),0)
return(SGMr)}
### small matrices example:
A<-matrix(rnorm(30),ncol=3)
B<-matrix(rnorm(30),ncol=3)
sigm(A,B)
### large matrices example:
A<-matrix(rnorm(900),ncol=3)
B<-matrix(rnorm(900),ncol=3)
sigm(A,B)
答案 0 :(得分:1)
这比我的系统快8倍。
biharm.new <- function(vec1,vec2){
n <- sqrt(sum((vec1-vec2)^2))
n^2*log(n)
}
sigm.new<-function(mat1,mat2=NULL){
tt<-mat1
if(is.null(mat2)){yy<-mat1}else{yy<-mat2}
SGMr <- apply(tt,1,function(t)apply(yy,1,biharm.new,t))
replace(SGMr,which(SGMr=="NaN",arr.ind=T),0)
}
### large matrices example:
set.seed(1)
A<-matrix(rnorm(900),ncol=3)
B<-matrix(rnorm(900),ncol=3)
system.time(result.1<-sigm(A,B))
# user system elapsed
# 6.13 0.00 6.13
system.time(result.2<-sigm.new(A,B))
# user system elapsed
# 0.81 0.00 0.81
all.equal(result.1,result.2)
# [1] TRUE
apply(...)
的使用效果提高了约3倍。剩下的工作来自优化biharm(...)
- 因为你要拨打810,000次,所以要尽可能高效。
请注意,Frobenius规范只是欧几里德范数,所以如果您真正想要使用sqrt(sum(x^2))
而不是转换为矩阵并使用norm(...)
。前者很多更快。
答案 1 :(得分:0)
这个怎么样:
set.seed(1)
foo<-matrix(runif(30),nc=3)
bar<-matrix(runif(30),nc=3)
sapply(1:10,function(j) sapply(1:10,function(k) biharm(bar[k,],foo[j,])) )
编辑 - 与jhoward的“sigm.new”基本相同,没有错误检查。显然biharm.new
是胜利者。
microbenchmark(carl(foo,bar),jhoward(foo,bar),times=3)
Unit: milliseconds
expr min lq median uq max neval
carl(foo, bar) 5846.8273 6071.364 6295.8999 6322.425 6348.951 3
jhoward(foo, bar) 891.5734 934.550 977.5267 1008.388 1039.248 3