如何修改我的R代码以加快计算速度

时间:2017-11-25 08:48:03

标签: r

这是我的R代码。能不能给我一些建议,以便加快计算速度:)

首先,函数myfun()生成一个复数。

其次,我使用myfun()来计算矩阵M的元素。

myfun<-function(a,b,nq,ul,uk)
 {
   m<-seq(1,(nq/2)+1,length=(nq/2)+1);
   k<-m;

   D<-matrix(NA,nrow = length(k),ncol = length(k)); 

  for(i in 1:length(k)) # row
    for(j in 1:length(m)) # column
    {
      D[i,j]<-(2/nq)*cos(((j-1)*(i-1)*pi)/(nq*0.5))
    }

    D[,1]<-D[,1]*0.5;
    D[,ncol(D)]<-D[,ncol(D)]*0.5;   

    # compute the vector v
    vseq<-seq(2,nq-2,by=2);
    vr<-2/(1-vseq^2);
    vr<-c(1,vr,1/(1-nq*nq));
    v<-matrix(vr,ncol=1);  # v is a N by 1 matrix

    # compute the vector w, length(w)=nq/2+1

    h<-function(x,ul,uk)
     {
      ((b-a)/2)*(exp((b-a)/2*x+(a+b)/2)+1)^(1i*uk)*cos(((b-a)/2*x+(a+b)/2-a)*ul)
     }

     w<-matrix(rep(NA,length(v)),ncol=1);

     for(i in 1:length(w))
      {
        w[i]<-h((cos((i-1)*pi/nq)),ul,uk)+h((-cos((i-1)*pi/nq)),ul,uk)
      }

      res<-t(t(D)%*%v)%*%w; # each element of matrix M

      return(res)
      }

接下来,计算矩阵M的每个元素。第N列和第N行是零。

   matrix.M<-matrix(0,ncol = N,nrow = N);

   for(i in 1:N-1)
    for(j in 1:N-1)
   {
    matrix.M[i,j]<-myfun(a,b,nq,i-1,j-1)
   }

我们可以将参数设置为

   a<--173.2;
   b<-78;
   alpha<-0.24;
   Dt<-0.1;
   M<-1000;
   N<-150;
   u<-seq(1,150,by=1)*pi/(b-a);
   nq<-3000;

感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

以下是加速功能的一些建议。我使用了三个&#34;技巧&#34;:

  1. 向量化尽可能多的功能
  2. 使用outer功能代替双循环
  3. 将隐藏的宝石crossprod用于最终的矩阵产品

    myfun&lt; -function(a,b,nq,ul,uk){     米&LT; -SEQ(1,(NQ / 2)+ 1,长度=(NQ / 2)+1);     K&LT; -m;

    ## Use outer to compute the elements of the matrix
    D <- outer(1:length(k), 1:length(m), function(i, j) {(2/nq)*cos(((j-1)*(i-1)*pi)/(nq*0.5))} )
    
    D[,1]<-D[,1]*0.5;
    D[,ncol(D)]<-D[,ncol(D)]*0.5;
    
                                        # compute the vector v                                                                             
    vseq<-seq(2,nq-2,by=2);
    vr<-2/(1-vseq^2);
    vr<-c(1,vr,1/(1-nq*nq));
    v<-matrix(vr,ncol=1);  # v is a N by 1 matrix                                                                                          
    
    h<-function(x,ul,uk) {
        ((b-a)/2)*(exp((b-a)/2*x+(a+b)/2)+1)^(1i*uk)*cos(((b-a)/2*x+(a+b)/2-a)*ul)
    }
    
    ## Compute the full w vector in one go    
    vect <- seq_along(v)-1
    w <- h((cos(vect*pi/nq)),ul,uk) + h((-cos(vect*pi/nq)),ul,uk)
    
    ## Compute the cross products. 
    res <- crossprod(crossprod(D, v), w)
    
    return(res)
    

    }

  4. 我认为与原始功能相比,这应该节省大约80%的时间。时间耗费是D的初始计算。希望这会有所帮助。