【问题标题】:Solved ODE by Sympy doesn't satisfy the given initial conditionSympy 求解的 ODE 不满足给定的初始条件
【发布时间】:2021-08-24 02:35:38
【问题描述】:

我正在尝试使用 Sympy 中的 dsolve 函数解决以下简单的 ODE

v = sp.Function('v', real=True)
t, g, m, c = sp.symbols('t g m c', positive=True, real=True)
eq = sp.Eq(v(t).diff(t), g - c/m*v(t)**2)
sol = sp.dsolve(eq, v(t), ics={v(0):0})

结果并不像预期的那么简单,但奇怪的是,如果您检查解决方案以确保满足给定的初始条件,它不会返回正确的结果 (v(0)=0),因为传入dsolve by ics 参数。

sol.subs(t,0)

【问题讨论】:

  • 你使用什么版本的 sympy,print(sympy.__version__)?您的版本中的文档是否保证 ics 参数将在解决方案中使用?请参阅stackoverflow.com/questions/41192748/… 和相关人员。
  • @Lutz Lehmann,感谢您的关注。我正在使用最新版本。 ics 参数现在功能齐全。
  • 看起来像一个 sympy 错误。它无法用新的常数替换复合常数。此外,它过早地简化为 1/tanh,这会阻止在时间为零的合理表达式。如果滥用复数对数,给定的解决方案仍然可能是正确的,但这不是必需的。

标签: sympy ode


【解决方案1】:

替换u=c/m*vc/m*g=a^2 得到等式u'=a^2-u^2,它是可分离的并导致

log|u+a|-log|u-a| = 2*a*t+c

这应该转化为

(u+a)/(u-a) = C*exp(2*a*t)

u = a*(C*exp(2*a*t)+1)/(C*exp(2*a*t)-1)

那么初始条件导致C=-1u(t)=a*tanh(a*t)

由于 sympy 解决方案中的常数显然没有从指数中删除,并且绝对值向负号的分辨率也显然没有遵循,sympy 最终得到c=log(-1)/2 的变化,这在实数上的等式的上下文。 -1 也位于复数的通常分支上,这使得这更加不确定。在实际解决方案中发现log((-1)**sqrt(m)) 不是一个定义明确的表达式。

【讨论】:

    【解决方案2】:

    问题是dsolve找到了通用解决方案:

    In [41]: sol
    Out[41]: 
                          √g⋅√m               
    v(t) = ───────────────────────────────────
                  ⎛             ⎛ C₁⋅√c⋅√g⋅m⎞⎞
                  ⎜          log⎝ℯ          ⎠⎟
                  ⎜√c⋅√g⋅t - ────────────────⎟
                  ⎜                 2        ⎟
           √c⋅tanh⎜──────────────────────────⎟
                  ⎝            √m            ⎠
    

    在尝试解决C1 之前,最好应用一些恒定的简化:

    In [42]: [logterm] = sol.atoms(log)
    
    In [43]: C1 = Symbol('C1')
    
    In [44]: sol2 = sol.subs(logterm, C1)
    
    In [45]: sol2
    Out[45]: 
                    √g⋅√m         
    v(t) = ───────────────────────
                  ⎛  C₁          ⎞
                  ⎜- ── + √c⋅√g⋅t⎟
                  ⎜  2           ⎟
           √c⋅tanh⎜──────────────⎟
                  ⎝      √m      ⎠
    
    In [46]: [c] = solve(sol2.rhs.subs(t, 0), C1)
    
    In [47]: c
    Out[47]: ⅈ⋅π⋅√m
    
    In [48]: sol2.subs(C1, c)
    Out[48]: 
                     √g⋅√m          
    v(t) = ─────────────────────────
                  ⎛          ⅈ⋅π⋅√m⎞
                  ⎜√c⋅√g⋅t - ──────⎟
                  ⎜            2   ⎟
           √c⋅tanh⎜────────────────⎟
                  ⎝       √m       ⎠
    
    In [49]: sol2.subs(C1, c).simplify()
    Out[49]: 
                     ⎛√c⋅√g⋅t⎞
           √g⋅√m⋅tanh⎜───────⎟
                     ⎝   √m  ⎠
    v(t) = ───────────────────
                    √c 
    

    也许实际上最好在求解过程的早期阶段求解常数。可能在纸笔上,一旦积分发生并且方程仍处于隐式形式时,求解常数是有意义的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-01-02
      • 2013-05-07
      • 1970-01-01
      • 2015-07-28
      • 2022-11-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多