pythonfortranf2py

Getting two values from fortran for Python?


Is it possible to get two values from fortran? for example, I want to get the maximum score and this coordinate from a matrix

# python code 
import numpy as np

matrix = np.array([[1, 10, 3, 4, 9],
                  [2, 1, 0, 9, 13], 
                  [3, 5, 10, 18, 3]])

max_score= 0
column_coord = 0
row_coord = 0

for i in range(len(matrix[:,0])):
    for j in range(len(matrix[0,:])):
        if matrix[i, j] >= max_score:
            # getting max_score, column, row coordinate
            max_score= matrix[i, j]
            column_coord = i
            row_coord = j
print(max_score, column_coord, row_coord)

This code works fine, but if the matrix gets bigger, it will take a lot of time to find the values that I want.
So, I decided to use the f2py for faster calculation, and this is the fortran code. cc is column length, and rr is row length.

subroutine findthemax(cc, rr, matrix, max_score, col_coord, row_coord)
integer, intent(in) :: cc, rr 
integer, intent(in) :: matrix(0:cc, 0:rr)
integer, intent(out) :: max_score, col_coord, row_coord

max_score = 0
col_coord = 0
row_coord = 0

do i = 1, cc
    do j = 1, rr
        if (matrix(i, j).GE.max_score) then
            max_score = matrix(i, j)
            col_coord = i
            row_coord = j
        end if        
    end do
end do
return
end subroutine

I want to get the max_score, col_coord, row_coord, so I imported findthemax module
(named findthemax.f90) that I transformed by f2py.

import numpy as np

matrix = np.array([[1, 10, 3, 4, 9],
                  [2, 1, 0, 9, 13], 
                  [3, 5, 10, 18, 3]])

cc = len(matrix[:,0])
rr = len(matrix[0,:])

max_score, column_coord, row_coord = findthemax.findthemax(cc, rr, matrix)

I don't know why this doesn't work, and that's because I don't actually know
how to return more than two values with fortran and f2py. Could someone please tell me how to
get the multiple values from fortran?


Solution

  • You can use a fortran subroutine with multiple return values in the following way.

    Fortran code findthemax.f90

    subroutine findthemax(matrix, max_score, row, col)
      integer, intent(in)  :: matrix(:,:)
      integer, intent(out) :: max_score, row, col
    
      integer :: ind(2)
    
      ind       = maxloc(matrix)
      row       = ind(1)
      col       = ind(2)
      max_score = matrix(row,col)
    end subroutine
    

    Compile it via f2py

    $ f2py -c findthemax.f90 -m findthemax
    

    Import it into your python code

    import findthemax
    import numpy as np
    
    matrix = np.array([[1, 10,  3,  4,  9],
                       [2,  1,  0,  9, 13],
                       [3,  5, 10, 18,  3]])
    
    (max_score, row, col) = findthemax.findthemax(matrix)
    
    print(max_score)        # 18
    print(row)              #  3
    print(col)              #  4