耦合四微分方程组-Python

耦合四微分方程组-Python,python,python-3.x,scipy,ode,odeint,Python,Python 3.x,Scipy,Ode,Odeint,我得到了图中4个微分方程的耦合系统。我有4个函数(xG;yG;gamma;beta)及其导数。它们都是同一个自变量t的函数 我正试图用odeint解决这个问题。问题是,为了做到这一点,我想我需要用一种方式来表达系统,即每个二阶导数不依赖于其他二阶导数。这涉及到大量的数学知识,肯定会让我在某个地方出错(我试过!) 你知道我怎么能: 按原样解这个微分方程组 或者让python帮我分离二阶导数 我正在附加我的测试代码 谢谢 import numpy import math from numpy imp

我得到了图中4个微分方程的耦合系统。我有4个函数(xG;yG;gamma;beta)及其导数。它们都是同一个自变量t的函数

我正试图用odeint解决这个问题。问题是,为了做到这一点,我想我需要用一种方式来表达系统,即每个二阶导数不依赖于其他二阶导数。这涉及到大量的数学知识,肯定会让我在某个地方出错(我试过!)

你知道我怎么能:

  • 按原样解这个微分方程组
  • 或者让python帮我分离二阶导数
  • 我正在附加我的测试代码

    谢谢

    import numpy
    import math
    from numpy import loadtxt
    from pylab import figure,  savefig
    import matplotlib.pyplot as plt
    # Use ODEINT to solve the differential equations defined by the vector field
    from scipy.integrate import odeint
    
    
    
    def vectorfield(w, t, p):
        """
        Defines the differential equations for the coupled system.
    
        Arguments:
            w :  vector of the state variables:
                      w = [Xg, Xg1 Yg, Yg1, Gamma, Gamma1, Beta, Beta1]
            t :  time
            p :  vector of the parameters:
                      p = [m, rAG, Ig,lcavo]
        """
    #Xg is position ; Xg1 is the first derivative ; Xg2 is the second derivative (the same for the other functions)
            Xg, Xg1,  Yg, Yg1, Gamma, Gamma1, Beta, Beta1 = w
            Xg2=-(Ig*Gamma2*math.cos(Beta))/(rAG*m*(-math.cos(Gamma)*math.sin(Beta)+math.sin(Gamma)*math.cos(Beta)))
            Yg2=-(Ig*Gamma2*math.sin(Beta))/(rAG*m*(-math.cos(Gamma)*math.sin(Beta)+math.sin(Gamma)*math.cos(Beta)))-9.81
            Gamma2=((Beta2*lcavo*math.sin(Beta))+(Beta1**2*lcavo*math.cos(Beta))+(Xg2)-(Gamma1**2*rAG*math.cos(Gamma)))/(rAG*math.sin(Gamma))
            Beta2=((Yg2)+(Gamma2*rAG*math.cos(Gamma))-(Gamma1**2*rAG*math.sin(Gamma))+(Beta1**2*lcavo*math.sin(Beta)))/(lcavo*math.cos(Beta))
            m, rAG, Ig,lcavo, Xg2,  Yg2, Gamma2, Beta2 = p
        
        
        # Create f = (Xg', Xg1' Yg', Yg1', Gamma', Gamma1', Beta', Beta1'):
        f = [Xg1,
             Xg2,
             Yg1, 
             Yg2, 
             Gamma1, 
             Gamma2, 
             Beta1, 
             Beta2]
             
        return f
    
        
    
    
    # Parameter values
    m=2.722*10**4
    rAG=2.622
    Ig=3.582*10**5
    lcavo=4
    # Initial conditions
    Xg = 0.0
    Xg1 = 0
    Yg = 0.0
    Yg1 = 0.0
    Gamma=-2.52
    Gamma1=0
    Beta=4.7
    Beta1=0
    
    # ODE solver parameters
    abserr = 1.0e-8
    relerr = 1.0e-6
    stoptime = 5.0
    numpoints = 250
    
    #create the time values
    t = [stoptime * float(i) / (numpoints - 1) for i in range(numpoints)]
    Deltat=t[1]
    # Pack up the parameters and initial conditions:
    p = [m, rAG, Ig,lcavo, Xg2,  Yg2, Gamma2, Beta2]
    w0 = [Xg, Xg1,  Yg, Yg1, Gamma, Gamma1, Beta, Beta1]
    
    # Call the ODE solver.
    wsol = odeint(vectorfield, w0, t, args=(p,),
                  atol=abserr, rtol=relerr)
    


    您需要将所有二阶导数重写为一阶导数,并一起求解8个ODE:

    然后你们需要所有导数的初始条件,但看起来你们已经有了。 仅供参考,您的代码未运行(
    第71行:名称错误:未定义名称“Xg2”),请检查它

    此外,有关更多信息,请参阅

    编辑#1: 在第一步,您需要解耦方程组。虽然您可以手动解决,但我不推荐,所以让我们使用
    sympy
    模块:

    import sympy as sm
    from sympy import symbols
    
    # define symbols. I assume all the variables are real-valued, this helps the solver. If not, I believe the result will be the same, but just calculated slower
    Ig, gamma, gamma1, gamma2, r, m, beta, beta1, beta2, xg2, yg2, g, l = symbols('I_g, gamma, gamma1, gamma2, r, m, beta, beta1, beta2, xg2, yg2, g, l', real = True)
    
    # define left hand sides as expressions
    # 2nd deriv of gamma
    g2 = (beta2 * l * sm.sin(beta) + beta1**2 *l *sm.cos(beta) + xg2 - gamma1**2 *r * sm.cos(gamma))/(r*sm.sin(gamma))
    # 2nd deriv of beta
    b2 = (yg2 + gamma2 * r * sm.cos(gamma) - gamma1**2 *r * sm.sin(gamma) + beta1**2 *l *sm.sin(beta))/(l*sm.cos(beta))
    # 2nd deriv of xg
    x2 = -Ig*gamma2*sm.cos(beta)/(r*m*(-sm.sin(beta)*sm.cos(gamma) + sm.sin(gamma)*sm.cos(beta)))
    # 2nd deriv of yg
    y2 = -Ig*gamma2*sm.sin(beta)/(r*m*(-sm.sin(beta)*sm.cos(gamma) + sm.sin(gamma)*sm.cos(beta))) - g
    
    # now let's solve the system of four equations to decouple second order derivs
    # gamma2 - g2 means "gamma2 - g2 = 0" to the solver. The g2 contains gamma2 by definition
    # one could define these equations the other way, but I prefer this form
    result = sm.solve([gamma2-g2,beta2-b2,xg2-x2,yg2-y2],
                      # this line tells the solver what variables we want to solve to
                      [gamma2,beta2,xg2,yg2] )
    # print the result
    # note that it is long and ugly, but you can copy-paste it as python code
    for res in result:
        print(res, result[res])
    
    现在我们将所有二阶导数解耦。例如,
    beta2
    的表达式为

    所以它(以及所有其他二阶导数)的形式是

    请注意,不依赖于
    xg
    yg

    让我们介绍两个新变量,
    b
    k

    然后 变成

    要解决的ODE的完整系统是


    现在所有的常微分方程都依赖于四个变量,它们不是任何事物的导数。此外,由于
    xg
    yg
    是退化的,因此也只有6个方程,而不是8个方程。但是,可以用与
    gamma
    beta
    相同的方式重写这两个方程,以获得完整的8个方程组,并将其集成在一起。

    您需要将所有二阶导数重写为一阶导数,并一起求解8个方程:

    然后你们需要所有导数的初始条件,但看起来你们已经有了。 仅供参考,您的代码未运行(
    第71行:名称错误:未定义名称“Xg2”),请检查它

    此外,有关更多信息,请参阅

    编辑#1: 在第一步,您需要解耦方程组。虽然您可以手动解决,但我不推荐,所以让我们使用
    sympy
    模块:

    import sympy as sm
    from sympy import symbols
    
    # define symbols. I assume all the variables are real-valued, this helps the solver. If not, I believe the result will be the same, but just calculated slower
    Ig, gamma, gamma1, gamma2, r, m, beta, beta1, beta2, xg2, yg2, g, l = symbols('I_g, gamma, gamma1, gamma2, r, m, beta, beta1, beta2, xg2, yg2, g, l', real = True)
    
    # define left hand sides as expressions
    # 2nd deriv of gamma
    g2 = (beta2 * l * sm.sin(beta) + beta1**2 *l *sm.cos(beta) + xg2 - gamma1**2 *r * sm.cos(gamma))/(r*sm.sin(gamma))
    # 2nd deriv of beta
    b2 = (yg2 + gamma2 * r * sm.cos(gamma) - gamma1**2 *r * sm.sin(gamma) + beta1**2 *l *sm.sin(beta))/(l*sm.cos(beta))
    # 2nd deriv of xg
    x2 = -Ig*gamma2*sm.cos(beta)/(r*m*(-sm.sin(beta)*sm.cos(gamma) + sm.sin(gamma)*sm.cos(beta)))
    # 2nd deriv of yg
    y2 = -Ig*gamma2*sm.sin(beta)/(r*m*(-sm.sin(beta)*sm.cos(gamma) + sm.sin(gamma)*sm.cos(beta))) - g
    
    # now let's solve the system of four equations to decouple second order derivs
    # gamma2 - g2 means "gamma2 - g2 = 0" to the solver. The g2 contains gamma2 by definition
    # one could define these equations the other way, but I prefer this form
    result = sm.solve([gamma2-g2,beta2-b2,xg2-x2,yg2-y2],
                      # this line tells the solver what variables we want to solve to
                      [gamma2,beta2,xg2,yg2] )
    # print the result
    # note that it is long and ugly, but you can copy-paste it as python code
    for res in result:
        print(res, result[res])
    
    现在我们将所有二阶导数解耦。例如,
    beta2
    的表达式为

    所以它(以及所有其他二阶导数)的形式是

    请注意,不依赖于
    xg
    yg

    让我们介绍两个新变量,
    b
    k

    然后 变成

    要解决的ODE的完整系统是


    现在所有的常微分方程都依赖于四个变量,它们不是任何事物的导数。此外,由于
    xg
    yg
    是退化的,因此也只有6个方程,而不是8个方程。但是,可以用与
    gamma
    beta
    相同的方式重写这两个方程,以获得完整的8个方程组,并将其集成在一起。

    感谢您的回复。然而,你写的第一个方程是psi的导数,等于g的导数的函数。我如何用python编写g的导数?在这种方法中不需要“导数函数”。你需要8个“简单”的功能。谢谢,你能给我提供更多的细节吗?在odeint中,我需要定义一个由定义良好的简单函数组成的函数。我如何定义一个函数是另一个的导数的函数?@Francesco,SciPy cookbook页面给出了一个将两个二阶方程组转换为四个一阶方程组的例子。看看这是否有用。谢谢沃伦。这正是我代码的基础所在。不幸的是,这个例子基于一个系统,在这个系统中,你可以很容易地得到二阶导数,作为常数的函数,或者时间的函数,或者它们的一阶导数。而在我的例子中,我不能很容易地得到一个二阶导数,作为常数、函数或一阶导数的函数:我总是在方程的两边都有一个二阶导数。在这种情况下如何处理?谢谢你的回复。然而,你写的第一个方程是psi的导数,等于g的导数的函数。我如何用python编写g的导数?在这种方法中不需要“导数函数”。你需要8个“简单”的功能。谢谢,你能给我提供更多的细节吗?在odeint中,我需要定义一个由定义良好的简单函数组成的函数。我如何定义一个函数是另一个的导数的函数?@Francesco,SciPy cookbook页面给出了一个将两个二阶方程组转换为四个一阶方程组的例子。看看这是否有用。谢谢沃伦。这正是我代码的基础所在。不幸的是,这个例子基于一个系统,在这个系统中,你可以很容易地得到二阶导数,作为常数的函数,或者时间的函数,或者它们的一阶导数。而在我的例子中,我不能很容易地得到一个二阶导数,作为常数、函数或一阶导数的函数:我总是在方程的两边都有一个二阶导数。在这种情况下如何处理?