Reputation: 975
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
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
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
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