Allocate dynamic array with interdependent dimensions

后端 未结 2 1394
星月不相逢
星月不相逢 2021-01-18 18:21

This is a bit complicated; I\'d welcome any comments on how to improve the clarity of the question.

Ok, say I have an array:

real, allocatable :: A(:         


        
相关标签:
2条回答
  • 2021-01-18 19:11

    I think you can do this simply by allocating/deallocating the array

    Program test
        Implicit none
        Real, dimension(:,:,:), allocatable :: A
        Integer  :: i,N
        Write(*,*)"Enter N"; Read(*,*)N
        Do i = 1, N
        if(Allocated(A)) then 
        deallocate(A);Allocate(A(i,i,i*i))
        else
        allocate(A(i,i,i*i))
        end if
        Write(*,*)Shape(A)
        End do
    end program test
    

    Compiling the program using gfortran gives:

     Enter N
    5
               1           1           1
               2           2           4
               3           3           9
               4           4          16
               5           5          25
    
    0 讨论(0)
  • 2021-01-18 19:17

    Yes, you can use a derived type to accomplish this:

    TYPE array
      REAL,DIMENSION(:,:,:),ALLOCATABLE :: A
    ENDTYPE array
    
    INTEGER :: i
    INTEGER,PARAMETER :: n=10
    
    TYPE(array),DIMENSION(:),ALLOCATABLE :: B
    
    ALLOCATE(B(n))
    
    DO i=1,n
      ALLOCATE(B(i)%A(3,i,i*i))
      WRITE(*,*)SHAPE(B(i)%A)
    ENDDO
    
    END
    

    This approach allows each element of array B to be a multi-dimensional array of a different shape.

    The output of the program is as expected:

            3            1            1
            3            2            4
            3            3            9
            3            4           16
            3            5           25
            3            6           36
            3            7           49
            3            8           64
            3            9           81
            3           10          100
    

    EDIT: To further answer OP's edited question. Yes, it seems like you would need to do something like this, use nested derived type (compare to your code example to figure out what you did wrong):

    integer,parameter :: m=3,n=5
    
    type cellarray
      integer,dimension(:),allocatable :: c
    endtype cellarray
    
    type myarray
      integer,allocatable :: lev(:)
      type(cellarray),dimension(:),allocatable :: cell
    endtype myarray
    
    type(myarray),dimension(:),allocatable :: B
    
    allocate(B(m))
    
    ! Allocate and assign lev and cell:
    do i=1,m
      allocate(B(i)%lev(n))
      allocate(B(i)%cell(n))
      do j=1,n
        B(i)%lev(j)=j
      enddo
    enddo
    
    ! Based on value of lev, allocate B%cell%c:    
    do i=1,m
      do j=1,n
        allocate(B(i)%cell(j)%c(B(i)%lev(j)**2))
      enddo
    enddo
    
    ! Print out to check that it works:
    do j=1,n
      write(*,*)j,B(1)%lev(j),SIZE(B(1)%cell(j)%c)
    enddo
    
    end
    

    Tried this with gfortran 4.6.2. It produces expected output:

           1           1           1
           2           2           4
           3           3           9
           4           4          16
           5           5          25
    
    0 讨论(0)
提交回复
热议问题