如何在Fortran中安排向量元素?

时间:2010-01-05 08:22:30

标签: vector fortran elements

我有两个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

在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)

现在我只需要那些第一个:ydim(t),所以其余的都没关系。

问题是,我怎样才能在Fortran中做类似的事情?

谢谢,

Jouni

2 个答案:

答案 0 :(得分:2)

“where语句”和“merge”内在函数功能强大,在数组中的选定位置上运行,但它们不会将项目移动到数组的前面。使用具有显式索引的旧式代码(可以打包到函数中),例如:

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

使用“pack”内在函数可以使用数组内在函数完成所需的操作。将ymiss转换为逻辑数组:0 - > .false。,1 - > .true ..然后使用代码(没有第二个索引测试):

y(1:ydim(t),t)= pack(y(:,t),ymiss(:,t))


编辑以添加示例代码,显示使用Fortran内在函数“where”,“count”和“pack”。 “哪里”单独无法解决问题,但“打包”可以。在本例中,我使用“< -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

使用pack后,“擦除”结束:    3.0 1.0 6.0 2.0 -99.0 -99.0

答案 1 :(得分:1)

在Fortran中,你不能将na存储在一个实数数组中,你只能存储实数。所以你可能想用一些不太可能存在于你的数据中的值替换na:huge()可能是合适的。对于Fortan来说,2D阵列完全没问题。您可能希望使用2D逻辑阵列来替换ymiss,而不是使用1和0的2D数组。

没有简单的,内在的实现你想要的东西,你需要编写一个函数。但是,更多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