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]
Myślę, że chce zadeklarować kształt dla IndexedBase. Ale nawet wtedy jest problem, ponieważ chce traktować indeksowane obiekty jako tensory. – asmeurer
Naprawdę powinniśmy wyłączyć domyślną konwencję sumowania w drukarce kodu. –