R:创建一个带有循环/应用的矩阵(原始代码Fortran)



感谢任何帮助,我今天一直在为这个问题而苦苦挣扎太久,我希望一双新鲜的眼睛和一组脑细胞可以提供帮助。关于如何使代码更有效率的建议也将不胜感激。

我正在将一个程序从Fortran重写为R。一旦所有数据都进来,最终的矩阵将大于 1000x1000。

代码的第一个元素如下所示:

allocate (S(nrecords))
do i=1,nrecords
    S(i)=ZZ(i,i)
  end do

在 R 中简单地变成了这样:S<-diag(ZZ) **n示例数据中的记录 = 10

我使用的示例数据集由一个 10x10 矩阵 ZZ 组成:

167315  136626  138035  150376  137080  136561  139467  137161  151010  140947
136626  171188  139660  138286  138161  138709  139713  138422  138138  140265
138035  139660  170362  138202  138643  138168  140629  139121  137675  139288
150376  138286  138202  167354  138025  138029  140168  137797  144110  139955
137080  138161  138643  138025  168606  144637  140715  138636  142043  141936
136561  138709  138168  138029  144637  167756  140256  138348  140914  152011
139467  139713  140629  140168  140715  140256  172119  141704  140553  140769
137161  138422  139121  137797  138636  138348  141704  169635  137902  138752
151010  138138  137675  144110  142043  140914  140553  137902  169823  142444
140947  140265  139288  139955  141936  152011  140769  138752  142444  173183

所以 S 是包含对角线值的向量。

不过,我仍然无法翻译这个 Fortran 元素:

 allocate(D(nrecords,nrecords))
  sumD=0
do i=1,nrecords
   do j=1,nrecords
    D(i,j)=S(i)+S(j)-2*ZZ(i,j)
    sumD=sumD+D(i,j)
   end do
end do
       deallocate(ZZ)
sumD=sumD/(nrecords*nrecords)

我知道在一天结束时,我应该得到另一个 10x10 矩阵,其中 D1,1 等于 0,D1,2 将是 65251。但是在阅读for循环,apply(),sapply()和tapply()之间,我相当迷茫和困惑。

这是另一个已经被翻译的元素,我想以此为基础进行 fortran 翻译,但我认为我已经盯着它太久了,我强烈怀疑有一个更有效的答案:

n <-6

sumA <- 0
for (i in 1:n) {
   for (j in 1:n) {
  sumA <- sumA+A[i,j]
              }
            }
sumA2 <- 0
for (i in 1:n) {
   for (j in 1:n) {
  sumA2 <- sumA2+A[i,j]^2
                 }
            }

使用相应的 fortran:

 sumA2=0.0;sumA=0.0
     do i=1,nrecords
      do j=1,nrecords
        if(A(i,j) > 0.0) then
           sumA2=sumA2+(A(i,j)*A(i,j))
           sumA=sumA+A(i,j)
        end if
      end do
    end do

 sumMMA=0.0;sumZZ=0.0
  do i=1,nrecords
   do j=1,nrecords
    sumMMA=sumMMA+(ZZ(i,j)*A(i,j))
   sumZZ=sumZZ+ZZ(i,j)  !this will not work using the sum(ZZ) function
  end do
 end do

矩阵 A 很简单

1   0   0   0   0   0   0   0   0   0
0   0.75    0   0   0   0   0   0   0   0
0   0   1   0   0   0   0   0   0   0
0   0   0   1   0   0   0   0   0   0
0   0   0   0   1   0   0   0   0   0
0   0   0   0   0   0.5 0   0   0   0
0   0   0   0   0   0   0.75    0   0   0
0   0   0   0   0   0   0   1   0   0
0   0   0   0   0   0   0   0   1   0
0   0   0   0   0   0   0   0   0   1

提前感谢!

apply函数的目的是提高可读性。 如果你不理解它们,你就不需要使用它们。 它们或多或少是for循环的包装器。 在您的情况下,您几乎可以逐字翻译您的代码。

R

nrecords <- 10
ZZ <- as.matrix(read.table(header=F, text='
167315  136626  138035  150376  137080  136561  139467  137161  151010  140947
136626  171188  139660  138286  138161  138709  139713  138422  138138  140265
138035  139660  170362  138202  138643  138168  140629  139121  137675  139288
150376  138286  138202  167354  138025  138029  140168  137797  144110  139955
137080  138161  138643  138025  168606  144637  140715  138636  142043  141936
136561  138709  138168  138029  144637  167756  140256  138348  140914  152011
139467  139713  140629  140168  140715  140256  172119  141704  140553  140769
137161  138422  139121  137797  138636  138348  141704  169635  137902  138752
151010  138138  137675  144110  142043  140914  140553  137902  169823  142444
140947  140265  139288  139955  141936  152011  140769  138752  142444  173183
                 '))
S <- diag(ZZ)

福特兰

 allocate(D(nrecords,nrecords))
  sumD=0
do i=1,nrecords
   do j=1,nrecords
    D(i,j)=S(i)+S(j)-2*ZZ(i,j)
    sumD=sumD+D(i,j)
   end do
end do
       deallocate(ZZ)
sumD=sumD/(nrecords*nrecords)

R

D <- matrix(0, nrecords, nrecords)
sumD = 0
for(i in 1:nrecords){
  for(j in 1:nrecords){
    D[i,j] = S[i] + S[j] - 2*ZZ[i,j]
    sumD = sumD + D[i,j]
  }
}
sumD = sumD/(nrecords*nrecords)

福特兰

do i=1,nrecords
  do j=1,nrecords
    if(A(i,j) > 0.0) then
       sumA2=sumA2+(A(i,j)*A(i,j))
       sumA=sumA+A(i,j)
    end if
  end do
end do    
sumMMA=0.0;sumZZ=0.0
  do i=1,nrecords
   do j=1,nrecords
    sumMMA=sumMMA+(ZZ(i,j)*A(i,j))
   sumZZ=sumZZ+ZZ(i,j)  !this will not work using the sum(ZZ) function
  end do
 end do

R

A <- matrix(0, nrecords, nrecords)
diag(A) <- c(1,.75,1,1,1,.5,.75,1,1,1)
sumA2 = 0
sumA = 0
for(i in 1:nrecords){
  for(j in 1:nrecords){
    if(A[i,j] > 0){
      sumA2=sumA2+(A[i,j]*A[i,j])
      sumA = sumA+A[i,j]
    }
  }
}
sumMMA=0
sumZZ=0
for(i in 1:nrecords){
  for(j in 1:nrecords){
    sumMMa=sumMMA+(ZZ[i,j]*A[i,j])
    sumZZ=sumZZ+ZZ[i,j]
  }
}

最新更新