2010-01-05 26 views
2

我有兩個p * n數組,y和ymiss。 y包含實數和NA。 ymiss包含1和0,所以如果y(i,j)== NA,ymiss(i,j)== 0,否則爲1。我也有1個* N陣列ydim告訴有位於y多少實數(1:P,N),所以ydim具有值0至P如何在Fortran中安排矢量元素?

一個R編程語言,我可以做以下幾點:

if(ydim!=p && ydim!=0) 
    y(1:ydim(t), t) = y(ymiss(,t), t) 

即代碼排列Y(,t)的所有實數在這樣

第一後的例如有 Y(,T)=(3,1,NA,6,2,NA) 代碼它是 y(,t)=(3,1,6,2,2,NA)

現在我將o只需要那些第一個1:ydim(t),所以這些休息是什麼都沒有關係。

問題是,我如何在Fortran中做類似的事情?

感謝,

Jouni

回答

1

Fortran中不能存儲吶在實數的數組,你只能存儲實數。所以你可能會想用你的數據中不可能存在的某些值代替na:huge()可能是合適的。對於Fortan而言,二維數組完全沒有問題。您可能想要使用二維數組邏輯來替換ymiss,而不是使用1和0的二維數組。

沒有簡單的,內在的實現你想要的,你需要寫一個函數。但是,更多Fortran的處理方式是使用邏輯數組作爲要執行的操作的掩碼

所以,這裏是一些零碎的Fortran代碼,沒有測試:

! Declarations 
real(8), dimension(m,n) :: y, ynew 
logical, dimension(m,n) :: ymiss 

! Executable 
where (ymiss) ynew = func(y) ! here func() is whatever your function is 
2

「在哪裏聲明」和「合併」固有功能是強大的,在陣列選定的位置工作,但他們不動項目放在數組的前面。與老式的代碼具有明確的索引(可能被打包成一個功能)例如: -

k=1 
do i=1, n 
    if (ymiss (i) == 1) then 
     y(k) = y(i) 
     k = k + 1 
    end if 
end do 

你想要可以在使用這個「包」的內在數組內在做什麼。將ymiss轉換成一個邏輯數組:0 - > .false。,1 - > .true ..然後使用類似於(沒有第二個索引測試)的代碼:

y(1:ydim(t),t) =包(Y(:,T),YMISS(:,t))的


修改以添加例如代碼,示出使用Fortran內部的 「其中」, 「計數」 和 「包」。 「哪裏」獨自解決不了問題,但「包裝」可以。在本例中,我使用「< -90」作爲NaN。 OP不需要使用「y(ydim + 1:LEN)= -99.0」這一步,他們不需要使用這些元素。

program test1 

integer, parameter :: LEN = 6 
real, dimension (1:LEN) :: y = [3.0, 1.0, -99.0, 6.0, 2.0, -99.0 ] 
real, dimension (1:LEN) :: y2 
logical, dimension (1:LEN) :: ymiss 
integer :: ydim 

y2 = y 
write (*, '(/ "The input array:"/6(F6.1))') y 

where (y < -90.0) 
    ymiss = .false. 
elsewhere 
    ymiss = .true. 
end where 

ydim = count (ymiss) 

where (ymiss) y2 = y 
write (*, '(/ "Masking with where does not rearrange:"/6(F6.1))') y2 

y (1:ydim) = pack (y, ymiss) 
y (ydim+1:LEN) = -99.0 
write (*, '(/ "After using pack, and ""erasing"" the end:"/6(F6.1))') y 


stop 

end program test1 

輸出是:

輸入數組: 3.0 1.0 -99.0 6.0 2.0 -99。0

掩蔽與在不重新排列: 3.0 1.0 -99.0 6.0 2.0 -99.0

使用包之後,以及 「擦除」 結束: 3.0 1.0 6.0 2.0 -99.0 -99.0