2012-11-19 15 views
5

Załóżmy, że musimy wywołać funkcję Fortran, która zwraca niektóre wartości, w programie Pythona. I okazało się, że przepisanie kodu FORTRAN w taki sposób:Tworzenie python i fortran przyjaciele

subroutine pow2(in_x, out_x) 
     implicit none 
     real, intent(in)  :: in_x 
!f2py real, intent(in, out) :: out_x 
     real, intent(out)  :: out_x 
     out_x = in_x ** 2 
     return 
end 

i nazywając go w Pythonie w taki sposób:

import modulename 
a = 2.0 
b = 0.0 
b = modulename.pow2(a, b) 

daje nam wynik roboczą. Czy mogę inaczej nazwać funkcję fortrana, bo myślę, że pierwszy sposób jest trochę niezgrabny?

+0

Rozważ użycie IPython? – inspectorG4dget

+0

Jak to może mi pomóc? O ile wiem, jest to rodzaj ulepszonego trybu interaktywnego. – user983302

+1

Umożliwia również komunikację z innymi programami, takimi jak R, MATLAB i FORTRAN. Sprawdź [ten film wideo] (http://pyvideo.org/video/1605/science-and-python-retrospective-of-a-mostly-s) – inspectorG4dget

Odpowiedz

10

myślę, że wystarczy zmienić swój podpis funkcji f2py lekko (tak, że out_x jest tylko intent(out) i in_x jest tylko intent(in)):

subroutine pow2(in_x, out_x) 
    implicit none 
    real, intent(in) :: in_x 
    !f2py real, intent(in) :: in_x 
    real, intent(out)  :: out_x 
    !f2py real, intent(out) :: out_x 
    out_x = in_x ** 2 
    return 
end subroutine pow2 

Teraz skompilować:

f2py -m test -c test.f90 

Teraz uruchom:

>>> import test 
>>> test.pow2(3) #only need to pass intent(in) parameters :-) 
9.0 
>>> 

Należy zauważyć, że w tym przypadku, f2py jest w stanie poprawnie zeskanować podpis funkcji bez specjalne !f2py komentarze:

!test2.f90 
subroutine pow2(in_x, out_x) 
    implicit none 
    real, intent(in) :: in_x 
    real, intent(out)  :: out_x 
    out_x = in_x ** 2 
    return 
end subroutine pow2 

kompilacji:

f2py -m test2 -c test2.f90 

run:

>>> import test2 
>>> test2.pow2(3) #only need to pass intent(in) parameters :-) 
9.0 
>>> 
+0

Wow, to niesamowite! W ten sposób można zwrócić wiele zmiennych w krotce! Właśnie z powodu mojej ciekawości, jeśli są inne sztuczki, nie zaznaczę tej odpowiedzi w tej chwili. – user983302

+0

Jestem często pod wrażeniem tego, jak łatwo jest zawrzeć fortranowy kod za pomocą 'f2py'. Z tego powodu nigdy nie chciałem uczyć się żadnego z Pythona C API, a nawet "Cythona", chociaż w pewnym momencie chciałbym je podnieść. – mgilson

0

Kolejna korzyść dla uniknięcia ding intent(inout) argumenty są (z kilkoma innymi ograniczeniami) wynikową funkcją can be considered PURE. Jest to związane z brakiem efektów ubocznych podjętych przez języki funkcjonalne i opłaca się z lepszą optymalizacją i wykrywaniem błędów przez kompilator Fortranu i jest szczególnie ważne dla autokalaryzacji.

0

Jeśli używasz ipython, spróbuj magiczne komendy, co sprawia, że ​​w stanie napisać

%%fortran 
subroutine pow2(in_x, out_x) 
    implicit none 
    real, intent(in) :: in_x 
    real, intent(out)  :: out_x 
    out_x = in_x ** 2 
    return 
end subroutine pow2 

a następnie po prostu użyć tej funkcji w kodzie (bez dodatkowego importu).