How to read a system of differential equations from a text file to solve the system with scipy.odeint?

前端 未结 1 612
梦如初夏
梦如初夏 2021-01-27 00:38

I have a large (>2000 equations) system of ODE\'s that I want to solve with python scipy\'s odeint.

I have three problems that I want to solve (maybe I will have to ask

相关标签:
1条回答
  • 2021-01-27 00:55

    This isn't a full answer, but rather some observations/questions, but they are too long for comments.

    dX_dt is called many times by odeint with a 1d array y and tuple t. You provide t via the args parameter. y is generated by odeint and varies with each step. dX_dt should be streamlined so it runs fast.

    Usually an expresion like [eq for eq in systemOfEquations] can be simplified to systemOfEquations. [eq for eq...] doesn't do anything meaningful. But there may be something about systemOfEquations that requires it.

    I'd suggest you print out systemOfEquations (for this small 3 line case), both for your benefit and ours. You are using sympy to translated the strings from the file into equations. We need to see what it produces.

    Note that myODEs is a function, not a file. It may be imported from a module, which of course is a file.

    The point to vals = dict(S=X[0], I=X[1], R=X[2], t=t) is to produce a dictionary that the sympy expressions can work with. A more direct (and I think faster) dX_dt function would look like:

    def myODEs(y, t, params):
        c,p, gamma = params
        beta = c*p
        dydt = [-beta*y[0]*y[1],
               beta*y[0]*y[1] - gamma*y[1],
               - gamma*y[1]]  
        return dydt
    

    I suspect that the dX_dt that runs sympy generated expressions will be a lot slower than a 'hardcoded' one like this.

    I'm going add sympy tag, because, as written, that is the key to translating your text file into a function that odeint can use.

    I'd be inclined to put the equation variability in the t parameters, rather a list of sympy expressions.

    That is replace:

        dydt = [-beta*y[0]*y[1],
               beta*y[0]*y[1] - gamma*y[1],
               - gamma*y[1]]  
    

    with something like

        arg12=np.array([-beta, beta, 0])
        arg1 = np.array([0, -gamma, -gamma])
        arg0 = np.array([0,0,0])
        dydt = arg12*y[0]*y[1] + arg1*y[1] + arg0*y[0]
    

    Once this is right, then the argxx definitions can be move outside dX_dt, and passed via args. Now dX_dt is just a simple, and fast, calculation.

    This whole sympy approach may work fine, but I'm afraid that in practice it will be slow. But someone with more sympy experience may have other insights.

    0 讨论(0)
提交回复
热议问题