Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Resize of a dynamic array

gsfantos
Beginner
616 Views
Is there any way to resize a dynamic allocatable array, i.e. A(k,l) to A(k+1,l+3), but not loose any of the data in A(k,l) and the data to remain in the same position. Also it is desirable not to allocate another array with the new dimensions and copy the data of the previous. The resizing will be always by adding columns or rows.
Thanks a lot in advance
0 Kudos
5 Replies
anthonyrichards
New Contributor III
616 Views
If you have a n-row Xm-column array, the numbers will be stored in consecutive locations and they will be correctly found using array reference indeces. E,.g The location Array(i,j) will be found using the offset (n-1)*j+(i-1) from the address of the first element. However, if you add a row (which must bem elements since you have defined it as anxm arrray) without moving the numbers, then the number previously element(i,j)is still stored at offset (j-1)*n+(i-1)=3 from the first element, but its offset in a (n+1)-row by m-column array should be (j-1)*(n)+(I+1), which is (j-1) elements further along the set of locations. The code will look for it there and will find another (wrong)value. Since I presume you wish to continue referencing array locations using standard array indeces (i,j), you have no choice but to recast your data into the format of a (n+1) Xm array. It follows that you have toallocate a newsection of consecutive memory locations and copy your (old) data there, making due allowance for the new row dimension. Thus element A(i,j), in location offset(n-1)*j+(i-1) must be copied to B(i,j) in location offset(j-1)*(n)+(I+1). This is all taken care of automatically in the codewhen you dimension A(n,m) and the new array B(n+1,m).
0 Kudos
gsfantos
Beginner
616 Views
Thanks a lot , that was very helpful
But is there any special function or command that resizes an array automatically and keeps the elements it has inside?
0 Kudos
Les_Neilson
Valued Contributor II
616 Views

Not until the 2003 Fortran standard ReAllocate capability is provided.

The followingshows a (cut down version of a) technique I use a lot usingmodules,pointers and allocatable arrays :

Code:

Module X

! Assign appropriate values to the following 3 integers
   integer*4 :: InitialSize
   integer*4 :: CurrentSize
   integer*4 :: Increment

! Pointer and target arrays 
   real*8,        pointer :: zlevel(:)                   ! Z Level
   real*8,        allocatable, target :: zlevel_a(:)     ! Z Level
   real*8,        allocatable, target :: zlevel_b(:)     ! Z Level

CONTAINS
   subroutine AllocateZLevel
! having set an appropriate value for InitialSize
      allocate(zlevel_a(InitialSize),stat=ierr)

! Point zlevel to zlevel_a
      zlevel => zlevel_a

! Initialise zlevel to some appropriate starting value
      zlevel = 0.0.d0
      CurrentSize = InitialSize

   end subroutine AllocateZLevel

   subroutine ReAllocateZLevel(ierr)

      osize = CurrentSize
      nsize = osize + INCREMENT
! Check which array is currently allocated a or b
! Allocate the other with the new size
! Copy the data from old array to the new array
! Point the pointer to the new array

      if (allocated(zlevel_b)) then
         allocate(zlevel_a(nsize), stat=ierr)
         if (ierr == 0) then
            do i=1,osize
               zlevel_a(i) = zlevel(i)
            enddo
            deallocate(zlevel_b, stat=i)
            zlevel => zlevel_a
         endif
      else
         allocate(zlevel_b(nsize), stat=ierr)
         if (ierr == 0) then
            do i=1,osize
               zlevel_b(i) = zlevel(i)
            enddo
            deallocate(zlevel_a, stat=i)
            zlevel => zlevel_b
         endif
      endif

      if (ierr == 0) then
         CurrentSize = nsize
      endif

      return
      end subroutine ReAllocateZLevel

end module X


I hope you see the principle anyway. Thedata is referenced throughout the code by zlevel and zlevel points to either zlevel_a or zlevel_bdepending on the calls to ReAllocateZLevel

Les

0 Kudos
Steven_L_Intel1
Employee
616 Views
There is no REALLOCATE in Fortran 2003. There is MOVE_ALLOC which is implemented in current Intel Fortran compilers and is designed to be used for this purpose. It is described in the release notes.
0 Kudos
Les_Neilson
Valued Contributor II
616 Views

Sorry for the misinformation. I thought I remembered something about the programmerbeing able to reallocate arrays (in place?)in F2003 I wasn't sure ifthere was a function/subroutine to do it though, or whether it wasan automatic "behind the scene" thing on assignment.

Reading more closelythe document"New features of Fortran 2003" by John Reid I see the use of MOVE_ALLOC.

Thanks Steve for the correction

Les

0 Kudos
Reply