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