2012-09-19 9 views
0

배열을 동적으로 할당하는 데 도움이 필요합니다.Fortran의 동적 메모리 할당

각 단계마다 크기가 계속 변경되는 배열이 있습니다. 행 벡터로 시작하여주기의 각 단계마다 다른 행 벡터를 추가합니다. 추가 계산을 위해이 새로운 배열을 사용해야합니다.

배열을 allocatable로 선언하고 do 루프 내에서 할당하려고 시도했지만 제대로 작동하지 못했습니다.

특정 배열에 대한 메모리 할당을 해제 할 때 어떤 일이 발생하는지 아직 명확하지 않습니다. 데이터가 손실 된 경우 할당을 해제하기 전에 데이터를 저장하려면 다른 배열을 사용합니까? 해당 배열의 크기는 어떻게 지정합니까?

도움을 주시면 감사하겠습니다.

! 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 
+0

to_rref 서브 루틴은 shape 인수가 있다고 가정합니다. 즉, 호출되는 모든 범위에서 명시적인 인터페이스가 있어야 함을 의미합니다. 이러한 인터페이스는 주 프로그램에 존재하지 않습니다. 서브 루틴을 모듈에 넣거나 명시 적 인터페이스 블록을 제공하십시오. 코드가 의미가 없다는 것을 고칠 때까지 – IanH

답변

2

예, 메모리를 할당 해제하면 더 이상 존재하지 않는 것으로 간주해야합니다. Fortran 95 및 이전 버전에서 배열을 확장하려면 데이터를 다른 배열에 복사하고 배열을 할당 해제 한 다음 해당 부분을 다시 할당하고 복사해야합니다. Fortran 2003은 프로세스를 단순화하는 내장 프로 시저 인 move_alloc을 제공합니다.