简体   繁体   中英

Solve system of recursive differential equation in Python

So I am trying to solve the following system of differential equations in Python.

System of differential equations

As you can see, for each n in {0,1,2,3,...} the system depends on the solution to the previous system.

I have tried solving the system for n=0 and found a solution R(0|t) that I can insert in R(1|t) and Python solves the system without problems. I have defined the solution R(0|t) as r0(t) and implemented the solution for n=1 as follows:

def model(z,t):
    dxdt = -3.273*z[0] + 3.2*z[1] + r0(t)
    dydt = 3.041*z[0] - 3.041*z[1]
    dzdt = [dxdt, dydt]
    return dzdt

z0 = [0,0]

t = np.linspace(0,90, 90)

z1 = odeint(model, z0, t)

However I would like to generalize this solution by calling the solution to the system for n-1 when solving for n. As the differential equations only has entry different from zero in the upper right corner of the matrix we only need the solution of z 1 from the previous solution. I have tried

def model0(z,t):
    dxdt = -3.273*z[0] + 3.2*z[1] 
    dydt = 3.041*z[0] - 3.041*z[1]
    dzdt = [dxdt, dydt]
    return dzdt

z0 = [1,1]

t = np.linspace(0,90)

def model1(z,t):
    dxdt = -3.273*z[0] + 3.2*z[1] + 0.071*odeint(model0, z0, t)[t,1]
    dydt = 3.041*z[0] - 3.041*z[1]
    dzdt = [dxdt, dydt]
    return dzdt


z1 = [0,0]


z = odeint(model1, z1, t)

Without any luck. Has anyone any experience in solving these recursive systems of odes in Python?

Thanks in advance.

Updated with code for 6x6 matrices and 6 function:


A = np.array([[h1h1, h1h2, h1h3, h1a1, h1a2, h1a3], 
              [h2h1, h2h2, h2h3, h2a1, h2a2, h2a3],
              [h3h1, h2h3, h3h3, h3a1, h3a2, h3a3],
              [a1h1, a1h2, a1h3, a1a1, a1a2, a1a3],
              [a2h1, a2h2, a2h3, a2a1, a2a2, a2a3],
              [a3h1, a3h2, a3h3, a3a1, a3a2, a3a3]
              ])


B = np.array([[0, 0, 0, 0, 0,    0], 
              [0, 0, 0, 0, 0,    0],
              [0, 0, 0, 0, h3a0, 0],
              [0, 0, 0, 0, 0,    0],
              [0, 0, 0, 0, 0,    0],
              [0, 0, 0, 0, 0,    0],
              ])


def model0n(u,t):
    Ra = u.reshape([-1,6])
    n = len(Ra) - 1
    dRa = np.zeros(Ra.shape)
    dRa[0] = A @ Ra[0]
    for i in range(1,n+1): 
        dRa[i] = A @ Ra[i] + B @ Ra[i-1]
    return dRa.flatten()

u0 = [1,1,1,1,1,1,0,0,0,0,0,0]
t = np.linspace(0,90,90+1)

u = odeint(model0n,u0,t)

The above results in the following plot for u[:,0]: Plot for u[:,0] which is supposed to be probabilities

For n=0 it provides results doing the matrix product 'manualy':


def modeln0manually(z,t):
    d1dt = h1h1*z[0] + h1h2 * z[1] + h1h3*z[2] + h1a1*z[3] + h1a2*z[4] + h1a3*z[5]
    d2dt = h2h1*z[0] + h2h2 * z[1] + h2h3*z[2] + h2a1*z[3] + h2a2*z[4] + h2a3*z[5]
    d3dt = h3h1*z[0] + h3h2 * z[1] + h3h3*z[2] + h3a1*z[3] + h3a2*z[4] + h3a3*z[5]
    d4dt = a1h1*z[0] + a1h2 * z[1] + a1h3*z[2] + a1a1*z[3] + a1a2*z[4] + a1a3*z[5]
    d5dt = a2h1*z[0] + a2h2 * z[1] + a2h3*z[2] + a2a1*z[3] + a2a2*z[4] + a2a3*z[5]
    d6dt = a3h1*z[0] + a3h2 * z[1] + a3h3*z[2] + a3a1*z[3] + a3a2*z[4] + a3a3*z[5]
    drdt = [d1dt, d2dt, d3dt, d4dt, d5dt, d6dt]    
    return drdt    


u0 = [1,1,1,1,1,1]
t = np.linspace(0,90)
z = odeint(modeln0manually, u0, t)

Resulting in the plot for u[:,0]: Plot of u[:,0] as it is supposed to be

Your system is coupled, even if in triangular way. So the most compact way is to solve it as a coupled system

A = np.array([[-3.273, 3.2], [3.041, -3.041]])
B = np.array([[0, 0.071], [0, 0]])

def model0n(u,t):
    Ra = u.reshape([-1,2])
    n = len(Ra) - 1
    dRa = np.zeros(Ra.shape)
    dRa[0] = A @ Ra[0]
    for i in range(1,n+1): 
        dRa[i] = A @ Ra[i] + B @ Ra[i-1]
    return dRa.flatten()

u0 = [1,1,0,0]
t = np.linspace(0,90,90+1)
u = odeint(model0n,u0,t)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM