marco
marco

Reputation: 975

is there an easy way to find index array zeros in Fortran?

I'm searching for intrinsic fortran functions to help me find the array index with zeros, or other value. I only found minloc function, but I think this is not suitable. Is there an matlab find function equivalent in Fortran?

Thanks

Upvotes: 6

Views: 4358

Answers (3)

mabalenk
mabalenk

Reputation: 1043

High Performance Mark's solution based on the pack intrinsic is short and elegant. However, if your array is relatively small, searching for a specific value with pack tends to be slower than a brute force search based on a do loop:

do i = 1, size(testarr)

  if (testarr(i) == 0) then

    idx = i
    exit

  end if

end do

See Craig Finch's answer for details. I have also verified that brute force do loop is faster for small arrays (< 10 elements), compared to the pack based search.

Upvotes: 0

High Performance Mark
High Performance Mark

Reputation: 78316

Given an integer array such as:

testarr = [0,1,0,2,0,3,0,4]

then the expression

pack([(ix,ix=1,size(testarr))],testarr==0)

will return the indices of the elements in testarr equal to 0.

I'll leave you to generalise or enhance this to deal with real numbers or to wrap it into a function to suit your purposes.

The Fortran 2008 standard adds a new intrinsic function findloc which offers to be the replacement for Matlab's find that the question seeks; the compiler I use most (Intel Fortran 13.1.1) doesn't seem to implement this yet.

Upvotes: 10

milancurcic
milancurcic

Reputation: 6241

Yes, see High Performance Mark's answer on how to do this with with the PACK instrinsic function.

If I needed to perform operations on all array elements that satisfy some condition, I would implement it using a combination of DO and IF constructs, for example:

INTEGER :: i
REAL,DIMENSION(10) :: a
REAL :: eps = someSmallNumber
...
DO i = 1,SIZE(a)
  IF( 0 > a(i)-eps .AND. 0 < a(i)+eps )THEN
    ...
  ENDIF
ENDDO

The range (a(i)-eps,a(i)+eps) is used above to prevent against comparison fail due to floating point arithmetic. If working with integers, an exact == comparison will do.

If only assignment operations to array elements are needed, you can achieve this using WHERE or FORALL constructs.

Upvotes: 2

Related Questions