0

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.

Ars3nous
  • 136
  • 1
  • 1
  • 8

1 Answers1

2

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)
Alexander Vogt
  • 17,879
  • 13
  • 52
  • 68
  • I understand what you are saying, but is there a way around by not having to specify from outside? because for the original program I want the d2 to be N for odd and N+1 for even. I could pass on arguments in the function itself and declared the array, but I was wondering if that could be bypassed – Ars3nous Mar 02 '15 at 14:30
  • This perhaps misses an important idea: explicit shape dummy argument arrays behave quite differently from assumed shape dummy argument arrays in several ways. – francescalus Mar 02 '15 at 14:34
  • 1
    At some point within your program you have to decide how large your arrays should be. My guess is, that you would like to do that in Python, and pass the arrays to the Fortran code. If you want to do that in Fortran, you'd probably need to `allocate` the arrays or use automatic allocation. Either way, since you pass the input to the subroutine and expect an output, those arrays must exist before and after calling the subroutine. – Alexander Vogt Mar 02 '15 at 14:34
  • @francescalus: You are probably right. I appended a variant with explicit shape dummy arguments to my answer. – Alexander Vogt Mar 02 '15 at 14:38
  • 1
    Yes, or even better: `N+1-mod(N,2)` to get what is wanted in the first comment! – Alexander Vogt Mar 02 '15 at 15:04
  • @HighPerformanceMark I got that... and removed `merge` from the answer! In their first comment, the OP states that they ultimately want to have *"N for odd and N+1 for even"*. Following your idea, this would result in `N+1-mod(N,2)`. – Alexander Vogt Mar 02 '15 at 15:11
  • Thanx you @AlexanderVogt so much for your answers. N+1 -mod(N,2) was my solution too. I already did this, and this seems to be natural (and better) way to do it as pointed out by you. I wanted to know if doing that in fortran was possible. If I dont get an answer by tomorrow, I would accept this as correct answer. – Ars3nous Mar 02 '15 at 15:31