2014-11-14 64 views
0

任何幫助表示讚賞,我一直在努力解決這個問題太長時間了,我希望一雙新的眼睛和一套braincells可以提供幫助。關於如何使代碼更高效的建議也將不勝感激。R:用循環創建一個矩陣/應用(原始代碼Fortran)

我正在將一個程序從Fortran重寫爲R.最終矩陣一旦所有數據進入,將會大於1000x1000。

的代碼的第一個元件是這樣的:

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

其中的R簡單地成爲這樣:S<-diag(ZZ) ** nrecords在示例數據= 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) 

我知道,在我應該用另一種10×10矩陣,結束了一天的結束,在這裏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 

提前致謝!

回答

1

apply函數的作用是提高可讀性。如果你不瞭解他們,你不需要使用它們。它們或多或少是for循環的包裝。就你而言,你幾乎可以逐字翻譯你的代碼。

ř

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

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) 

ř

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

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] 
    } 
} 
+0

非常感謝@cdeterman!我被告知,我嘗試過分複雜的事情,我沒有意識到答案可以如此簡單:) – Tundrahorse 2014-11-14 16:41:11