Gewone differentiaalvergelijkingen: Scheiden van variabelen
Exacte oplossingen van een GDV met Python
Python heeft het pakket Symbolic Python
aan boord om exacte berekeningen te kunnen doen. Een paar voorbeelden geven een idee hoe het werkt.
Algemene oplossing We bekijken de differentiaalvergelijking \[\frac{\dd y}{\dd t} = t\,y\] Via de methode van scheiden van variabelen vind je als algemene oplossing \[y(t)=c\cdot e^{\frac{1}{2}t^2}\] voor zekere constante \(c\). Python kan deze oplossing ook bepalen via de dsolve
functie uit het sympy
pakket:
>>> import sympy as sy # laad het sympy pakket en gebruik een acroniem
>>> t = sy.symbols('t') # maak een symbool t
>>> y = sy.Function('y') # maak een symbolische functie y
>>> GDV = sy.Eq(sy.Derivative(y(t),t), t*y(t)) # de differentiaalvergelijking
>>> yopl = sy.dsolve(GDV, y(t)); yopl # bepaal de algemene oplossing
y(t) = C1*exp(t**2/2))
Beginwaardeprobleem Je kunt aan het dsolve
commando ook de beginwaarde als vergelijking opgeven. We nemen als voorbeeld het beginwaardeprobleem \[\frac{\dd y}{\dd t} = y^2,\quad y(0)=1\] Via de methode van scheiden van variabelen vind je als algemene oplossing \[y(t)=\frac{1}{c-t}\] voor zekere constante \(c\). Uit \(y(0)=1\) volgt dat \(c=1\). Python kan deze oplossing ook bepalen via de dsolve
functie:
>>> import sympy as sy # laad het sympy pakket en gebruik een acroniem
>>> sy.init_printing() # voor mooiere uitvoer
>>> t = sy.symbols('t') # maak een symbool t
>>> y = sy.Function('y') # maak een symbolische functie y
>>> GDV = sy.Eq(sy.Derivative(y(t),t), y(t)**2) # de differentiaalvergelijking
>>> yopl = sy.dsolve(GDV, y(t), ics = {y(0):1}) # los beginwaardeprobleem op
>>> yopl
-1
y(t) = -----
t - 1
>>> genopl = sy.dsolve(GDV, y(t)) # bepaal algemene oplossing
>>> constant = sy.solve([genopl.rhs.subs(t,0)-1]) # bepaal de constante
>>> yopl = genopl.subs(constant); yopl
-1
y(t) = -----
t - 1
GDV van orde 2 We nemen als voorbeeld het beginwaardeprobleem \[\frac{\dd^2y}{\dd t^2} -3\frac{\dd y}{\dd t}+ 2y = 0, \quad y(0)=-1,\quad \frac{\dd y}{\dd t}(0) = -3\] In een volgende sectie zullen we leren hoe dit probleem op te lossen, maar de oplossing is \[y(t)=e^t - 2e^{2t}\] In onderstaand programma hebben we een alternatief gebruikt om afgeleiden in de differentiaalvergelijking en de beginwaarden te specificeren
>>> import sympy as sy # laad het sympy pakket en gebruik een acroniem
>>> sy.init_printing() # voor mooiere uitvoer
>>> t = sy.symbols('t') # maak een symbool t
>>> y = sy.Function('y') # maak een symbolische functie y
>>> GDV = sy.Eq(y(t).diff(t,2)-3*y(t).diff(t) + 2*y(t), 0); GDV
2
d d
2*y(t) - 3*--(y(t)) + ---(y(t)) = 0
dt 2
dt
>>> yopl = sy.dsolve(GDV, y(t), ics = {y(0):1, sy.diff(y(t), t).subs(t,0):-3}); yopl
2*t t
y(t) = - 2*e + e
>>> genopl = sy.dsolve(GDV, y(t)); genopl # de algemene oplossing
/ t\ t
y(t) = \C1 + C2*e /*e
>>> # stel vergelijkingen voor beginwaarden op en los ze op.
>>> constants = sy.solve([genopl.rhs.subs(t,0)+1, genopl.rhs.diff(t).subs(t,0)+3])
>>> yopl = genopl.subs(constants); yopl # substitutie van gevonden waarden
/ t\ t
y(t) = \1 - 2*e /*e
>>> sy.expand(yopl) # werk haakjes uit en vereenvoudig
2*t t
y(t) = - 2*e + e
We zetten dit voorbeeld door om te laten zien hoe je met de symbolische oplossing verder kunt rekenen in numerieke zin. Zo maar waarden voor \(t\) invullen werkt niet handig omdat de yopl
een symbolische uitdrukking. Gebruik lambdify
om een functie van de symbolische uitdrukking voor \(y(t)\) te maken.
>>> yfun = sy.lambdify(t, yopl.rhs, "math")
>>> list(map(yfun, [0,1,2]))
[-1.0, -12.059830369402254, -101.80724396735783]