I need some help with allocating arrays dynamically.
I have an array whose size keeps changing at each step – I start with a row vector and add another row vector at each step of a cycle. I need to use this new array for further calculations.
I’ve been trying to declare the arrays as allocatable, and then allocate them within a do-loop, but I haven’t been able to get it working properly.
I am still not very clear with what happens when you deallocate the memory for that particular array. If the data is lost, then to store it before deallocation, do I use another array? How do I specify the size of that array?
Any help would be greatly appreciated.
! Program to generate a matrix whose rows are linearly independent vectors.
! The elements of the matrix are either 1 or -1
program trial
implicit none
integer, parameter ::n=10,p=5 !where 'p' gives the no. of rows, & 'n' gives the no. of columns
real(kind=8),dimension(p,n) ::z1
! The array to be generated - this needs to be made allocatable
! I'll need the values of this array for further calculations, so should I store
! them in another array?
integer::i,j,k,s1 !counters used
real(kind=8),dimension(n)::x
do i=1,p
15 call random_number(x) !generate random row vectors
z1(i,:)=x
! To make the array elements 1's and -1's
do j=1,n
if (z1(i,j).ge.0.5) then
z1(i,j)=1.d0
! write(*,*),z1(i,j)
else
z1(i,j)=-1.d0
! write(*,*),z1(i,j)
endif
enddo
! Checking the output so far
print*,'Z1'
do k=1,i
write(*,*)(z1(k,j),j=1,n)
enddo
! To ckeck for linear independence, get the reduced row echelon form. Check the rows
! of the rref array, if any of the rows contains only zeros, the vectors are not
! linearly independent. Hence, regenerate that particular row of the array.
! Check for linear independence as each row is added
call to_rref(z1)
do k=1,i
s1=0
do j=1,n
if(z1(k,j)==0)then
s1=s1+1
endif
if (s1==n) then
print *,'THE VECTORS ARE NOT LINEARLY INDEPENDENT'
goto 15
endif
enddo
enddo
do k=1,i
write(*,*)(z1(k,j),j=1,n)
enddo
enddo
end
! Subroutine for getting the reduced row echelon form
subroutine to_rref(matrix)
implicit none
real, dimension(:,:), intent(inout) :: matrix
integer :: pivot, norow, nocolumn
integer :: r, i
real, dimension(:), allocatable :: trow
pivot = 1
norow = size(matrix, 1)
nocolumn = size(matrix, 2)
allocate(trow(nocolumn))
do r = 1, norow
if ( nocolumn <= pivot ) exit
i = r
do while ( matrix(i, pivot) == 0 )
i = i + 1
if ( norow == i ) then
i = r
pivot = pivot + 1
if ( nocolumn == pivot ) return
end if
end do
trow = matrix(i, :)
matrix(i, :) = matrix(r, :)
matrix(r, :) = trow
matrix(r, :) = matrix(r, :) / matrix(r, pivot)
do i = 1, norow
if ( i /= r ) matrix(i, :) = matrix(i, :) - matrix(r, :) * matrix(i, pivot)
end do
pivot = pivot + 1
end do
deallocate(trow)
end subroutine to_rref
Yes, when you deallocate memory you must regard it as no longer existent. In Fortran 95 and earlier, if you wish to expand an array, you must copy the data to another array, deallocate the array, reallocate and copy the portion back. Fortran 2003 provides an intrinsic procedure that simplifies the process: move_alloc.