# FINDLOC alternative

**URL:** <https://fortran-lang.discourse.group/t/findloc-alternative/1968>\
**Category:** Help\
**Created:** [September 30, 2021, 8:53pm UTC](https://fortran-lang.discourse.group/t/findloc-alternative/1968 "2021-09-30T20:53:45Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![Niko](https://avatars.discourse-cdn.com/v4/letter/n/91b2a8/32.png) [@Niko](https://fortran-lang.discourse.group/u/Niko)\
**Post date:** [September 30, 2021, 8:53pm UTC](https://fortran-lang.discourse.group/t/findloc-alternative/1968/1 "2021-09-30T20:53:45Z")

</div>

I used FINDLOC (in the standard since 2008) in a code. Ifort works fine with it, gfortran \> 9.1 works fine, but older gfortran does not have it implemented. There is a user of my code that runs older gfortran and is stuck with it. Does anyone maybe have open source function that mimics the functionality of FINDLOC? If the performance is suboptimal, it does not matter much.

Thanks!!

---

<div class="post-metadata">

**Author:** ![Beliavsky](https://avatars.discourse-cdn.com/v4/letter/b/ba8739/32.png) [@Beliavsky](https://fortran-lang.discourse.group/u/Beliavsky)\
**Post date:** [September 30, 2021, 9:10pm UTC](https://fortran-lang.discourse.group/t/findloc-alternative/1968/2 "2021-09-30T21:10:49Z")

</div>

> [@Niko](#):
>
> I used FINDLOC (in the standard since 2008) in a code. Ifort works fine with it, gfortran \> 9.1 works fine, but older gfortran does not have it implemented. There is a user of my code that runs older gfortran and is stuck with it. Does anyone maybe have open source function that mimics the functionality of FINDLOC? If the performance is suboptimal, it does not matter much.

Findloc works for arrays of all intrinsic types and ranks, and it has several optional arguments, listed [here](https://gcc.gnu.org/onlinedocs/gfortran/FINDLOC.html). How general of a `findloc` do you need? This could be determined empirically by writing a `findloc` interface and adding necessary module procedures until the code compiles. Writing a `findloc` that works for say 1d and 2d integer or character arrays would not be difficult. There was [discussion](https://github.com/fortran-lang/stdlib/issues/258) of putting findloc in stdlib for your use case, but I don’t see it [here](https://stdlib.fortran-lang.org/lists/procedures.html), so I don’t it was implemented.

---

<div class="post-metadata">

**Author:** ![Niko](https://avatars.discourse-cdn.com/v4/letter/n/91b2a8/32.png) [@Niko](https://fortran-lang.discourse.group/u/Niko)\
**Post date:** [September 30, 2021, 9:22pm UTC](https://fortran-lang.discourse.group/t/findloc-alternative/1968/3 "2021-09-30T21:22:59Z")

</div>

It does not have to be general at all. It should actually work just for 1D arrays of integers or floats. Yes, I’m aware that this is easy, but I’m getting lazy when I have to do something that probably already exists. 🙂 I was a bit surprised that I couldn’t google it, so I thought of asking here before doing it myself.

---

<div class="post-metadata">

**Author:** ![rwmsu](https://avatars.discourse-cdn.com/v4/letter/r/48db29/32.png) [@rwmsu](https://fortran-lang.discourse.group/u/rwmsu)\
**Post date:** [September 30, 2021, 9:26pm UTC](https://fortran-lang.discourse.group/t/findloc-alternative/1968/4 "2021-09-30T21:26:55Z")

</div>

I wrote my own FINDLOC workalike a few years back just so I could  
compile code on gfortran and PGI compilers that did not support  
FINDLOC at that time. My code supports rank 1 through rank3 arrays of  
Integer and real (both 32 and 64 bit) and logicals. I can bundle the code into  
a standalone package and put it on github if there is sufficient interest

---

<div class="post-metadata">

**Author:** ![Beliavsky](https://avatars.discourse-cdn.com/v4/letter/b/ba8739/32.png) [@Beliavsky](https://fortran-lang.discourse.group/u/Beliavsky)\
**Post date:** [September 30, 2021, 9:31pm UTC](https://fortran-lang.discourse.group/t/findloc-alternative/1968/5 "2021-09-30T21:31:43Z")

</div>

Maybe try

`findloc(array,value) = minloc(abs(array-value))`

but test the resulting code and see if it does what you want when `value` is not found in `array`.

---

<div class="post-metadata">

**Author:** ![Niko](https://avatars.discourse-cdn.com/v4/letter/n/91b2a8/32.png) [@Niko](https://fortran-lang.discourse.group/u/Niko)\
**Post date:** [September 30, 2021, 9:36pm UTC](https://fortran-lang.discourse.group/t/findloc-alternative/1968/6 "2021-09-30T21:36:42Z")

</div>

Thanks! I’ll write my ad-hoc function taking care of the exceptions.

@rwmsu I guess that such a code is always useful.

---

<div class="post-metadata">

**Author:** ![rwmsu](https://avatars.discourse-cdn.com/v4/letter/r/48db29/32.png) [@rwmsu](https://fortran-lang.discourse.group/u/rwmsu)\
**Post date:** [September 30, 2021, 9:41pm UTC](https://fortran-lang.discourse.group/t/findloc-alternative/1968/7 "2021-09-30T21:41:03Z")

</div>

My code is based on using MAXLOC and MERGE. Here is my code for a 1D interger  
array. The multi-dimensional arrays follow the same basic template

```auto
  Pure Function findloc1D_I32(a, value, mask, back) Result(index)

    Implicit NONE

    Integer(INT32), Intent(IN) :: a(:)
    Integer(INT32), Intent(IN) :: value
    Logical, Intent(IN), OPTIONAL :: mask(:)
    Logical, Intent(IN), OPTIONAL :: back

    Integer :: index(1)

    Logical :: reverse
    Logical, ALLOCATABLE :: m(:)

    index = 0
    ALLOCATE(m(SIZE(a,DIM=1)))
    m = .TRUE.
    If (PRESENT(mask)) m = mask

    If(COUNT(a==value .AND. m) == 0) RETURN

    reverse = .FALSE.

    If (PRESENT(back)) reverse = back

    If (reverse) Then

      index(1) = MAXLOC(MERGE(1,0, (a(SIZE(a):1:-1) == value) &
                .AND. m(SIZE(a):1:-1)),DIM=1)
      If (index(1) > 0) index(1) = UBOUND(a,DIM=1)-index(1) + 1
    Else

      index(1) = MAXLOC(MERGE(1,0, a == value .AND. m), dim=1)

    EndIf

  End Function findloc1D_I32

```

---

<div class="post-metadata">

**Author:** ![Beliavsky](https://avatars.discourse-cdn.com/v4/letter/b/ba8739/32.png) [@Beliavsky](https://fortran-lang.discourse.group/u/Beliavsky)\
**Post date:** [September 30, 2021, 11:50pm UTC](https://fortran-lang.discourse.group/t/findloc-alternative/1968/8 "2021-09-30T23:50:33Z")

</div>

The [emulators](https://github.com/sourceryinstitute/emulators) project of @everythingfunctional and @rouson implements findloc.

> #### Motivation and Usage
> 
> Are you hoping for a world with full compiler support for recent Fortran standards? Emulating an unsupported feature facilitates using the feature prior to compiler support. This path offers minimal impact on future code.
> 
> …
> 
> #### Contents
> 
> Emulated features:
> 
> - Fortran 2008 intrinsic function: `findloc`
> - Fortran 2018 collective subroutines: `co_sum` , `co_broadcast`
> 
> Those who find the collective subroutines useful might also be interested in language extensions such as the [Sourcery](https://github.com/sourceryinstitute/sourcery) library’s `co_all` subroutine, which provides a parallel, collective `logical` operation analogous to the `all` intrinsic function.

---

<div class="post-metadata">

**Author:** ![rwmsu](https://avatars.discourse-cdn.com/v4/letter/r/48db29/32.png) [@rwmsu](https://fortran-lang.discourse.group/u/rwmsu)\
**Post date:** [October 1, 2021, 1:36am UTC](https://fortran-lang.discourse.group/t/findloc-alternative/1968/9 "2021-10-01T01:36:57Z")

</div>

I have added my findloc implementations to my github ModForUtils repository

Go to:

> **[ModForUtils/findlocUtils at main · rweed/ModForUtils](https://github.com/rweed/ModForUtils/tree/main/findlocUtils)**
>
> main/findlocUtils

---

<div class="post-metadata">

**Author:** ![shahmoradi](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/shahmoradi/32/3151_2.png) [@shahmoradi](https://fortran-lang.discourse.group/u/shahmoradi)\
**Post date:** [October 1, 2021, 2:36am UTC](https://fortran-lang.discourse.group/t/findloc-alternative/1968/10 "2021-10-01T02:36:15Z")

</div>

Just in case, the array is _large_ and _sorted_, a binary search would likely be much faster than the intrinsic `findloc` which presumably uses a linear search.

---

<div class="post-metadata">

**Author:** ![Niko](https://avatars.discourse-cdn.com/v4/letter/n/91b2a8/32.png) [@Niko](https://fortran-lang.discourse.group/u/Niko)\
**Post date:** [October 1, 2021, 8:35am UTC](https://fortran-lang.discourse.group/t/findloc-alternative/1968/11 "2021-10-01T08:35:48Z")

</div>

Oh, thanks! I wasn’t aware of this effort to emulate unsupported features! What a noble intention. 🙂

@rwmsu Excellent work! Many thanks!!

@shahmoradi That’s an excellent point. I will do some experiments to see how does findloc perform in terms of speed in the case of interest. Thank you!
