编写Fortran矩阵乘法子程序以在R中调用

编写Fortran矩阵乘法子程序以在R中调用,r,fortran,R,Fortran,我想写一个Fortran子程序,它可以做一些矩阵乘法。我使用R创建输入: set.seed(7232015) ############# # meta data # ############# B <- 200 # (actually millions) D <- 100 # number of markov chain monte carlo draws (actually 4,000) T <- 8 # number of quarters #########

我想写一个Fortran子程序,它可以做一些矩阵乘法。我使用R创建输入:

set.seed(7232015)
#############
# meta data #
#############
B <- 200  # (actually millions)
D <- 100  # number of markov chain monte carlo draws (actually 4,000)
T <- 8    # number of quarters

#########
# input #
#########
input <- data.frame(
    treat = sample(0:1, B, T), # treatment indicator
    time = sample(1:T, B, T),  # time
    weight = rnorm(B),         # weight
    pred = rnorm(B),           # predictions (x \hat\beta)
    eresid = exp(rnorm(B))
)    # exp(resid) exp(y - x \hat\beta)

thetaTime <- matrix(rnorm(T * D), T, D) # time-by-treatment intrxn
theta <-
    thetaTime[input$time,]       # pull off the relevant value for ea obs
rm(list=setdiff(ls(), c("input", "theta", "T")))
我能够编译它并在R上运行它

system("R CMD SHLIB ./Fortran/mytest.f90")
dyn.load("./Fortran/mytest.so")
X <- .Fortran("test3", d = as.integer(1), i = nrow(input), 
              nMCd = nrow(theta), DF = unlist(input), 
              theta = unlist(theta), 
              C = numeric(nrow(input)))
在Fortran中,这种方法或循环更有效吗

subroutine test3(d, i, nMCd, DF, theta, C)
    integer, intent(in)                                 :: d, i, nMCd
    double precision, intent(in), dimension(i,5)        :: DF
    double precision, intent(in), dimension(i,nMCd)     :: theta
    double precision, dimension(i)                      :: epredC, epredT
    double precision, intent(out), dimension(i)         :: C

    C=0.0d0
    epredC = exp(DF(:,4) + (theta(:,d) * DF(:,1)))
    epredT = exp(DF(:,4) + (theta(:,d) * (1-DF(:,1))))

    do jj=1, i
        do j=1, i
            C(jj) = C(jj) + DF(j,5)*epredT(jj)
        end do
    end do

end subroutine test3 
system("R CMD SHLIB ./Fortran/mytest.f90")
dyn.load("./Fortran/mytest.so")
X <- .Fortran("test3", d = as.integer(1), i = nrow(input), 
              nMCd = nrow(theta), DF = unlist(input), 
              theta = unlist(theta), 
              C = numeric(nrow(input)))
subroutine test5(d, i, nMCd, DF, theta, C)
    integer, intent(in)                                 :: d, i, nMCd
    double precision, intent(in), dimension(i,5)        :: DF
    double precision, intent(in), dimension(i,nMCd)     :: theta
    double precision, dimension(i)                      :: epredC, epredT
    double precision, intent(out), dimension(i)         :: C
    double precision, dimension(i,i)                    :: B

    C=0.0d0
    B=0.0d0

    epredC = exp(DF(:,4) + (theta(:,d) * DF(:,1)))
    epredT = exp(DF(:,4) + (theta(:,d) * (1-DF(:,1))))

    do j=1,i
        B(:,j)=epredT(j)
    end do

    C = matmul(DF(:,5), B)

end subroutine test5