Играю с f2py. Я немного запутался в numpy внутренних типах по сравнению с типами fortran 90. Похоже, я могу использовать только вещественные числа одинарной точности в fortran 90 при взаимодействии с python. Позвольте мне проиллюстрировать это на примере:
Скажем, у меня есть этот модуль fortran 90, test.f90, который нужно скомпилировать с помощью f2py и импортировать в python:
module test
implicit none
integer, parameter :: sp = selected_real_kind(6,37) ! single precision
integer, parameter :: dp = selected_real_kind(15,307) ! double precision
real(sp) :: r_sp = 1.0
real(dp) :: r_dp = 1.0_dp
end module
и я компилирую вот так:
f2py -c -m test test.f90
Затем в питоне:
>>> import test
>>> test.test.r_sp
array(1.0, dtype=float32)
>>> test.test.r_dp
array(1.0)
IOW, похоже, что f2py не принимает двойную точность. Это становится еще более проблематичным при передаче входных данных подпрограмме fortran 90 из python. Скажем, я расширил свой модуль до:
module test
implicit none
integer, parameter :: sp = selected_real_kind(6,37) ! single precision
integer, parameter :: dp = selected_real_kind(15,307) ! double precision
real(sp) :: r_sp = 1.0
real(dp) :: r_dp = 1.0_dp
contains
subroutine input_sp(val)
real(sp), intent(in) :: val
real(sp) :: x
x = val
write(*,*) x
end subroutine
subroutine input_dp(val)
real(dp), intent(in) :: val
real(dp) :: x
x = val
write(*,*) x
end subroutine
end module
f2py -c -m test test.f90
питон
>>> import test
>>> test.test.input_sp(array(1.0,dtype=float32))
1.0000000
>>> test.test.input_sp(array(1.0,dtype=float64))
1.0000000
>>> test.test.input_dp(array(1.0,dtype=float32))
-1.15948430791165406E+155
>>> test.test.input_dp(array(1.0,dtype=float64))
-1.15948430791165406E+155
Итак, похоже, что любая входная переменная, отправляемая из python, должна быть объявлена с одинарной точностью. Это известная проблема с f2py?
Кроме того, в качестве дополнительного вопроса: преобразование из sp в dp работает в следующем смысле:
subroutine input_sp_to_dp(val)
real(sp), intent(in) :: val(2)
real(dp) :: x(2)
x = val
write(*,*) x
end subroutine
Но мне интересно, специфично ли это вообще для компилятора? Могу ли я ожидать, что вышеуказанная подпрограмма будет работать правильно с любым компилятором любой архитектуры? При тестировании для всех вышеперечисленных примеров я использовал gfortran.