Any help appreciated, I have been struggling with this problem far too long today, and I hope a fresh pair of eyes and set of braincells can help. Suggestions on how to make the code more efficient will also be greatly appreciated.
任何帮助表示赞赏,今天我一直在努力解决这个问题太久了,我希望一副新鲜的眼睛和一套braincells可以提供帮助。关于如何提高代码效率的建议也将不胜感激。
I am in the process of rewriting a program from Fortran into R. The eventual matrix, once all the data comes in, will be bigger that 1000x1000.
我正在将一个程序从Fortran重写为R.最终的矩阵,一旦所有数据进入,将大于1000x1000。
The first element of the code looked like this:
代码的第一个元素如下所示:
allocate (S(nrecords))
do i=1,nrecords
S(i)=ZZ(i,i)
end do
which in R simply became this: S<-diag(ZZ)
**nrecords in the example data = 10
在R中简单地变成这样:S <-diag(ZZ)** nrecords in example data = 10
The example dataset I am using consists of a 10x10 matrix ZZ:
我使用的示例数据集包含一个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
so S is a vector containing the diagonal values.
所以S是包含对角线值的向量。
I am stuck in translating this Fortran element though:
我仍然坚持翻译这个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)
I know that at the end of the day I am supposed to end up with another 10x10 matrix, where D1,1 will equal to 0, and D1,2 will be 65251. But between reading-up on for-loops, apply(), sapply() and tapply() I am rather lost and confused.
我知道在一天结束时我应该得到另一个10x10矩阵,其中D1,1将等于0,而D1,2将是65251.但是在读取for循环之间,应用() ,sapply()和tapply()我很迷茫和困惑。
This is another element that has already been translated, and I wanted to base the fortran translation on this, but I think I have been staring at it too long, and I strongly suspect that there is a more efficient answer:
这是另一个已被翻译过的元素,我想在此基础上进行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
}
}
with the corresponding fortran:
与相应的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
Matrix A is simply
矩阵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
Thanks in advance!
提前致谢!
1 个解决方案
#1
1
The purpose of the apply
functions is to improve readability. If you don't understand them you don't need to use them. They are more or less wrappers for for
loops. In your case, you can almost translate your code verbatim.
应用功能的目的是提高可读性。如果您不理解它们,则不需要使用它们。它们或多或少是for循环的包装器。在您的情况下,您几乎可以逐字翻译您的代码。
R
[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)
Fortran
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)
R
[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)
Fortran
Fortran语言
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
[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]
}
}
#1
1
The purpose of the apply
functions is to improve readability. If you don't understand them you don't need to use them. They are more or less wrappers for for
loops. In your case, you can almost translate your code verbatim.
应用功能的目的是提高可读性。如果您不理解它们,则不需要使用它们。它们或多或少是for循环的包装器。在您的情况下,您几乎可以逐字翻译您的代码。
R
[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)
Fortran
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)
R
[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)
Fortran
Fortran语言
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
[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]
}
}