Search code examples
fortran

I have an array of zeros and I want to add 1's to some array elements


I tried this in fortran.

The initial array is zeros, for example:

InitialMatrix = 0 0 
                0 0 
                0 0
                0 0

And I want to add numbers 1 sequentially:

FinalMatrix  =  0 0
                0 1
                1 0
                1 1

As if adding one bit at a time.

I generated a matrix containing all elements equal to zero and tried to use ibset to change the zero element to 1, but without success.

The code I made was this one:

program test
    implicit none
    integer(1) numSitio
    integer:: Comb
    integer:: i, j
    integer, dimension(10, 10)::MatrixZeros
    integer, dimension(10, 10)::MatrixSpins
    
    print*, "Set the number of sites: "
    read(*,*)numSitio
    
    Comb = 2**numSitio
    
    MatrixZeros = 0
    MatrixSpins = ibset(MatrixZeros, 1)
        

    do i = 1, Comb
        do j = 1, numSitio
            MatrixSpins(i,j) = 0
        end do
    end do

    do i = 1, Comb
        write(*,*)(MatrixSpins(i,j), j= 1, numSitio)
    end do

    
    !write(*,*)MatrixZeros
    
end program test

I generated a matrix of zeros to be auxiliary, and then I created the matrix of spins that I want. I tried using the ibset command to add numbers 1 to zero array.

Note: I want to generate a matrix with n columns and 2^n rows, where the first row is all zero elements and starting from the second row, add a 1 bit in the last column. In the third line, the rightmost bit (last column, move to the left column and go on adding bits 1 until in the last line of the matrix, all elements are 1.


Solution

  • If you simply want to count in binary, then just

    program test
       implicit none
       integer i, n
       character fmt
    
       print *, "Input number of bits: ";   read *, n
       write( fmt, "( i0 )" ) n
       print "( b0." // fmt // " )", ( i, i = 0, 2 ** n - 1 )
    
    end program test
    

    If you absolutely have to store all the configurations in a matrix (an array of characters would be just as good) then you can just count up with traditional "carry" operations:

    program test
       implicit none
       integer i, j, imx, jmx
       integer n
       integer, allocatable :: M(:,:)
    
       print *, "Input number of bits: ";   read *, n
       imx = 2 ** n - 1;   jmx = n - 1
       allocate( M(0:imx, 0:jmx) )
       M = 0
    
       do i = 1, imx
          M(i,:) = M(i-1,:)
          M(i,jmx) = M(i,jmx) + 1
          j = jmx
          do while ( M(i,j) > 1 )     ! "carry" operations
             M(i,j) = 0
             j = j - 1
             M(i,j) = M(i,j) + 1
          end do
       end do
    
       do i = 0, imx
          print "( *( i1, 1x ) )", M(i,:)
       end do
    
    end program test
    

    or you could use bit operations:

    program test
       implicit none
       integer i, j, imx, jmx, p
       integer n
       integer, allocatable :: M(:,:)
    
       print *, "Input number of bits: ";   read *, n
       imx = 2 ** n - 1;   jmx = n - 1
       allocate( M(0:imx, 0:jmx) )
       M = 0
    
       p = 1
       do j = 0, jmx
          do i = 0, imx
             if ( iand(i,p) > 0 ) M(i,jmx-j) = 1
          end do
          p = 2 * p
       end do
    
       do i = 0, imx
          print "( *( i1, 1x ) )", M(i,:)
       end do
    
    end program test