Skip to content
Advertisement

SymPy returns wrong solution of a nonlinear ODE?

I am trying to solve the ODE of the frictional free fall:

from sympy import *
t = symbols ('t')
v = Function ('v')
dgl = Eq (diff (v(t), t) + v(t)**2, 1)

enter image description here

erg = dsolve (dgl)

enter image description here

I think the solution might be wrong. I believe it should be the reciprocal of the returned expression. Therefore, if I try to find the value of the constant for an initial condition of rest (v(0) = 0), I get no real solutions:

C1 = symbols ('C1')
solve (erg.rhs.subs (t, 0), C1)

enter image description here

As a consequence, if I ask SymPy to solve the ODE with the initial condition, it throws errors:

dsolve (dgl, ics = {v(0): 0})

enter image description here

Advertisement

Answer

The sympy answer is formally correct, with v=u'/u one gets u''=u so that

u(t) = A*exp(t)+B*exp(-t)

v(t) = (A*exp(t)-B*exp(-t))/(A*exp(t)+B*exp(-t))

Depending on how the constants are combined into one parameter, and what sign combination one prefers, one has

A = D*exp(-C), B = D*exp(C) ==> v(t) = tanh(t-C)

A = D*exp(-C), B =-D*exp(C) ==> v(t) = ctgh(t-C)

One can switch from one version to the other using complex factors, as the solver did

ctgh(t-C+i*pi/2) = (i*exp(t-C)+(-i)*exp(-t+C))/(i*exp(t-C)-(-i)*exp(-t+C))

                 = tanh(t-C)

This is what the solver for the initial condition proposed.


What you can do is check what other solution paths are available

classify_ode(dgl)
#('separable',
# '1st_exact',
# '1st_rational_riccati',
# '1st_power_series',
# 'lie_group',
# 'separable_Integral',
# '1st_exact_Integral')

dsolve (dgl, ics = {v(0): 0}, hint='1st_rational_riccati')
# Eq(v(t), (1 - exp(2*t))/(-exp(2*t) - 1))
dsolve (dgl, ics = {v(0): 0}, hint='1st_rational_riccati').simplify()
# Eq(v(t), tanh(t))

which gives a sensible solution.

User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement