我对Fortran相对较新,现在几个小时就打破了一件事:
我想写一个子程序来查找真实一维数组中特定元素的索引(作为输入提供给例程)。
我已经生成了一个包含100个随机实数的数组,称为arr
,现在想要确定那些大于实数值min
的元素的索引,它们也传递给子例程。
另外,最后我想要一个我最后分配的指针,据说这比使用包含索引的数组indices
更好。
我只是没有找到解决方法,我有以下方法:
SUBROUTINE COMP(arr, min)
real, intent(in) :: arr(:)
real, intent(in) :: min
integer, pointer, dimension(:) :: Indices
integer :: i, j
! now here I need a loop which assigns to each element of the pointer
! array the Indices one after another, i don't know how many indices there
! are to be pointed at
! And I dont know how to manage that the Indices are pointed at one after another,
! like Indices(1) => 4
! Indices(2) => 7
! Indices(3) => 32
! Indices(4) => 69
! ...
! instead of
! Indices(4) => 4
! Indices(7) => 7
! Indices(32) => 32
! Indices(69) => 69
! ...
DO i = 1, size(arr)
IF (arr(i) > min) THEN
???
ENDIF
ENDDO
allocate(Indices)
END SUBROUTINE COMP
答案 0 :(得分:3)
如果简洁(而不是表现)漂浮在你的船上......考虑:
FUNCTION find_indexes_for_specific_elements_in_a_real_1D_array(array, min) &
RESULT(indices)
REAL, INTENT(IN) :: array(:)
REAL, INTENT(IN) :: min
INTEGER, ALLOCATABLE :: indices(:)
INTEGER :: i
indices = PACK([(i,i=1,SIZE(array))], array >= min)
END FUNCTION find_indexes_for_specific_elements_in_a_real_1D_array
[需要F2003。假定具有可分配结果的形状参数和函数的过程需要在引用它们的地方可访问显式接口,因此所有表现良好的Fortran程序员都将它们放在模块中。]
答案 1 :(得分:2)
获取大于值arr
的元素的等级1数组min
的索引的简单方法是
indices = PACK([(i, i=LBOUND(arr,1), UBOUND(arr,1))], arr.gt.min)
其中indices
为allocatable, dimension(:)
。如果您的编译器不支持自动(重新)分配,那么在该点之前将需要ALLOCATE(indices(COUNT(arr.gt.min))
(如果DEALLOCATE
已经分配,那么在此之前使用indices
。
作为解释:[(i, i=...)]
创建一个数组,其中包含另一个数组的索引数,PACK
内在数据选择与掩码条件对应的数组。
请注意,如果您在子程序中进行索引计算,则必须小心:
subroutine COMP(arr, min, indices)
real, intent(in) :: arr(:)
real, intent(in) :: min
integer, allocatable, intent(out) :: indices(:)
!...
end subroutine
无论实际参数的边界(传递的数组)如何(可能是arr
,子例程中的 1
都会有下限VALS(10:109)
。您还需要将下限传递给子程序,或稍后解决。
[自动分配不是F90功能,但在F90中还必须考虑可分配的子程序参数
答案 2 :(得分:1)
我认为你走在正确的轨道上,但是你忽略了一些固有的Fortran函数,特别是count,你没有返回任何东西!
subroutine comp(arr, min)
real, intent(in) :: arr(:)
real, intent(in) :: min
! local variables
integer, allocatable :: indices(:)
integer :: i,j, indx
! count counts the number of TRUE elements in the array
indx = count(arr > min)
allocate(indices(indx))
! the variable j here is the counter to increment the index of indices
j=1
do i=1,size(arr)
if(arr(i) > min) then
indices(j) = i
j = j+1
endif
enddo
end subroutine comp
然后您可以将数组indices
用作
do i=1,size(indices)
var = arr(indices(i))
enddo
请注意,由于您没有返回indices
,一旦您返回,您将丢失所有找到的信息 - 除非您打算在子程序中使用它,那么您没问题。如果你没有在那里使用它,你可以将它定义为module
中的全局变量,其他子程序应该看到它。