Finding the intersection of two arrays in Fortran

I am trying to create an intersection of two 1-D arrays in Fortran.

The goal is to use this intersection as a mask in maxloc

so that I can pull at most a few elements from one array to another (behavior similar to re-deleting root in max heap).

Currently I just set the value at the index found with maxloc

to zero after I insert the value at that index into the second array, but I was hoping Fortran had a clever mask related method. (It would be nice to leave the original array intact during this max-fetch procedure)

+3


source to share


1 answer


I'm not really sure what you mean. If you want to compare two indexes of arrays by index, you can do so simply by using ==

, for example:

INTEGER :: a(4), b(4)
LOGICAL :: inter(4)

a = (/ 1, 2, 3, 4 /)
b = (/ 4, 2, 3, 1 /)
inter = (a == b)  ! (/ F, T, T, F /)

      

This is not technically an intersection, but MASK

in MAXLOC

should be an array LOGICAL

, so I assumed this is what you want.

If you want to check if a value a

is anywhere b

you must use at least one loop DO

, I think:

DO j = 1, size(a)
    inter(j) = any(a(j) == b)
END DO

      



If you want to find the largest, say n values, you can use something like this:

function largest(vars, n)
    implicit none
    integer, intent(in) :: n
    real, dimension(:), intent(in) :: vars
    real, dimension(n) :: largest
    integer :: i
    logical, dimension(size(vars)) :: m
    integer :: mloc

    m = .TRUE.

    do i = 1, n
       mloc = maxloc(vars, DIM=1, MASK=m)
       m(mloc) = .FALSE.
       largest(i) = vars(mloc)
    end do
    return
end function largest

      

Basically it uses a mask that is true and then every time it returns the mask for the highest false, so that it doesn't get that value again in the next iteration.

Of course, this is the order (n * size (var)), so if n is large it might be faster to do bubble sort until you have the n largest values ​​accumulated at the end, then pick them up.

+6


source







All Articles