Search code examples
pythonarraysfortranf2py

defining arrays in fortran after dynamic size declaration


I am new to Fortran and what I want is that my size of the matrix depends on if N is even or odd, Naively I would try something like below, but this doesnt compile, if I remove the if statement it works fine though,

 subroutine f(fMatrix,oMatrix,N)
      implicit none; 
      integer,intent(in)::N
      integer::d2
      if(mod(N,2)==0) then ! if N is even then 1 type of size
        parameter(d2=1)
      else
        parameter(d2=2)
      endif
      double precision,intent(in),dimension(N, d2):: fMatrix
      double precision,intent(out),dimension(N, d2):: oMatrix
      !do stuff here with fMatrix
      oMatrix = fMatrix
 end subroutine f

What would be possible workaround for this? without going to allocate? I am working with f2py, so any specifics in that way would be convenient.


Solution

  • I think this is closest to what you want to achieve:

    subroutine f(fMatrix,oMatrix,N)
      implicit none
      integer,intent(in)                                    :: N
      double precision,intent(in),dimension(N, mod(N,2)+1)  :: fMatrix
      double precision,intent(out),dimension(N, mod(N,2)+1) :: oMatrix
    
      ! ...
      oMatrix = fMatrix
    end subroutine
    

    I personally would prefer one of the following solutions:

    1. Since both fMatrix and oMatrix are dummy arguments and are passed to the subroutine, you can use assumed shape array specifications:
    subroutine f(fMatrix,oMatrix,N)
      implicit none
      integer,intent(in)                           :: N
      double precision,intent(in),dimension(:, :)  :: fMatrix
      double precision,intent(out),dimension(:, :) :: oMatrix
    
      ! ...
    end subroutine
    

    Now the calling program needs to specify the shape of the arrays.

    1. Define d2 externally and pass it to the subroutine as well:
    subroutine f(fMatrix,oMatrix,N, d2)
      implicit none
      integer,intent(in)                            :: N, d2
      double precision,intent(in),dimension(N, d2)  :: fMatrix
      double precision,intent(out),dimension(N, d2) :: oMatrix
    
      ! ...
    end subroutine
    

    and call the subroutine with:

    call f(fMatrix,oMatrix,N,mod(N,2)+1)