2012-11-19 15 views
5

Si supponga di dover chiamare la funzione fortran, che restituisce alcuni valori, nel programma python. Ho scoperto che la riscrittura del codice FORTRAN in modo tale:creazione di amici python e fortran

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 

e chiamandolo in python in modo tale:

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

ci dà risultato di lavoro. Posso chiamare la funzione fortran in un altro modo, perché penso che il primo modo sia un po 'maldestro?

+0

Considerare l'utilizzo di IPython? – inspectorG4dget

+0

Come può aiutarmi? Per quanto ne so è una sorta di modalità interattiva aggiornata. – user983302

+1

Consente inoltre di interfacciarsi con altri programmi come R, MATLAB e FORTRAN. Dai un'occhiata [questo video] (http://pyvideo.org/video/1605/science-and-python-retrospective-of-a-mostly-s) – inspectorG4dget

risposta

10

Penso solo bisogno di cambiare un po 'il vostro f2py firma funzione (in modo che out_x è solo intent(out) e in_x è solo 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 

Ora compilare:

f2py -m test -c test.f90 

Ora eseguire:

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

nota che in questo caso, f2py è in grado di eseguire la scansione correttamente la firma della funzione senza le speciali !f2py commenti:

!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 

Compile:

f2py -m test2 -c test2.f90 

run:

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

Wow, è fantastico! In questo modo persino puoi restituire più variabili in tuple! Solo per la mia curiosità, se ci sono altri trucchi, non spunta questa risposta proprio ora. – user983302

+0

Sono spesso impressionato da quanto sia facile racchiudere il codice fortran con 'f2py'. Per questo motivo, non mi sono mai preso la briga di imparare alcuna API Python o anche 'Cython', anche se a un certo punto mi piacerebbe riprendere queste abilità. – mgilson

0

Un altro vantaggio per avoi ding intent(inout) argomenti è (con alcune altre restrizioni) la funzione risultante can be considered PURE. Questo è legato all'approccio senza effetti collaterali adottato dai linguaggi funzionali e si ripaga con una migliore ottimizzazione e rilevamento degli errori da parte del compilatore Fortran ed è particolarmente importante per l'auto-parallelizzazione.

0

Se stai usando IPython, provare il comando magia, che lo rende in grado di scrivere

%%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 

e poi semplicemente utilizzare questa funzione nel codice (senza importazioni supplementari).