Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 这个循环矢量化的方法?将两个矩阵相乘,存储信息,在不循环的情况下多次执行此操作_R_Loops_Matrix_Vectorization_Apply - Fatal编程技术网

R 这个循环矢量化的方法?将两个矩阵相乘,存储信息,在不循环的情况下多次执行此操作

R 这个循环矢量化的方法?将两个矩阵相乘,存储信息,在不循环的情况下多次执行此操作,r,loops,matrix,vectorization,apply,R,Loops,Matrix,Vectorization,Apply,假设(本例中的小数字)我有一个数组 3 x 14 x 5 叫这个 set.seed(1) dfarray=array(rnorm(5*3*14,0,1),dim=c(3,14,5)) 我有一个矩阵,它对应于这个 39 (which is 13*3) x 14 将此矩阵称为: dfmat = matrix(rnorm(13*3*14,0,1),39,14) dfmat = cbind(dfmat,rep(1:3,13)) dfmat = dfmat[order(dfmat [,15]),]

假设(本例中的小数字)我有一个数组

3 x 14 x 5
叫这个

set.seed(1)
dfarray=array(rnorm(5*3*14,0,1),dim=c(3,14,5))
我有一个矩阵,它对应于这个

39 (which is 13*3) x 14
将此矩阵称为:

dfmat = matrix(rnorm(13*3*14,0,1),39,14)
dfmat = cbind(dfmat,rep(1:3,13))
dfmat = dfmat[order(dfmat [,15]),]
colnames(dfmat)[15]='unit'
我要做的是运行此循环:

 costs = c(0.45, 2.11, 1.05, 1.44, 0.88, 2.30, 1.96, 1.76, 2.06, 1.54, 1.69,1.75,0)
    p = c(1,2,3,1,4,3,2,1,4,1,3,4,0)
    profit=numeric(0)
    for(i in 1:3){
            j=13
            beta = dfarray[i,,]
            Xt = dfmat [which(dfmat [,'unit']==i),1:14]    #this takes a set of 13, Xt is 13x14

            Xbeta = exp( Xt %*% beta )
            iota = c(rep(1, j))
            denom = iota%*%Xbeta
            Prob =  (Xbeta/ (iota%*%denom))
            Eprob = rowSums(Prob)/5  #the 5 coming from the last dim of array
            profit = c(profit,sum((p-costs)*Eprob))

        }


     sum(profit)  
我想不出一种方法来通过调用

beta = dfarray[i,,]
Xt = dfmat [which(dfmat [,'unit']==i),]   #this takes a set of 13, Xt is 13x14

为了让我在评论栏中的评论更清楚,假设我们有
dfmat
作为矩阵列表。使用矩阵列表几乎总是比使用一个大的命名矩阵更容易。此外,如果您想完全矢量化此处给出的解决方案,您可能希望使用作用于列表的
matrix
包中的
bdiag
获得块对角矩阵

set.seed(1)
dfarray=array(rnorm(5*3*14,0,1),dim=c(3,14,5))
# dfmats as a list of matrices
dfmats <- lapply(1:3, function(i)matrix(rnorm(13*14), nrow=13))
你的方法呢

profits1 <- function(){
    profit=numeric(0)
    for(i in 1:dim(dfarray)[1]){
        j=13
        beta = dfarray[i,,]
        Xt = dfmat [which(dfmat [,'unit']==i),1:14]    #this takes a set of 13, Xt is 13x14
        
        Xbeta = exp( Xt %*% beta )
        iota = c(rep(1, j))
        denom = iota%*%Xbeta
        deno <- colSums(Xbeta)
        s <- iota%*%denom
        Prob =  (Xbeta/ s)
        Eprob = rowSums(Prob)/dim(dfarray)[3]  #the 100 coming from the last dim of array
        profit = c(profit,Eprob)
        
    }
    return(profit)
}
dfmat <- do.call(rbind, dfmats)
dfmat <- cbind(dfmat,rep(1:3, each=13))
colnames(dfmat)[15]='unit'
基准 我在通过访问的AWS EC2免费tie实例上运行了这个

请注意,使用
列表
会带来异常的加速,并且会带来可怕的名称查找成本

system.time(a1 <- profits1())
#   user  system elapsed 
#250.885   4.442 255.394 
system.time(a <- profits())
#   user  system elapsed 
#  2.717   0.429   3.167 
all.equal(a, a1)
#[1] TRUE

system.time(a1)也可以将
dfmat
存储在一个3维数组中吗?是的,可以,有没有一种方法可以进行3d数组乘法?我正在编辑代码,所以现在它是可复制的,请耐心等待!看看
tensorA
包。它提供了
mul.tensor
函数。我想你需要使用<代码>通过该函数中的
参数,以便循环通过索引
i
。我现在将研究这个问题,代码现在是可复制的,顺便说一句!该函数类似于
mul.tensor(X,i=c(),Y,j=i,by=NULL)
X
Y
将是您的三维数组(在这种情况下,tensor objects)。使用
i
j
可以定义用于矩阵乘法的索引,
by
参数是循环变量(
i
)。
all.equal(profits(), profits1())
[1] TRUE
dfarray=array(rnorm(100*10000*14,0,1),dim=c(10000,14,100))
dfmats <- lapply(1:10000, function(i)matrix(rnorm(13*14), nrow=13))
dfmat <- do.call(rbind, dfmats)
dfmat <- cbind(dfmat,rep(1:10000, each=13))
colnames(dfmat)[15]='unit'
system.time(a1 <- profits1())
#   user  system elapsed 
#250.885   4.442 255.394 
system.time(a <- profits())
#   user  system elapsed 
#  2.717   0.429   3.167 
all.equal(a, a1)
#[1] TRUE