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