scipy python中的向量求解

xdnvmnnf  于 12个月前  发布在  Python
关注(0)|答案(1)|浏览(94)

我想知道是否有可能解决一个向量的常微分方程的scipy。
以下是scipy页面上的一个例子:

import numpy as np

from scipy.integrate import solve_ivp

def lotkavolterra(t, z, a, b, c, d):
    x, y = z
    return [a*x - b*x*y, -c*y + d*x*y]

sol = solve_ivp(lotkavolterra, [0, 15], [10, 5], args=(1.5, 1, 3, 1),

                dense_output=True)

t = np.linspace(0, 15, 300)

z = sol.sol(t)

如果我在一个solve_ivp调用中有一个初始条件和参数的向量,我能解出这个方程吗?

ICs = np.random.rand(10, 2)
args = np.random.rand(10, 4)
t3psigkw

t3psigkw1#

是的,这是可能的,不推荐。
1.因为你改变了参数,所以常微分方程的解将受到最严格的常微分方程的限制(因为它们都是同时被计算的)。这可能会导致代码变慢。
1.这不是预期的功能,而是对代码的滥用。它需要小心如何创建和使用变量
尽管如此,我还是会告诉你如何做到这一点。在我们开始之前,我们必须了解求解器的要求。

  1. y0必须是1D的,所以你需要在函数中展平变量并重塑它们。
  2. args将分割变量,因此它们必须放在一个numpy数组中,该数组放置在一个元组中,该元组作为一个参数传递。
    1.您必须对所有模拟使用相同的t_span和函数。
    要创建兼容的y0args,您可以执行以下操作:
rng = np.random.default_rng(0)

N = 2
y0 = rng.random((N,2)).flat
args = (rng.random((N,4)),)

在这里,N是您一次执行的模拟数量。每个模拟有2个变量和4个参数。请注意y0是如何展开的,args是如何放置在元组中的。
对于这个函数,你现在需要接受一个单独的参数,这个参数将在里面被分割。而且,如前所述,您需要重新塑造解决方案向量。对于我上面使用的形式,我们需要将其展平,以便每个模拟解决方案都保持在一起,因此在展平之前需要转置。在提取变量时也需要撤销转置,这就是为什么在定义xy时要进行整形和转置。

def lotkavolterra(t, z, args):
    a, b, c, d = args[0].T  # transposed because the columns are the parameters
    x, y = z.reshape(-1, 2).T
    return np.array([a*x - b*x*y, -c*y + d*x*y]).T.flat

总的来说,我们有:

import numpy as np
from scipy.integrate import solve_ivp
import matplotlib.pyplot as plt

plt.close("all")

def lotkavolterra(t, z, args):
    a, b, c, d = args[0].T
    x, y = z.reshape(-1, 2).T
    return np.array([a*x - b*x*y, -c*y + d*x*y]).T.flat

rng = np.random.default_rng(0)

N = 2
t0 = 0
tn = 20
y0 = rng.random((N,2)).flat
args = (rng.random((N,4)),)
sol = solve_ivp(lotkavolterra, [0, 15], y0, args=args, dense_output=True)

t = np.linspace(0, 15, 300)
z = sol.sol(t)

fig, ax = plt.subplots()
for i in range(N):
    x, y = z[2*i:2*i+2]
    ax.plot(t, x, label=f"x{i}")
    ax.plot(t, y, label=f"y{i}")
    
ax.legend()
ax.set_title("Lotka-Volterra System")
fig.show()

结果:

同样,这不是正确的方法,可能不应该使用。但最终,你是程序员,可以决定你想做什么。

相关问题