我正在尝试使用一些不同的方法()循环2)ANY,使逻辑数组(B)用于基于数组(EP_G2)中.1和.999之间的值的逻辑索引。
program flux_3d
implicit none
INTEGER :: RMAX, YMAX, ZMAZ, timesteps
DOUBLE PRECISION, PARAMETER :: pmin=0.1
DOUBLE PRECISION, PARAMETER :: pmax=0.999
INTEGER :: sz
DOUBLE PRECISION, ALLOCATABLE :: EP_G2(:,:), C(:)
INTEGER, DIMENSION(RMAX*ZMAX*YMAX) :: B
LOGICAL, DIMENSION(RMAX*ZMAX*YMAX) :: A
! dimensions of array,
RMAX = 540
YMAX = 204
ZMAX = 54
timesteps = 1
!Open ascii array
OPEN(100, FILE ='EP_G2', form = 'formatted')
ALLOCATE( EP_G2(RMAX*ZMAX*YMAX, timesteps))
READ(100, *) EP_G2
WHERE(pmin<EP_G2(:,timesteps)<pmax) B = 1
ELSEWHERE
B = 0
ENDWHERE
PRINT*, B
! SZ # OF POINTS IN B
sz = count(B.eq.1)
!alternate way of finding points between pmin and pmax
A = ANY(pmin<EP_G2(:,t)<pmax)
print*, sz
!Then use the logical matrix B (or A) to make new array
!Basically I want a new array that isolates just the points in array between
!pmin and pmax
ALLOCATE(C(sz))
C = EP_G2(LOGICAL(B), 1)
我得到的问题是我要么得到整个数组,要么没有任何东西,而命令LOGICAL(B)得到的错误是它不正确。我是来自Matlab的Fortran的新手,我将使用find。 此外,由于此阵列超过5,948,640 x 1计算时间是一个问题。我正在使用英特尔Fortran编译器(我相信15.0)。
基本上,我正在寻找在两个数字之间找到数组中点的索引的最快方法。
非常感谢任何帮助。
答案 0 :(得分:2)
我对你的代码和问题感到有些困惑,但我认为你想要找到数组中元素的索引,其值在0.1
和0.999
之间。你并不完全清楚你想要的是指数,或者仅仅是元素本身,但是请耐心等待,我会解释如何获得两者。
假设您的原始数组声明为
real, dimension(10**6) :: values
并且它填充了值。然后我可以像这样声明一个索引数组
integer, dimension(10**6) :: indices = [(ix,ix=1,10**6)]
(显然你也需要声明变量ix
。)
现在,表达式
pack(indices, values>pmin.and.values<pmax)
将返回indices
的元素,其值严格位于pmin
和pmax
之间。当然,如果您只想要值本身,您可以完全省略indices
并写入
pack(values, values>pmin.and.values<pmax)
pack
的这两种用法都将返回排名为1的数组,并且您可以将返回的数组分配给可分配的,Fortran将为您处理大小调整。
我会留给你将这种方法扩展到你实际使用的rank-2数组,但这样做应该不会太难。如果需要,请寻求更多帮助。
这是最快的方法吗?我不确定,但编写起来非常快,如果你对它的运行时性能感兴趣,我建议你测试一下。
顺便提一下,Fortran内部函数logical
用于将logical
值从一种转换为另一种,它不是在整数(或任何其他内在类型)上定义的。 Fortran早于将0
和1
视为逻辑值的疯狂。
答案 1 :(得分:1)
阵列如何相同?
RMAX,YMAX,ZMAZ和时间步长值在声明A,B和C之后才知道 - 因此它们(A和B)可能不是您想要的大小。
implicit none
INTEGER :: RMAX, YMAX, ZMAZ, timesteps
DOUBLE PRECISION, PARAMETER :: pmin=0.1
DOUBLE PRECISION, PARAMETER :: pmax=0.999
INTEGER :: sz
DOUBLE PRECISION, ALLOCATABLE :: EP_G2(:,:), C(:)
INTEGER, DIMENSION(RMAX*ZMAX*YMAX) :: B
LOGICAL, DIMENSION(RMAX*ZMAX*YMAX) :: A
! dimensions of array,
RMAX = 540
YMAX = 204
ZMAX = 54
timesteps = 1
你可能想要这个:
implicit none
INTEGER , PARAMETER :: RMAX = 504
INTEGER , PARAMETER :: YMAX = 204
INTEGER , PARAMETER :: ZMAZ = 54
INTEGER , PARAMETER :: timesteps = 1
DOUBLE PRECISION, PARAMETER :: pmin = 0.1
DOUBLE PRECISION, PARAMETER :: pmax = 0.999
INTEGER :: sz
DOUBLE PRECISION, ALLOCATABLE :: EP_G2(:,:), C(:)
INTEGER, DIMENSION(RMAX*ZMAX*YMAX) :: B
LOGICAL, DIMENSION(RMAX*ZMAX*YMAX) :: A
! dimensions of array,
!RMAX = 540
!YMAX = 204
!ZMAX = 54
!timesteps = 1
或者这个:
implicit none
! dimensions of array
INTEGER , PARAMETER :: RMAX = 504
INTEGER , PARAMETER :: YMAX = 204
INTEGER , PARAMETER :: ZMAZ = 54
INTEGER , PARAMETER :: timesteps = 1
DOUBLE PRECISION, PARAMETER :: pmin = 0.1
DOUBLE PRECISION, PARAMETER :: pmax = 0.999
INTEGER :: sz
DOUBLE PRECISION, ALLOCATABLE :: EP_G2(:,:), C(:)
INTEGER, DIMENSION(:), ALLOCATABLE :: B
LOGICAL, DIMENSION(:), ALLOCATABLE :: A
! Then allocate A and B
您可能还想考虑使用SHAPE或SIZE来查看数组的等级和大小是否正确。
IF(SHAPE(A) /= SHAPE(B) ) ... chuck and error message.
IF(SIZE(A,1) /= SIZE(B,1) ) etc