在Fortran 90基于“查找”的逻辑索引
我想使用几种不同的方法在数组(EP_G2)中基于.1和.999之间的值在逻辑索引中使用逻辑数组(B) )其中循环2)任何。在Fortran 90基于“查找”的逻辑索引
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)
我得到的问题是,我要么得到整个数组或没有和命令逻辑的(B)得到一个错误,这是不正确的那种。我是来自Matlab的Fortran的新手,我只用find。 此外,由于此数组超过5,948,640 x 1,所以计算时间是一个问题。我正在使用英特尔Fortran编译器(我相信15.0)。
基本上,我正在寻找最快的方法来查找两个数字之间的数组中的点的索引。
任何帮助将不胜感激。
我有点困惑你的代码和问题,但我想你想找到一个数组的元素索引值在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)
将返回其值处于严格pmin
和pmax
之间的indices
那些元素。当然,如果你只希望值本身可以用indices
免除全部写
pack(values, values>pmin.and.values<pmax)
这两个pack
这些用途将回到1级的数组,你可以返回的数组分配到一个分配, Fortran将为您处理尺寸。
我会让你把这种方法扩展到你实际使用的rank-2数组,但是这样做不应该太困难。如果您需要它,请寻求更多帮助。
这是最快的方法吗?我不确定,但编写起来非常快,如果您对运行时性能感兴趣,我建议您测试一下。顺便提一句,Fortran内部函数logical
用于将值从一种类型转换为另一种类型,它并未在整数(或任何其他内在类型)上定义。 Fortran早于关于0
和1
作为逻辑值的疯狂。
谢谢你的回答。澄清? 我添加到我的脚本作为 'A = PACK(值,值> pmin.and.values
编辑你的问题或者要求一个新的。从评论中弄清楚发生了什么实在太难了。 –
数组如何可以相同?
直到声明A,B和C之后才知道RMAX,YMAX,ZMAZ和时间步长值 - 所以它们(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
而且你可能还需要考虑使用形状或大小,看看等级和尺寸的数组是正确的。
IF(SHAPE(A) /= SHAPE(B)) ... chuck and error message.
IF(SIZE(A,1) /= SIZE(B,1)) etc
只是为了澄清问题。你有一个'DOUBLE PRECISION :: EP_G2'的数组。你需要第二个数组'DOUBLE PRECISION :: C',它只包含特定范围内的值。那是对的吗?你还需要将这些数字的索引存储在'EP_G2'中吗? – Jack
是的。我正在寻找将值存储在一个数组中并将索引存储在单独的数组中。 – akimbo