有没有办法在python中加速odeint

92vpleto  于 2021-08-25  发布在  Java
关注(0)|答案(0)|浏览(224)

目前,我正在考虑如何为我正在运行的模拟加速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.index.values,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的评论修改代码。谢谢你的提示。我不知道这一点,也学到了一些新的东西,没想到字典会对计算时间产生如此大的影响。但是现在它快多了。

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题