Package: gotranx
gotranxgotranxis the next generation General ODE translator and is an attempt to a full rewrite ofgotran.The general idea is that you write your ODE in a high level markup language and usegotranxto generate code for solving the ODE in different programming languages.gotranxusessympyto generate the numerical schemes.Note:gotranxis still under active development, so do not expect it to be complete.InstallInstall with pippython3 -m pip install gotranxor for the development versionpython3 -m pip install git+https://github.com/finsberg/gotranxQuick startDefine you ode in an.odefile, for example for the Lorentz attractor you can write the following file (calledlorentz.ode)parameters(
sigma=12.0,
rho=21.0,
beta=2.4
)

states(x=1.0, y=2.0,z=3.05)

dx_dt = sigma * (y - x)
dy_dt = x * (rho - z) - y
dz_dt = x * y - beta * zwhich defines the parameters and states with default initial conditions. For each state-variable we also define the derivatives usingdx_dtfor the state with namex.Now we can generate code that can be used to solve the equation, e.gpython3 -m gotranx lorentz.ode --to .py --scheme forward_explicit_eulerwhich will generate a python filelorentz.pycontaining the following functionsimportnumpydefparameter_index(name:str)->float:"""Return the index of the parameter with the given nameArguments---------name : strThe name of the parameterReturns-------floatThe index of the parameterRaises------KeyErrorIf the name is not a valid parameter"""data={"beta":0,"rho":1,"sigma":2}returndata[name]defstate_index(name:str)->float:"""Return the index of the state with the given nameArguments---------name : strThe name of the stateReturns-------floatThe index of the stateRaises------KeyErrorIf the name is not a valid state"""data={"x":0,"y":1,"z":2}returndata[name]definit_parameter_values(**values):"""Initialize parameter values"""# beta=2.4, rho=21.0, sigma=12.0parameters=numpy.array([2.4,21.0,12.0])forkey,valueinvalues.items():parameters[parameter_index(key)]=valuereturnparametersdefinit_state_values(**values):"""Initialize state values"""# x=1.0, y=2.0, z=3.05states=numpy.array([1.0,2.0,3.05])forkey,valueinvalues.items():states[state_index(key)]=valuereturnstatesdefrhs(t,states,parameters):# Assign statesx=states[0]y=states[1]z=states[2]# Assign parametersbeta=parameters[0]rho=parameters[1]sigma=parameters[2]# Assign expressionsvalues=numpy.zeros(3)values[0]=sigma*(-x+y)values[1]=x*(rho-z)-yvalues[2]=-beta*z+x*yreturnvaluesdefforward_explicit_euler(states,t,dt,parameters):# Assign statesx=states[0]y=states[1]z=states[2]# Assign parametersbeta=parameters[0]rho=parameters[1]sigma=parameters[2]# Assign expressionsvalues=numpy.zeros(3)dx_dt=sigma*(-x+y)values[0]=dt*dx_dt+xdy_dt=x*(rho-z)-yvalues[1]=dt*dy_dt+ydz_dt=-beta*z+x*yvalues[2]=dt*dz_dt+zreturnvaluesSimilarly, you can use the following commandpython3 -m gotranx lorentz.ode --to .h --scheme forward_explicit_eulerto generate a C-header file with the following content#include<math.h>voidinit_parameter_values(double*parameters){/*beta=2.4, rho=21.0, sigma=12.0*/parameters[0]=2.4;parameters[1]=21.0;parameters[2]=12.0;}voidinit_state_values(double*states){/*x=1.0, y=2.0, z=3.05*/states[0]=1.0;states[1]=2.0;states[2]=3.05;}voidrhs(constdoublet,constdouble*__restrictstates,constdouble*__restrictparameters,double*values){// Assign statesconstdoublex=states[0];constdoubley=states[1];constdoublez=states[2];// Assign parametersconstdoublebeta=parameters[0];constdoublerho=parameters[1];constdoublesigma=parameters[2];// Assign expressionsvalues[0]=sigma*(-x+y);values[1]=x*(rho-z)-y;values[2]=-beta*z+x*y;}voidforward_explicit_euler(constdouble*__restrictstates,constdoublet,constdoubledt,constdouble*__restrictparameters,double*values){// Assign statesconstdoublex=states[0];constdoubley=states[1];constdoublez=states[2];// Assign parametersconstdoublebeta=parameters[0];constdoublerho=parameters[1];constdoublesigma=parameters[2];// Assign expressionsconstdoubledx_dt=sigma*(-x+y);values[0]=dt*dx_dt+x;constdoubledy_dt=x*(rho-z)-y;values[1]=dt*dy_dt+y;constdoubledz_dt=-beta*z+x*y;values[2]=dt*dz_dt+z;}