Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Need some help with dynamic memory allocation in Fortran

  1. Jul 13, 2012 #1
    Hi,

    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.

    Thank you
     
  2. jcsd
  3. Jul 13, 2012 #2

    chiro

    User Avatar
    Science Advisor

    Hey sue132 and welcome to the forums.

    Do you mind posting your code so that the readers can make specific suggestions? Without this kind of thing neither you nor the other readers benefit from the discourse.

    To post code surround your code with *CODE* */CODE* tags but replace the *'s with square brackets (left [ bracket before C and ] bracket after E for each tag).
     
  4. Jul 13, 2012 #3
    Thanks a lot.

    I've tried to include enough comments to make the code clear, hope it makes some sense.

    The current program is giving me a segmentation fault error, which I'm trying to rectify now.


    Code (Text):

    ! 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
     

    P.S.: I've used the rref function from numerical recipes, as I've heard that they are highly optimized.
     
  5. Jul 13, 2012 #4

    chiro

    User Avatar
    Science Advisor

    Do you have any debug output in terms of the line of code and the variable dump that gave you the error?

    Running it through a debugger should give you an error message and the line in which the program crashes.
     
  6. Jul 13, 2012 #5
    sue:

    Quick reply here

    First of all, I don't see why you need your z1 matrix allocatable when you are defining n and p with initial values and you even have your do-loop as "i=1,p"...

    Now, if the rref subroutine is destructive, then, yes, I would declared two matrices and call rref with both of them, one with intent(in) and one with intent(out) so that z1 does not gets destroyed.

    Also, if I understand your program correctly, I think I would turn the hard set "do i=1,p" for some index-less "do - enddo" loop with an 'exit' somewhere in between...after all, if you are checking linear independence every iteration, you do not want to throw away the entire matrix, you just want to re-do the last row and, so, you need to control the row number during your iteration...you may need to set it back 1...to that end, you cannot let it be a loop variable....maybe I am getting ahead of myself and you already knew that.

    my 2 cents.
     
  7. Jul 16, 2012 #6
    Thanks for the reply, gsal.

    I need the array to be allocatable, as my array size is ultimately pXn, but not throughout the program. My array starts with a 1Xn row vector and at each step, another row is added. Hence, it needs to be allocatable.

    And, I'm not discarding the entire array - I just go back to the step within the loop where a new row is generated, and as I'm still within the loop, I'm only generating the row afresh. At least, this is what I'm trying to do.

    Hope I'm clear...
     
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook




Similar Discussions: Need some help with dynamic memory allocation in Fortran
Loading...