Re: Locate function for logical array



On Jan 25, 1:17 pm, jfh <john.har...@xxxxxxxxx> wrote:
On Jan 24, 1:17 pm, glen herrmannsfeldt <g...@xxxxxxxxxxxxxxxx> wrote:



Dave Allured <nos...@xxxxxxxxxx> wrote:
I am seeking a function that is like the "index" function for strings,
except for a 1-D logical array.  Is there an intrinsic function or more
elegant coding method to do this, rather than an explicit loop?  It
"seems" to me that there ought to be a nicer way in fortran.
  integer i, p
  logical x(6)
  x = (/.false.,.false.,.true.,.false.,.true.,.false./)
  p = 0
  do i = 1, 6
     if (x(i)) then
        p = i
        exit
     end if
  end do

...
Otherwise, you can write a logicalindex function pretty easily.
You do need two loops, though.

You could make strings of 'T' and 'F', and then use index.

The following program shows and tests a way to do it in F95 without
having to write the loops oneself, though they are presumably "under
the hood" of the intrinsics used. BTW, I used the variable reallyback
to work around a bug in one of the compilers I tried, which wouldn't
let an absent dummy argument be used as an actual optional argument,
in spite of the F95 standard 12.4.1.5 and F2003 standard 12.4.1.6. I
reported the bug to the compiler's developers some time ago. They may
have fixed it by now, but our systems people haven't yet installed the
latest version of that compiler.)

program logicalindex
  implicit none
  logical,parameter:: &
       larray(6) = (/.false.,.true.,.false.,.true.,.true.,.false./),&
       farray(2) = larray(1:3:2)
  print *,larray,lindex(larray)
  print *,farray,lindex(farray)
  print *,larray,lindex(larray,.true.)
  print *,farray,lindex(farray,.true.)
  print *,larray,lindex(larray,.false.)
  print *,farray,lindex(farray,.false.)
contains
  integer function lindex(larray,back) ! Pos. of first(last) true
element
    logical,intent(in) :: larray(:)
    logical,intent(in),optional::back
    character(size(larray)) :: string
    logical:: reallyback = .false.
    if(present(back)) reallyback = back
    lindex = index(transfer(merge('T','F',larray),string),'T',&
         reallyback)
  end function lindex
end program logicalindex

-- John Harper

Aargh! I fell into the intialization trap: if lindex is called without
its optional argument after being called with it true, the variable
reallyback will have the wrong value. What is worse, my test program
did not test that case. Also, one compiler warned that in
transfer(merge('T','F',larray),string) I was using the variable string
before it had been set. That didn't stop the program compiling and
running,though. Here is a revised version that avoids all those
troubles, with my apologies for causing them:

program logicalindex
implicit none
logical,parameter :: T = .true., F = .false., &
larray(6) = (/ F,T,F,T,T,F /),&
farray(2) = (/ F,F /)
print *,larray,lindex(larray,T),' should be 5'
print *,farray,lindex(farray,T),' should be 0'
print *,larray,lindex(larray) ,' should be 2'
print *,farray,lindex(farray) ,' should be 0'
print *,larray,lindex(larray,F),' should be 2'
print *,farray,lindex(farray,F),' should be 0'
contains
integer function lindex(larray,back) ! Pos. of first(last) true
element
logical,intent(in) :: larray(:)
logical,intent(in),optional::back
logical :: reallyback
character(size(larray)) :: string
reallyback = F
string = ' '
if(present(back)) reallyback = back
lindex = index(transfer(merge('T','F',larray),string),'T',&
reallyback)
end function lindex
end program logicalindex

-- John Harper
.



Relevant Pages

  • Re: Locate function for logical array
    ...   integer i, p ... you can write a logicalindex function pretty easily. ... You do need two loops, ... I used the variable reallyback ...
    (comp.lang.fortran)
  • Re: Locate function for logical array
    ... you can write a logicalindex function pretty easily. ... I used the variable reallyback ... end function lindex ... end program logicalindex ...
    (comp.lang.fortran)
  • Re: Locate function for logical array
    ... Is there an intrinsic function or more ... you can write a logicalindex function pretty easily. ... I used the variable reallyback ...
    (comp.lang.fortran)