Sympy二阶颂歌

时间:2016-01-12 04:33:32

标签: python sympy ode

我有一个简单的二阶ODE的同类解决方案,当我尝试使用Sympy求解初始值时,返回相同的解决方案。它应该替代y(0)和y'(0)并产生没有常数的解,但不能。这是设置方程的代码(它是弹簧平衡方程,k =弹簧常数,m =质量)。我在其他地方使用的一些冗余符号,抱歉。

%matplotlib inline
from sympy import *
m,k, x,t,s,T, omega,A,B = symbols('m k x t s T omega A B',float=True)
a = symbols('a', positive=True)
f,y,g,H,delta,S=symbols('f y g H delta S',cls=Function)
Eq1 = Eq(m*diff(y(t),t,2)+k*y(t))
Eq1

结果是(正确): $ y {\ left(t \ right)} = C_ {1} e ^ { - t \ sqrt { - \ frac {k} {m}}} + C_ {2} e ^ {t \ sqrt { - \ frac {K} {M}}} $

y(t)= C1e ^( - t√( - k / m))+ C2e ^(t√( - km)),其中y_n = c1.cos(√( - k / m)t )+ c2.sin(√(-k /米)T)。

当通过分析求解该方程,并使用具有omega = sqrt(-k / m)的正弦和余弦转换为解,然后c1 = y(0)和c2 = y'(0)/ omega。因此,虽然解决方案部分涉及复数,但是,当然,dsolve只返回原始的齐次方程。我在y(0)和y'(0)处评估ODE的代码是:

Eq1_soln_IVP =dsolve(Eq1,y(t),x0=0, ics={y(0): a, y(t).diff(t).subs(t, 0): a})

我很欣赏dsolve可能无法通过分析方式处理这个IVP,但如果基于其他容量,我会感到惊讶。关于如何解决这个问题以及因此可以解决其他分析二阶问题的任何帮助都将非常感激。问题的核心是:

ics={y(0): a, y(t).diff(t).subs(t, 0): a}

所以我试过的解决方案是Dietrich确认的:

 #Create IVP for y(0)
 expr = Eq(Eq1_soln_IVP.rhs.subs(sqrt(-k/m),I*omega),y(0))
 #Create IVP for y'(0)
 expr2 = Eq(diff(y(t),t).subs(t,0),expr.lhs.diff(t))
 #Maps all free variables and solves for each where t = 0.
 solve([expr.subs(t,0),expr2.subs(t,0)])

虽然它是“一个”解决方案,但这似乎是一种非常复杂的方法来找到y(t)= y(0)cos(omega * t - phi)...它回答了关于这个求解器的某些局限性的隐含问题以及如何解决ics arg的直接问题。谢谢。

1 个答案:

答案 0 :(得分:4)

ics中的参数dsolve()无效(Issue 4720),因此您必须手动进行替换。你可以尝试:

from IPython.display import display
import sympy as sy

sy.init_printing()  # LaTeX-like pretty printing for IPython

t = sy.Symbol("t", real=True)
m, k = sy.symbols('m k', real=True)  # gives C_1 Exp() + C_2 Exp() solution
# m, k = sy.symbols('m k', positive=True)  # gives C_1 sin() + C_2 cos() sol.
a0, b0 = sy.symbols('a0, b0', real=True)
y = sy.Function('y')

Eq1 = sy.Eq(m*sy.diff(y(t), t, 2) + k*y(t))
print("ODE:")
display(Eq1)

print("Generic solution:")
y_sl0 = sy.dsolve(Eq1, y(t)).rhs  # take only right hand side
display(sy.Eq(y(t), y_sl0))

# Initial conditions:
cnd0 = sy.Eq(y_sl0.subs(t, 0), a0)  # y(0) = a0
cnd1 = sy.Eq(y_sl0.diff(t).subs(t, 0), b0)  # y'(0) = b0

#  Solve for C1, C2:
C1, C2 = sy.symbols("C1, C2")  # generic constants
C1C2_sl = sy.solve([cnd0, cnd1], (C1, C2))

# Substitute back into solution:
y_sl1 = sy.simplify(y_sl0.subs(C1C2_sl))
print("Solution with initial conditions:")
display(sy.Eq(y(t), y_sl1))