有没有办法在python中加速odeint

问题描述

目前我正在考虑如何为我正在运行的模拟加速 odeint。实际上它只是一个带有摩擦项和不连续力的原始二阶颂歌。我用来描述动力学的模型是在一个单独的函数中定义的。尝试解决 ode 会导致错误或极高的计算时间(以天为单位)。

这是我的大部分硬编码代码

import numpy as np
import pandas as pd
from scipy.integrate import odeint
import matplotlib.pyplot as plt

def create_ref(tspan):
    if tspan>2 and tspan<8:
        output = np.sin(tspan)
    elif tspan>=20:
        output = np.sin(tspan*10)
    else:
        output = 0.5
    return output

def model(state,t):
    def Fs(x):
        pT = 0
        pB = 150
        p0 = 200
        pA = 50
        kein = 0.25
        kaus = 0.25
        if x<0:
            pA = pT
            Fsres = -kaus*x*pA-kein*x*(p0-pB)
        else:
            pB = pT
            Fsres = -kaus*x*pB-kein*x*(p0-pA)
        return Fsres

    x,dx = state
    refNow = np.interp(t,xref.index.values,xref.values.squeeze())
    refprev = np.interp(t-dt,xref.values.squeeze())
    drefNow = (refNow-refprev)/dt
    x_meas = x
    dx_meas =  dx
    errNow = refNow-x_meas
    errprev = refprev-(x_meas-dx_meas*dt)
    intrefNow = dt*(errNow-errprev)
    kp = 10
    kd = 0.1
    ki = 100
    sigma = kP*(refNow-x_meas)+kd*(drefNow-dx_meas)+ki*intrefNow
    tr0 = 5
    FricRed = (1.5-0.5*np.tanh(0.1*(t-tr0)))
    kpu = 300
    fr = 0.1
    m = 0.01
    d = 0.01
    k = 10
    u = float(kpu*np.sqrt(np.abs(sigma))*np.sign(sigma))
    ddx = 1/m*(Fs(x)+FricRed*fr*np.sign(dx)-d*dx-k*x + u )
    return [dx,ddx]
    
dt = 1e-3
tspan = np.arange(start=0,stop=50,step=dt)
steplim = tspan[-1]*0.1

reffunc = np.vectorize(create_ref)
xrefvals = reffunc(tspan)
xref = pd.DataFrame(data=xrefvals,index=tspan,columns=['xref'])

x0 = [-0.5,0]
simresult = odeint(model,x0,tspan)

plt.figure(num=1)
plt.plot(tspan,simresult[:,0],label='ispos')
plt.plot(tspan,xref['xref'].values,label='despos')
plt.legend()
plt.show()

我根据 Pranav Hosangadi 的评论更改了代码。感谢您的提示。我不知道这一点并学到了一些新东西,没想到字典对计算时间有如此大的影响。但现在速度要快得多。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)