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