scipy 非齐次常微分方程的不精确solve_ivp解(Python)

gzszwxb4  于 2022-11-10  发布在  Python
关注(0)|答案(2)|浏览(245)

今天,我第一次开始使用solve_ivp。我的问题如下:
我有来自加速度计和速度计的数据(代码中的变量a和v),它们对应于流体中物体的运动数据。运动的控制方程为:

总结一下,我想做的是:
1.使用Force wrt time获取数组(简单)
1.因为a是v的导数,我们现在有一个变量F,它取决于时间,我想解这个微分方程:

并将恢复的速度与原始测量的速度进行比较。

我的尝试:

我使用solve_ivp来完成这个任务,这是我的代码(我假设m=1,所以在计算中省略了它):

def obtainF(self, v, a):
    return(a + self.coef * v**2)

def eqMot(self, t, y, F, coef):
    return(F[t] - coef*y*y)

def diffSolver(self, F): 

    t = linspace(0,len(F)-1,len(F))

    y0 = [0.0]
    p = [F, self.coef]

    sol = solve_ivp(self.eqMot, [0, len(F)-1], y0, args = p, t_eval=t)

    return(sol.y[0])

(the代码几乎是自我解释的)。代码在DavidJ回答后更新(问题仍然存在)
原始的加速度和速度几乎都是正弦曲线,具有很小的低频偏移,它们甚至被预先低通滤波,以避免与求解器发生任何冲突。

问题:

原始速度和计算速度不匹配。不仅如此,当增加“系数”时,不匹配似乎减少了。
获得的“系数”= 0.2的图:

并且,这里,对于“coef”= 1.5:

我不明白问题的起因。任何帮助都是欢迎的!

tquggr8v

tquggr8v1#

所提出的系统是一阶的,我相信你正在试图解决以下问题。

def obtainF(self, v, a):
    return(a + self.coef * v * v)

def eqMot(self, t, v, F, coef):
    # indexing `F` with a float `t` can lead to problems. 
    # Use interpolation of `F` to ensure this evaluates correctly.
    return(F(t) - coef * v * v)

def diffSolver(self, F): 

    t = linspace(0.0,len(F)-1.0,len(F))

    y0 = [0.0]
    # According to the API doc `args` should be a tuple
    p = (F, self.coef)

    sol = solve_ivp(self.eqMot, [0.0, len(F)-1.0], y0, args = p, t_eval=t)

    v_new = sol.y

    return v_new

看起来你也混合了面向对象和函数式编程风格。考虑哪一种更有意义,并一致地实现。

camsedfj

camsedfj2#

所以我设法解决了这个问题。正如@LutzLehmann在评论中所建议的,因为我从一个传感器获取速度测量值,从另一个传感器获取加速度数据,尽管乍一看后者似乎是前者的导数,但在逐个样本的分析中,结果表明速度和加速度的de(手动计算)导数之间存在显著差异。
我用一个互补滤波器混合两个数据源,然后对得到的速度矢量进行处理,然后对它进行微分,从而解决了这个问题。
谢谢你的帮助!

相关问题