Search code examples
arraysfortrando-loops

How to obtain all variations of an array with elements being zero or one


I am going to write a do loop over possible values of an array elements. More specifically I have an array, say A(:) with size n and any element of array A can be 0 or 1. I want to iterate over all possible values of elements of A. Of course a simple way is

do A(1)=0, 1
 do A(2)=0, 1
  ....
   ! do something with array A

 end do 
end do 

but the size of my array is large and this method is not very suitable. is there a better way to do this?


Solution

  • Since this is binary only, why not (mis-)use integers for this task? Just increment the integer by one for each of the combinations and read out the corresponding bits using btest:

    program test
      implicit none
      integer, parameter  :: n = 3
      integer             :: i
      integer             :: A(n)
      integer             :: idx(n) = [(i, i=0,n-1)] ! bit positions start at zero
    
      ! Use a loop to increment the integer
      do i=0,2**n-1
        ! Get the bits at the lowest positions and map true to "1" and false to "0"
        A = merge( 1, 0, btest( i, idx ) )
        print *,A
      enddo
    end program
    

    This simple code fills A with all combinations (one at a time) and prints them successively.

    ./a.out 
               0           0           0
               1           0           0
               0           1           0
               1           1           0
               0           0           1
               1           0           1
               0           1           1
               1           1           1
    

    Note that Fortran only has signed integers, so the highest bit is not usable here. This leaves you up to 2^(32-1) combinations for (default) 4 byte integers if you start from zero as shown here (array length up to 31).

    To get the full range, do the loop in the following way:

      do i=-huge(1)-1,huge(1)
    

    This gives you the full 2^32 distinct variations for arrays of length 32.