| | 1056 | |
| | 1057 | def desolve_numerical(des, ics, times, dvars, ivar=None, ComputeJacobian=False, args=(), ml=None, mu=None, rtol=None, atol=None, tcrit=None, h0=0.0, hmax=0.0, hmin=0.0, ixpr=0, mxstep=0, mxhnil=0, mxordn=12, mxords=5, printmessg=0): |
| | 1058 | """ |
| | 1059 | Solves numerically a system of first-order ordinary differential equations using odeint from scipy.integrate module. |
| | 1060 | |
| | 1061 | INPUT: |
| | 1062 | des -- right hand sides of the system |
| | 1063 | ics -- initial conditions |
| | 1064 | times -- a sequence of time points in which the solution must be found |
| | 1065 | dvars -- dependent variables. ATTENTION: the order must be the same as in des, that means: d(dvars[i])/dt=des[i] |
| | 1066 | ivar -- independent variable, default is t |
| | 1067 | ComputeJacobian -- boolean. If True, the Jacobian of des is computed and used during the integration of Stiff Systems. Default value is False. |
| | 1068 | |
| | 1069 | Other Parameters (taken from the documentation of odeint function from scipy.integrate module) |
| | 1070 | ---------------------------------------------------------------------------------------------- |
| | 1071 | ml, mu : integer |
| | 1072 | If either of these are not-None or non-negative, then the |
| | 1073 | Jacobian is assumed to be banded. These give the number of |
| | 1074 | lower and upper non-zero diagonals in this banded matrix. |
| | 1075 | For the banded case, Dfun should return a matrix whose |
| | 1076 | columns contain the non-zero bands (starting with the |
| | 1077 | lowest diagonal). Thus, the return matrix from Dfun should |
| | 1078 | have shape len(y0) * (ml + mu + 1) when ml >=0 or mu >=0 |
| | 1079 | rtol, atol : float |
| | 1080 | The input parameters rtol and atol determine the error |
| | 1081 | control performed by the solver. The solver will control the |
| | 1082 | vector, e, of estimated local errors in y, according to an |
| | 1083 | inequality of the form:: |
| | 1084 | max-norm of (e / ewt) <= 1 |
| | 1085 | where ewt is a vector of positive error weights computed as:: |
| | 1086 | ewt = rtol * abs(y) + atol |
| | 1087 | rtol and atol can be either vectors the same length as y or scalars. |
| | 1088 | tcrit : array |
| | 1089 | Vector of critical points (e.g. singularities) where integration |
| | 1090 | care should be taken. |
| | 1091 | h0 : float, (0: solver-determined) |
| | 1092 | The step size to be attempted on the first step. |
| | 1093 | hmax : float, (0: solver-determined) |
| | 1094 | The maximum absolute step size allowed. |
| | 1095 | hmin : float, (0: solver-determined) |
| | 1096 | The minimum absolute step size allowed. |
| | 1097 | ixpr : boolean |
| | 1098 | Whether to generate extra printing at method switches. |
| | 1099 | mxstep : integer, (0: solver-determined) |
| | 1100 | Maximum number of (internally defined) steps allowed for each |
| | 1101 | integration point in t. |
| | 1102 | mxhnil : integer, (0: solver-determined) |
| | 1103 | Maximum number of messages printed. |
| | 1104 | mxordn : integer, (0: solver-determined) |
| | 1105 | Maximum order to be allowed for the nonstiff (Adams) method. |
| | 1106 | mxords : integer, (0: solver-determined) |
| | 1107 | Maximum order to be allowed for the stiff (BDF) method. |
| | 1108 | |
| | 1109 | |
| | 1110 | OUTPUT: |
| | 1111 | Returns a list with the solution of the system at each time in times. |
| | 1112 | |
| | 1113 | |
| | 1114 | EXAMPLES: |
| | 1115 | 1) Lotka Volterra Equations: |
| | 1116 | |
| | 1117 | sage: from sage.calculus.desolvers import desolve_numerical |
| | 1118 | sage: x,y=var('x,y') |
| | 1119 | sage: sol=desolve_numerical([x*(1-y),-y*(1-x)],[0.5,2],srange(0,10,0.1),[x,y]) |
| | 1120 | sage: p=line(zip(sol[:,0],sol[:,1])) |
| | 1121 | sage: p.show() |
| | 1122 | |
| | 1123 | |
| | 1124 | 2) Lorenz Equations: |
| | 1125 | |
| | 1126 | sage: from sage.calculus.desolvers import desolve_numerical |
| | 1127 | sage: from sage.plot.plot3d.shapes2 import Line |
| | 1128 | sage: x,y,z=var('x,y,z') |
| | 1129 | sage: # Next we define the parameters |
| | 1130 | sage: sigma=10 |
| | 1131 | sage: rho=28 |
| | 1132 | sage: beta=8/3 |
| | 1133 | sage: # The Lorenz equations |
| | 1134 | sage: lorenz=[sigma*(y-x),x*(rho-z)-y,x*y-beta*z] |
| | 1135 | sage: # Time and initial conditions |
| | 1136 | sage: times=srange(0,50.05,0.05) |
| | 1137 | sage: ics=[0,1,1] |
| | 1138 | sage: sol=desolve_numerical(lorenz,ics,times,[x,y,z],rtol=1e-13,atol=1e-14) |
| | 1139 | |
| | 1140 | |
| | 1141 | 3) One-dimensional Stiff system: |
| | 1142 | |
| | 1143 | sage: from sage.calculus.desolvers import desolve_numerical |
| | 1144 | sage: y= var('y') |
| | 1145 | sage: epsilon=0.01 |
| | 1146 | sage: f=y^2*(1-y) |
| | 1147 | sage: ic=epsilon |
| | 1148 | sage: times=srange(0,2/epsilon,1) |
| | 1149 | sage: sol=desolve_numerical(f,ic,times,y,rtol=1e-13,atol=1e-14,ComputeJacobian=True) |
| | 1150 | sage: p=points(zip(times,sol)) |
| | 1151 | sage: p.show() |
| | 1152 | |
| | 1153 | |
| | 1154 | 4) Another Stiff system with some optional parameters with no default value: |
| | 1155 | |
| | 1156 | sage: y1,y2,y3=var('y1,y2,y3') |
| | 1157 | sage: f1=77.27*(y2+y1*(1-8.375*1e-6*y1-y2)) |
| | 1158 | sage: f2=1/77.27*(y3-(1+y1)*y2) |
| | 1159 | sage: f3=0.16*(y1-y3) |
| | 1160 | sage: f=[f1,f2,f3] |
| | 1161 | sage: ci=[0.2,0.4,0.7] |
| | 1162 | sage: times=srange(0,10,0.01) |
| | 1163 | sage: sol=desolve_numerical(f,ci,times,[y1,y2,y3],ComputeJacobian=True,rtol=1e-3,atol=1e-4,h0=0.1,hmax=1,hmin=1e-4,mxstep=1000,mxords=17) |
| | 1164 | |
| | 1165 | |
| | 1166 | AUTHOR: Oriol Castejon (05-2010) |
| | 1167 | """ |
| | 1168 | |
| | 1169 | from scipy.integrate import odeint |
| | 1170 | from sage.ext.fast_eval import fast_float |
| | 1171 | from sage.calculus.functions import jacobian |
| | 1172 | |
| | 1173 | if ivar==None: |
| | 1174 | from sage.symbolic.ring import var |
| | 1175 | ivar=var('t') |
| | 1176 | |
| | 1177 | # one-dimensional systems: |
| | 1178 | if len(dvars)==1 or len(dvars)==0: |
| | 1179 | func=fast_float(des,dvars,ivar) |
| | 1180 | if ComputeJacobian==False: |
| | 1181 | Dfun=None |
| | 1182 | else: |
| | 1183 | J=jacobian(des,dvars) |
| | 1184 | J=J[0][0] |
| | 1185 | J=fast_float(J,dvars,ivar) |
| | 1186 | Dfun=lambda y,t: [J(y,t)] |
| | 1187 | |
| | 1188 | |