Ticket #8950: trac_8950_desolve_numerical.patch

File trac_8950_desolve_numerical.patch, 6.9 KB (added by uri, 3 years ago)
  • sage/calculus/all.py

    # HG changeset patch
    # User Oriol Castejon <oriol.castejon@gmail.com>
    # Date 1273594153 -7200
    # Node ID de4e5f716010e9e1c9094c4761bcba5e777aa885
    # Parent  eb27a39a6df43f557bdc8bc838c30f3b5c41e925
    trac 8950: add new function to solve sytems of first order differential equations, more efficient than the existing
    
    diff -r eb27a39a6df4 -r de4e5f716010 sage/calculus/all.py
    a b  
    1010 
    1111from desolvers import (desolve, desolve_laplace, desolve_system, 
    1212                       eulers_method, eulers_method_2x2,  
    13                        eulers_method_2x2_plot, desolve_rk4, desolve_system_rk4) 
     13                       eulers_method_2x2_plot, desolve_rk4, desolve_system_rk4, desolve_numerical) 
    1414 
    1515from var import (var, function, clear_vars) 
    1616 
  • sage/calculus/desolvers.py

    diff -r eb27a39a6df4 -r de4e5f716010 sage/calculus/desolvers.py
    a b  
    10531053    sol.extend(sol_2) 
    10541054 
    10551055    return sol 
     1056 
     1057def 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