在1D数组中查找连续标志值的索引

时间:2016-02-27 12:05:54

标签: arrays fortran fortran90 gfortran

我希望在1D数组中找到值0。我在这个数组中有几个0值,大部分时间是连续的0值。现在我想要做的就是找到每个连续事件中第一个零值出现和最后一个零值出现的索引,我将在下面给出一个例子来使事情清楚: 想象一下,我有以下数组:

A= 0.0 0.0 0.0 0.0 0.0 0.0 0.38458693526004206 0.37630968444637147 0.40920888023862656 0.37240138383511134 0.38032672100490084 0.37013107455599198 0.40263333907360693 0.36804456033540955 0.41199172743738527 0.42761170349633443 0.39300715826673704 0.39783513932402137 0.44013743441396674 0.435127008833611 0.48217350280280391 0.47501246018014148 0.49234819258730078 0.54559998531569354 0.47840534103437832 0.0 0.0 0.0 0.51927791704510429 0.0 0.0 0.0 0.0 0.0 0.45862555500619961 0.50158980306905965 0.45676444815553296 0.49679306608627022 0.53878698007533210 0.50186256107128602 0.51714780706878094 0.53005606067091249 0.48409168179213419 0.48594430950932133 0.50963106475909081 0.49300327248076087 0.50531667704394834 0.46415085995913757 0.51930900041928330

所以我在每次连续的事件中寻找第一个位置和零的最后位置,我应该得到以下内容:

min_loc_1=1

max_loc_1=6

min_loc_2=26

max_loc_2=28

min_loc_3=30

max_loc_3=34

现在我尝试了anyminlocmaxlocforall的组合,但我无法弄清楚

         do ijk = 1, size(work1)
             if (work1(ijk) .eq. 0) then
                 location1(ijk) = ijk
             end if         
          end do
                    min_loc=minloc(location1)
                    max_loc1=maxloc(location1)

我无法使用where,因为我在其中调用了一个子程序,而Fortran显然不喜欢它。

1 个答案:

答案 0 :(得分:1)

有限的测试使我确信这可以解决您的直接问题。我还没有对它进行过广泛的测试,我会把它留给你。它将0每次运行的开始和结束的索引写入数组b

  INTEGER, DIMENSION(:),ALLOCATABLE :: b
  LOGICAL :: zz
  ...    
  ALLOCATE(b(0))
  zz = .false.
  DO ix = 1, SIZE(a)
     IF (.NOT.zz.AND.a(ix)==0) THEN
        b = [b,ix]
        zz = .TRUE.
     END IF
     IF (zz.AND.a(ix)/=0) THEN
        b = [b,ix-1]
        zz = .FALSE.
     END IF
  END DO

这会产生,当您向我们展示数组时,

b == [1 6 26 28 30 34]

如果这不具有吸引力,这似乎也有效:

  b = [(ix,ix=1,SIZE(a))]
  WHERE(a/=0.0) b = 0
  c = PACK(b,b/=0)
  b = PACK(c,(CSHIFT(c,1)-c)*(CSHIFT(c,-1)-c)/=-1)

如果您无法确定此版本,请坚持使用第一个代码段中的显式循环。