Ich spiele mit f2py herum. Ich bin etwas verwirrt über numpige intrinsische Typen vs. Fortran 90 Typen. Es scheint, als ob ich in Fortran 90 nur Einzelpräzisions-Reale verwenden kann, wenn ich mit Python interagiere. Lassen Sie mich mit einem Beispiel illustrieren:f2py: Spezifizieren Sie echte Genauigkeit in Fortran, wenn Sie mit Python interagieren?
Sagen, ich habe dieses Fortran 90-Modul, test.f90, mit f2py und importiert in Python erstellt werden:
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
und ich kompilieren wie folgt aus:
f2py -c -m Test test.f90
Dann in python:
>>> import test
>>> test.test.r_sp
array(1.0, dtype=float32)
>>> test.test.r_dp
array(1.0)
IOW, Es scheint, als ob f2py keine doppelte Genauigkeit akzeptiert. Dies wird noch problematischer, wenn die Eingabe von python an eine Fortran 90-Subroutine übergeben wird. Sagen, dass ich mein Modul zu erweitern:
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
Python
>>> 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
So scheint es, wie jeder Die von python zu sendende Eingabevariable muss als einfache Genauigkeit deklariert werden. Ist das ein bekanntes Problem mit f2py?
Auch als Follow-up-Frage: von sp Converting Werke dp, im folgenden Sinn:
subroutine input_sp_to_dp(val)
real(sp), intent(in) :: val(2)
real(dp) :: x(2)
x = val
write(*,*) x
end subroutine
Aber ich frage mich, ob dieser Compiler überhaupt spezifisch ist? Kann ich erwarten, dass die obige Subroutine mit jedem Compiler in jeder Architektur das Richtige tut? Beim Testen verwendete ich Gfortran für alle obigen Beispiele.
Danke für Ihre Antwort. Ich habe zuerst Methode 2, und das hat gut funktioniert. Aber dann habe ich versucht, dies auf das eigentliche Programm anzuwenden, das ich schreibe, das disttitils verwendet, um die Kompilierung über eine setup.py-Datei und so weiter zu machen. Ich fand dann heraus, dass es nicht genug war, nur eine .f2py_cmap-Datei zu haben, obwohl es aussprach, dass während des Builds Änderungen von .f2py_cmap erfolgreich angewendet wurden. Also musste ich Methode 3 verwenden. Eigentlich verwendete ich bereits ein separates Modul für die Definitionen von Präzisionsvariablen, aber ich hatte die Anweisung "use types" am oberen Ende des Moduls, das es verwendete, nicht innerhalb der einzelnen Unterprogramme. – arne