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
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.
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.
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.