2016-08-19 39 views
9

W oparciu o dawny przykład, który znalazłem here, próbuję dowiedzieć się, jak wygenerować kod Fortran, który odpowiada konkretnemu formularzowi, do którego muszę się przykleić. Wymagana kodu FORTRAN będzie wyglądać następująco (it is based on the FitzHugh–Nagumo model):Generowanie podprogramu Fortran z kodekiem SymPy dla systemu równań

SUBROUTINE FF(NE,U,PAR,F) 
!  ---------- -- 
!  Define the nonlinear term 

    IMPLICIT NONE 
    INTEGER, INTENT(IN) :: NE 
    DOUBLE PRECISION, INTENT(IN) :: U(NE),PAR(*) 
    DOUBLE PRECISION, INTENT(OUT) :: F(NE) 

    DOUBLE PRECISION u,v,e,a1,a0 

    u=U(1) 
    v=U(2) 
    e=PAR(1) 
    a1=PAR(2) 
    a0=PAR(3) 

    F(1)= u-u**3-v 
    F(2)= e*(u-a1*v-a0) 

    END SUBROUTINE FF 

udaje mi się stworzyć odpowiednie wyrażenia w SymPy, ale nie zorientowali się, jak wygenerować żądany kod z codegen. Oto moja próba tak daleko:

from sympy import symbols,latex 
from sympy.utilities.codegen import codegen 
from sympy.tensor import IndexedBase, Idx 
from sympy import Matrix 
U, PAR = symbols('U PAR', cls=IndexedBase) 

u = U[1] 
v = U[2] 

e = PAR[1] 
a1 = PAR[2] 
a0 = PAR[3] 

dudt = u-u**3-v 
dvdt = e*(u-a1*v-a0) 

print latex(dudt) 
print latex(dvdt) 

F = Matrix([dudt,dvdt]) 
print F 

result = codegen(('my_function', F), 'f95', 'my_project') 
print result[0][1] 

ale daje mi:

IndexException: 
Range is not defined for all indices in: PAR[3] 
+0

Myślę, że chce zadeklarować kształt dla IndexedBase. Ale nawet wtedy jest problem, ponieważ chce traktować indeksowane obiekty jako tensory. – asmeurer

+0

Naprawdę powinniśmy wyłączyć domyślną konwencję sumowania w drukarce kodu. –

Odpowiedz

1

Jeśli wystarczy wywołać funkcję FORTRAN w kodzie Pythona, znalazłem, że przy użyciu opakowanie FORTRAN był znacznie prostsze niż próba odtworzenia kodu FORTRAN w pythonie, szczególnie jeśli GOTO są mocno wykorzystywane.

Czy próbowałeś f2py? https://sysbio.ioc.ee/projects/f2py2e/