我想在python中解决大量的双线性ODE系统。衍生物是这样的:
def x_(x, t, growth, connections):
return x * growth + np.dot(connections, x) * x
我对非常准确的结果不感兴趣,但对定性行为感兴趣,即组件是否归零。
因为我必须解决如此大量的高分辨率系统,所以我想使用尽可能大的步长。
由于步长大,可能会发生ODE在零下的一个组件中。这是不可能的,因为(由于特定ODE的结构)每个组件都以零为界。因此 - 为了防止出现错误的结果 - 我想在每个组件低于手动时将其手动设置为零。
此外,在我想要解决的系统中,解决方案可能会爆发。我想通过设置上限来防止这种情况,即如果某个值超出限制,则将其设置回绑定值。
我希望我可以让我的目标可以理解,为您提供以下我想要做的伪代码:
for t in range(0, tEnd, dt):
$ compute x(t) using x(t-dt) $
x(t) = np.minimum(np.maximum(x(t), 0), upperBound)
我使用Runge-Kutta算法实现了这一点。一切正常。只是表现不好。因此,我更喜欢使用预先实现的方法,如scipy.integrate.odeint。
因此,我不知道如何设置这样的界限。我试过的一个选项是以这种方式操纵ODE,一旦x高于界限,导数变为0,而一旦x低于0,则导出(正)。另外,为了防止在一个时间步内跳得太高,我也是限制了衍生物:
def x_(x, t, growth, connections, bound):
return (x > 0) * np.minimum((x < bound) * \
( x * growth + np.dot(connections, x) * x ), bound) + (x < 0)
虽然这个解决方案(特别是对于零界限)非常难看,但只要它有效就足够了。不幸的是,它不起作用。使用odeint
x = scipy.integrate.odeint(x_, x0, timesteps, param)
我经常遇到这两个错误中的一个:
Repeated convergence failures (perhaps bad Jacobian or tolerances).
Excess work done on this call (perhaps wrong Dfun type).
他们可能是由于我操纵的ODE的不连续性。互联网上有很多关于这些错误消息的主题,但它们对我没有帮助。例如。增加允许的步数既不能阻止这个问题,也不是一个很好的解决方案,因为我需要使用大步长。此外,通过雅各布也没有帮助。
查看解决方案后,可以看到发生错误时会发生两种奇怪的行为:
我很感激有关如何解决问题的所有提示 - 无论是否有帮助
我提前谢谢你了!
我被问到一个最小的例子:
import numpy as np
import random as rd
rd.seed()
import scipy.integrate
def simulate(simParam, dim = 20, connectivity = .8, conRange = 1, threshold = 1E-3,
constGrowing=None):
"""
Creates the random system matrix and starts a simulation
"""
x0 = np.zeros(dim, dtype='float') + 1
connections = np.zeros(shape=(dim, dim), dtype='float')
growth = np.zeros(dim, dtype='float') +
(constGrowing if not constGrowing == None else 0)
for i in range(dim):
for j in range(dim):
if i != j:
connections[i][j] = rd.uniform(-conRange, conRange)
tend, step = simParam
return RK4NumPy(x_, (growth, connections), x0, 0, tend, step)
def x_(x, t, growth, connections, bound):
"""
Derivative of the ODE
"""
return (x > 0) * np.minimum((x < bound) *
(x * growth + np.dot(connections, x) * x), bound) + (x < 0)
def RK4NumPy(x_, param, x0, t0, tend, step, maxV = 1.0E2, silent=True):
"""
solving method
"""
param = param + (maxV,)
timesteps = np.arange(t0 + step, tend, step)
return scipy.integrate.odeint(x_, x0, timesteps, param)
simulate((300, 0.5))
要查看解决方案,必须绘制x。使用给定的参数,我经常得到上面提到的错误
Excess work done on this call (perhaps wrong Dfun type).
Run with full_output = 1 to get quantitative information.