Einführung in die Programmierung für Studierende der Physik¶

(Introduction to Programming for Physicists)¶

Vorlesung gehalten an der J.W.Goethe-Universität in Frankfurt am Main¶

(Sommersemester 2026)¶

von Dr.phil.nat. Dr.rer.pol. Matthias Hanauske¶

Frankfurt am Main 14.05.2026¶

Das Computeralgebrasystem: Python Jupyter + SymPy¶

In diesem Jupyter Notebook wird die Programmiersprache Python, in Verbindung mit der Python-Bibliothek SymPy benutzt, um symbolische Berechnungen durchzuführen (Matrix-Berechnungen, Differentiation, Integration, analytisches Lösen von Differentialgleichungen). In diesem Sinne agiert das Jupyter Notebook somit als ein Computeralgebrasystem - ein Computerprogramm, das der Bearbeitung algebraischer Ausdrücke dient. Es löst nicht nur mathematische Aufgaben mit festen Zahlenwerten, sondern auch solche mit symbolischen Ausdrücken (Gleichungen von Variablen, Funktionen, Polynomen und Matrizen) und ist dadurch im Erscheinungsbild den kommerziellen Software-Produkten Mathematica oder Maple sehr ähnlich.

Zunächst wird das Python Modul "sympy" eingebunden. Falls Sie das "sympy" Modul das erste Mal verwenden, müssen Sie es zunächst in Ihrer Python 3 Umgebung installieren (z.B. in einem Linux Terminal mit "pip3 install sympy").

In [1]:
from sympy import *
init_printing()

Berechnungen mit Matrizen¶

Wir definieren uns eine (2x3)-Matrix $\hat{\bf {A}}$ und eine (3x3)-Matrix $\hat{\bf {B}}$:

In [2]:
A = Matrix([[1, 2, 3, 4, 5],[21,22,23,24,25],[51,52,53,54,55]])
A
Out[2]:
$\displaystyle \left[\begin{matrix}1 & 2 & 3 & 4 & 5\\21 & 22 & 23 & 24 & 25\\51 & 52 & 53 & 54 & 55\end{matrix}\right]$
In [3]:
B = Matrix([[1, 2, 3],[4, 5, 6],[7, 8, 9],[10,11,12],[13,14,15]])
B
Out[3]:
$\displaystyle \left[\begin{matrix}1 & 2 & 3\\4 & 5 & 6\\7 & 8 & 9\\10 & 11 & 12\\13 & 14 & 15\end{matrix}\right]$

Das Produkt der Matrizen $\hat{\bf {A}}$ und $\hat{\bf {B}}$ berechnet sich zu

In [4]:
C = A*B
C
Out[4]:
$\displaystyle \left[\begin{matrix}135 & 150 & 165\\835 & 950 & 1065\\1885 & 2150 & 2415\end{matrix}\right]$

, die transponierte Matrix $(\hat{\bf {A}})^T$

In [5]:
transpose(A)
Out[5]:
$\displaystyle \left[\begin{matrix}1 & 21 & 51\\2 & 22 & 52\\3 & 23 & 53\\4 & 24 & 54\\5 & 25 & 55\end{matrix}\right]$

Man kann die einzelnen Elemente der Matrix auch mittels symbolischer Variablen benennen und dann allgemeine Ausdrücke erhalten.

In [6]:
a,b,c,d = symbols('a,b,c,d')
F = Matrix([[a, b],[c,d]])
F
Out[6]:
$\displaystyle \left[\begin{matrix}a & b\\c & d\end{matrix}\right]$

Z.B. ergibt sich für die Determinante der Matrix $\hat{\bf {F}}$

In [7]:
det(F)
Out[7]:
$\displaystyle a d - b c$

Berechnungen mit Vektoren können in gleicher Weise durchgeführt werden und die Operationen des Skalar- und Kreuzproduktes sind ebenfalls in SymPy schon vordefiniert. Nehmen wir z.B. die folgenden Vektoren $\vec{a}$ und $\vec{b}$ und berechnen das Skalar- und Kreuzprodukt:

$$ \begin{equation} \vec{a} =\left( \begin{array}{ccc} 4 \\ 7 \\ 9 \end{array} \right) \quad , \quad \vec{b} =\left( \begin{array}{ccc} -3 \\ 5 \\ -7 \end{array} \right) \qquad , \quad \hbox{Skalarprodukt:} \,\, s = \vec{a} \cdot \vec{b} \quad , \quad \hbox{Kreuzprodukt:} \,\, \vec{c} = \vec{a} \times \vec{b} \end{equation} $$

In [8]:
va = Matrix([4, 7, 9])
vb = Matrix([-3, 5, -7])

Das Skalarprodukt ($s = \vec{a} \cdot \vec{b} = \sum_{i=1}^3 a_i \, b_i $) ergibt sich mittels dem Befehl $\vec{a}$.dot( $\vec{b}$ ):

In [9]:
va.dot(vb)
Out[9]:
$\displaystyle -40$

Das Kreuzprodukt ( $\vec{c} = \vec{a} \times \vec{b} = \sum_{i,j,k=1}^3 \epsilon_{ijk} \, a_i \, b_j \, \vec{e}_k$ ) ergibt sich mittels dem Befehl $\vec{a}$.cross( $\vec{b}$ ), wobei $\epsilon_{ijk}$ der total antisymmetrischer Tensor (auch Epsilon-Tensor bzw. Levi-Civita-Symbol) ist.

In [10]:
va.cross(vb)
Out[10]:
$\displaystyle \left[\begin{matrix}-94\\1\\41\end{matrix}\right]$

Weitere Matrix Operationen finden Sie unter http://docs.sympy.org/latest/tutorial/matrices.html

Symbolische Berechnungen von Gleichungen¶

Das Modul sympy ist auch dafür gemacht, symbolische Berechnungen durchzuführen. Betrachten wir z.B. die folgende Gleichung $0=x^2 + p \, x + q$. Zunächst definieren wir die symbolischen Variablen der Gleichung und geben der Gleichung den Variablennamen "Gl".

In [11]:
x = symbols('x')
p,q = symbols('p,q')
Gl = Eq(x**2 + p*x + q, 0)
Gl
Out[11]:
$\displaystyle p x + q + x^{2} = 0$

Die Lösungen erhält man mittels des SymPy-Befehls "solve(...)"

In [12]:
Loes_Gl=solve(Gl,x)
Loes_Gl
Out[12]:
$\displaystyle \left[ - \frac{p}{2} - \frac{\sqrt{p^{2} - 4 q}}{2}, \ - \frac{p}{2} + \frac{\sqrt{p^{2} - 4 q}}{2}\right]$

Wir legen nun die symbolischen Variablen $p$ und $q$ auf die folgenden Werte fest (SymPy-Befehl "subs(...)", $0=x^2-3x+9$)

In [13]:
Gl_1=Gl.subs(p,-3).subs(q,9)
Gl_1
Out[13]:
$\displaystyle x^{2} - 3 x + 9 = 0$

und lösen die Gleichung erneut:

In [14]:
Loes_Gl_1=solve(Gl_1)
Loes_Gl_1
Out[14]:
$\displaystyle \left[ \frac{3}{2} - \frac{3 \sqrt{3} i}{2}, \ \frac{3}{2} + \frac{3 \sqrt{3} i}{2}\right]$

Die Gleichung besitzt keine reellwertige Lösung, wie man auch anhand der folgenden Abbildung erkennt.

In [15]:
plot(Gl_1.lhs, xlim=(-5,7), ylim=(-2,50));
No description has been provided for this image

Differentation und Integration¶

Die erste Ableitung einer Funktion $f(x)$:

hier speziell $f(x)=10 \cdot e^{-x/5} \cdot \hbox{sin}(3 x)$

In [16]:
f = 10 * exp(-x/5) * sin(3*x)
f
Out[16]:
$\displaystyle 10 e^{- \frac{x}{5}} \sin{\left(3 x \right)}$

Erste Ableitung: $f^\prime(x)$=

In [17]:
f.diff(x)
Out[17]:
$\displaystyle - 2 e^{- \frac{x}{5}} \sin{\left(3 x \right)} + 30 e^{- \frac{x}{5}} \cos{\left(3 x \right)}$

Zweite Ableitung: $f^{\prime \prime}(x)$=

In [18]:
f.diff(x,x)
Out[18]:
$\displaystyle - 4 \left(\frac{112 \sin{\left(3 x \right)}}{5} + 3 \cos{\left(3 x \right)}\right) e^{- \frac{x}{5}}$

Dritte Ableitung: $f^{\prime \prime \prime}(x)$=

In [19]:
f.diff(x,3)
Out[19]:
$\displaystyle \frac{4 \left(337 \sin{\left(3 x \right)} - 1665 \cos{\left(3 x \right)}\right) e^{- \frac{x}{5}}}{25}$

Das unbestimmte Integral einer Funktion $f(x)$: $\int f(x) \, dx$

In [20]:
f.integrate(x)
Out[20]:
$\displaystyle - \frac{25 e^{- \frac{x}{5}} \sin{\left(3 x \right)}}{113} - \frac{375 e^{- \frac{x}{5}} \cos{\left(3 x \right)}}{113}$

Das bestimmte Integral einer Funktion $f(x)$: $\int_a^b f(x) \, dx$

In [21]:
f.integrate((x, a, b))
Out[21]:
$\displaystyle - \frac{25 e^{- \frac{b}{5}} \sin{\left(3 b \right)}}{113} - \frac{375 e^{- \frac{b}{5}} \cos{\left(3 b \right)}}{113} + \frac{25 e^{- \frac{a}{5}} \sin{\left(3 a \right)}}{113} + \frac{375 e^{- \frac{a}{5}} \cos{\left(3 a \right)}}{113}$

Das bestimmte Integral einer Funktion $f(x)$: $\int_1^2 f(x) \, dx$

In [22]:
f.integrate((x, 1, 2))
Out[22]:
$\displaystyle \frac{375 \cos{\left(3 \right)}}{113 e^{\frac{1}{5}}} - \frac{375 \cos{\left(6 \right)}}{113 e^{\frac{2}{5}}} + \frac{25 \sin{\left(3 \right)}}{113 e^{\frac{1}{5}}} - \frac{25 \sin{\left(6 \right)}}{113 e^{\frac{2}{5}}}$
In [23]:
f.integrate((x, 1, 2)).evalf()
Out[23]:
$\displaystyle -4.75874851668195$

Analytisches Lösen von Differentialgleichungen¶

Zusätzlich ist es in sympy auch möglich Differentialgleichungen (DGLs) zu lösen (falls eine analytische Lösung existiert). Betrachten wir z.B. die folgende DGL zweiter Ordnung: $\frac{d^2y(x)}{dx^2}=-3y(x)$

In [24]:
y = Function('y')(x)
DGL = Eq(y.diff(x,x), -3*y)
DGL
Out[24]:
$\displaystyle \frac{d^{2}}{d x^{2}} y{\left(x \right)} = - 3 y{\left(x \right)}$

Die allgemeine Lösung lautet:

In [25]:
dsolve(DGL)
Out[25]:
$\displaystyle y{\left(x \right)} = C_{1} \sin{\left(\sqrt{3} x \right)} + C_{2} \cos{\left(\sqrt{3} x \right)}$

Die allgemeine Lösung hängt von den zwei Parametern $C_1$ und $C_2$ ab, die durch eine Wahl der Anfangs/Randbedingungen festgelegt werden können. Wir wählen z.B. $\quad y(0)=1 \quad $ und $ \quad \left. \frac{dy(x)}{dx}\right|_{x=0}=2\quad $.

In [26]:
Eq(y.subs(x,0),1)
Out[26]:
$\displaystyle y{\left(0 \right)} = 1$
In [27]:
Eq(y.diff(x).subs(x, 0),2)
Out[27]:
$\displaystyle \left. \frac{d}{d x} y{\left(x \right)} \right|_{\substack{ x=0 }} = 2$

Die spezielle Lösung lautet dann:

In [28]:
Loes = dsolve(DGL,ics={y.subs(x,0):1, y.diff(x).subs(x, 0): 2})
Loes
Out[28]:
$\displaystyle y{\left(x \right)} = \frac{2 \sqrt{3} \sin{\left(\sqrt{3} x \right)}}{3} + \cos{\left(\sqrt{3} x \right)}$

Die Lösung können wir wie folgt, direkt mittels SymPy visualisieren:

In [29]:
plot(Loes.rhs, (x, 0, 15));
No description has been provided for this image

Die Lösung können wir uns auch mittels "matplotlib" visualisieren, wobei man dazu den analytischen Ausdruck mittels "lambdify(...)" in eine numerische Funktion umwandelt.

In [30]:
import matplotlib.pyplot as plt 
import numpy as np

xvals = np.linspace(0, 15, 300)
func = lambdify(x, Loes.rhs)
plt.ylabel('y(x)')
plt.xlabel('x')
plt.plot(xvals,func(xvals));
No description has been provided for this image

Die oben definierte numerische Funktion mit dem Namen "func", gibt dabei die Funktionswerte der jeweiligen Gitterpunkte aus. In der folgenden Ausgabe z.B. für die ersten 10 Gitterpunkte.

In [31]:
func(xvals[:10])
Out[31]:
array([1.        , 1.09643549, 1.18459782, 1.26382176, 1.33350954,
       1.39313532, 1.44224919, 1.48048057, 1.50754098, 1.52322624])

Legen wir hingegen nur eine der Randbedingungen fest (z.B. $y(0)=1$), so können wir in einer Animation die Auswirkungen der anderen Randbedingung uns visualisieren. Hierzu führt man einen Animationsparameter ein, z.B. den Parameter $\alpha = \left. \frac{dy(x)}{dx}\right|_{x=0}$, und berechnet sich den analytischen Ausdruck der Lösung der DGL.

In [32]:
alpha = symbols("alpha")
Loes_alpha = dsolve(DGL,ics={y.subs(x,0):1, y.diff(x).subs(x, 0): alpha})
Loes_alpha
Out[32]:
$\displaystyle y{\left(x \right)} = \frac{\sqrt{3} \alpha \sin{\left(\sqrt{3} x \right)}}{3} + \cos{\left(\sqrt{3} x \right)}$

Nun kann man z.B. direkt die analytische Lösung mittels der spb-Python-Bibliothek (das SymPy Plotting Backends-Modul) als eine interaktive Animation darstellen (siehe SPB Modules Reference) und speichern. Wir animieren im Folgenden die Lösung im Bereich $\alpha \in [-2,6]$.

In [33]:
from spb import plot as spb_plot
from IPython.display import IFrame

anim = spb_plot( Loes_alpha.rhs, (x, 0, 15),
                params={alpha: (-2, 6)},
                animation={"fps": 20, "time": 5},
                title = (r"$\alpha$ = {:.2f}", alpha),
                xlabel = ('x'), ylabel= ('y(x)'),
                ylim = (-4, 4),
                imodule = "panel", show = False 
               )

#anim.show().save("Animation.html", embed=True)

IFrame(src="Animation.html", width="100%", height="600px")
Out[33]:

Alternativ kann man auch in Matplotlib die animierte Grafik erzeugen, speichern und im Jupyter Notebook darstellen (näheres siehe matplotlib.animation und Beispiele von Animationen).

In [34]:
func_alpha = lambdify((x,alpha), Loes_alpha.rhs)
In [35]:
from matplotlib.animation import FuncAnimation
from IPython.display import HTML

frames_N = 20

fig, ax = plt.subplots(figsize=(7, 5))

def animate(i):
    ax.cla()
    alpha_s = 8*i/frames_N - 2
    ax.set_title(r"$\alpha$ = {:.2f}".format(alpha_s))
    ax.set(xlabel='x', ylabel='y(x)', ylim=(-4, 4))
    ax.plot(xvals, func_alpha(xvals, alpha_s))
    return fig,

ani = FuncAnimation(fig, animate, frames=frames_N, interval=250)

ani.save("./Animation.gif", writer='pillow')
plt.close(fig)
HTML(ani.to_html5_video())
Out[35]:
Your browser does not support the video tag.

Anwendungsbeispiel: Taylorreihen Entwicklung¶

Wir möchten nun die Funktion $f(x)=\frac{1}{x}$ um die Stelle $x_0=1$ in eine Taylorreihe entwickeln. Hierzu definieren wir zunächst die Funktion:

In [36]:
f = 1/x

Das N-te Taylorpolynom $P_N(x)$ der Taylorreihe einer Funktion um eine Stelle $x_0$ ist wie folgt definiert:

$$ \begin{equation} P_N(x) = \sum_{k=0}^N \frac{f^{(k)}(x_0)}{k!}\cdot(x-x_0)^k \quad, \end{equation} $$

wobei $f^{(k)}(x_0)$ die k-te Ableitung der Funktion $f(x)$ an der Stelle $x=x_0$ darstellt: $f^{(k)}(x_0):=\left. \frac{d^k f(x)}{dx^k} \right|_{x=x_0}$

Das 4-te Taylorpolynom $P_4(x)$ der Taylorreihe der Funktion $f(x)=\frac{1}{x}$ um eine Stelle $x_0$ lautet z.B.:

In [37]:
x_0 = Symbol('x_0')
P_4 = sum(f.diff(x, k).subs(x,x_0)/factorial(k)*(x - x_0)**k  for k in range(5))
P_4
Out[37]:
$\displaystyle \frac{1}{x_{0}} - \frac{x - x_{0}}{x_{0}^{2}} + \frac{\left(x - x_{0}\right)^{2}}{x_{0}^{3}} - \frac{\left(x - x_{0}\right)^{3}}{x_{0}^{4}} + \frac{\left(x - x_{0}\right)^{4}}{x_{0}^{5}}$

Durch das Ausmultiplizieren der Klammern (Befehl "expand()") vereinfacht sich der obere Ausdruck:

In [38]:
P_4.expand()
Out[38]:
$\displaystyle \frac{x^{4}}{x_{0}^{5}} - \frac{5 x^{3}}{x_{0}^{4}} + \frac{10 x^{2}}{x_{0}^{3}} - \frac{10 x}{x_{0}^{2}} + \frac{5}{x_{0}}$

Wir stellen uns im Folgenden die ersten drei Taylorpolynome $P_1(x), P_2(x)$ und $P_3(x)$ der Funktion $f(x)=\frac{1}{x}$ mit $x_0=1$ grafisch dar und vergleichen diese mit der ursprünglichen Funktion $f(x)$.

In [39]:
P_1 = sum(f.diff(x, k).subs(x,1)/factorial(k)*(x - 1)**k  for k in range(2))
P_2 = sum(f.diff(x, k).subs(x,1)/factorial(k)*(x - 1)**k  for k in range(3)).expand()
P_3 = sum(f.diff(x, k).subs(x,1)/factorial(k)*(x - 1)**k  for k in range(4)).expand()
In [40]:
x_min = 0.4
x_max = 2.25
pf = plot(f, P_1, P_2, P_3, (x,x_min,x_max), line_color='black', legend = True, show=False)
pf[1].line_color='red'
pf[2].line_color='blue'
pf[3].line_color='green'
pf.show()
No description has been provided for this image

Wir stellen uns nun das 30-te Taylorpolynom $P_{30}(x)$ der Funktion $f(x)=\frac{1}{x}$ mit $x_0=1$ grafisch dar und vergleichen es wieder mit der ursprünglichen Funktion $f(x)$.

In [41]:
P_30 = sum(f.diff(x, k).subs(x,1)/factorial(k)*(x - 1)**k  for k in range(31))
P_30.expand()
Out[41]:
$\displaystyle x^{30} - 31 x^{29} + 465 x^{28} - 4495 x^{27} + 31465 x^{26} - 169911 x^{25} + 736281 x^{24} - 2629575 x^{23} + 7888725 x^{22} - 20160075 x^{21} + 44352165 x^{20} - 84672315 x^{19} + 141120525 x^{18} - 206253075 x^{17} + 265182525 x^{16} - 300540195 x^{15} + 300540195 x^{14} - 265182525 x^{13} + 206253075 x^{12} - 141120525 x^{11} + 84672315 x^{10} - 44352165 x^{9} + 20160075 x^{8} - 7888725 x^{7} + 2629575 x^{6} - 736281 x^{5} + 169911 x^{4} - 31465 x^{3} + 4495 x^{2} - 465 x + 31$
In [42]:
x_min = 0.05
x_max = 2.1
pf = plot(f, P_30, (x,x_min,x_max), line_color='black', show=False)
pf[1].line_color='red'
pf.show()
No description has been provided for this image

Anwendungsbeispiel: Herleitung der Differentiationregeln mittels der Methode der Lagrange Polynome¶

Die Ableitung (Differentiation) einer Funktion $f(x)$ stellt ein fundamentales Konzept der Mathematik dar, welches bei der Formulierung von physikalischen Bewegungsgleichungen essenziell ist. Die mathematische Definition der Ableitung einer Funktion, der sogenannte Differentialquotient, benutzt dabei eine Grenzwert-Formulierung ($h \to 0$), wobei in der numerischen Mathematik hingegen mehrere Differentiationregeln formuliert werden, die den wirklichen Wert der Ableitung approximieren. Die analytische Herleitung dieser Regeln benutzt die Methode der Lagrange Polynome (siehe Anwendungsbeispiel: Interpolation und Polynomapproximation). In diesem Anwendungsbeispiel wird die Herleitung dieser Differentiationregeln behandelt.

Die mathematische Definition der Ableitung einer Funktion $f(x)$ an der Stelle $x_0$ lautet

$$ \begin{equation} f^\prime(x_0) = \lim \limits_{h \to 0} \frac{f(x_0+h) - f(x_0)}{h} \quad. \end{equation} $$

Zur Approximation dieser Zahl werden wir nun die Funktion $f(x)$ in ein Lagrange Polynom entwickeln und diesen Ausdruck dann Differenzieren. Wir möchten jetzt die Funktion $f(x)$ mittels ($n+1$) vorgegebener Punkte ($(x_0,f(x_0)), (x_1,f(x_1)), ..., (x_n,f(x_n)) $) in ein Lagrange Polynom vom Grade $n$ entwickeln, wobei wir annehmen, dass $x_0 \in [a,b]$ und $x_n = x_0 + n \cdot h$. Der Wert von $h$ sollte hierbei hinreichend klein sein um sicherzustellen, dass $x_n \in [a,b]$ gilt.

Das n-te Lagrange Polynom $P_n(x)$ einer Funktion ist wie folgt definiert:

$$ \begin{equation} P_n(x) = \sum_{k=0}^n f(x_k) \cdot L_{n,k}(x) \quad, \end{equation} $$

mit

$$ \begin{equation} L_{n,k}(x) = \prod_{i=0 , \, i \neq k}^n \frac{(x-x_i)}{(x_k-x_i)} \quad. \end{equation} $$

Wir approximieren nun die Funktion $f(x)$ durch das n-te Lagrange Polynom $P_n(x)$

$$ \begin{equation} f(x) = P_n(x) + \underbrace{ \frac{f^{(n+1)}(\xi(x))}{(n+1)!} \prod_{i=0}^n (x-x_i) }_{\hbox{Fehler}} \,\, , \,\, \forall \,\, \xi(x) \in [x_0,x_n] \quad, \end{equation} $$ wobei $f^{(n+1)(x)}$ die $(n+1)$-te Ableitung der Funktion darstellt und $\xi(x)$ ein x-Wert im Bereich der Stützstellen ist.

Vernachlässigt man den Fehlerterm und leitet den Ausdruck ab, erhält man:

$$ \begin{equation} f^\prime(x) \approx \frac{d}{dx} P_n(x) = \frac{d}{dx} \left( \sum_{k=0}^n f(x_k) \cdot L_{n,k}(x) \right) = \sum_{k=0}^n f(x_k) \cdot \frac{d}{dx} L_{n,k}(x) = \sum_{k=0}^n f(x_k) \cdot L^\prime_{n,k}(x) \end{equation} $$

Die unterschiedlichen numerischen Differentiationregeln für $f^\prime(x)$ ergeben sich nun durch die Wahl wieviele Punkte ($n+1$) man bei der Berechnung berücksichtigt.

Wir definieren zunächst eine allgemeine SymPy-Funktion $f(x)$.

In [43]:
f = Function('f')(x)

Zweipunkteformel (n=1)¶

Wir betrachten nun den Fall $n=1$ und approximieren die Funktion mittels des ersten Lagrange Polynoms $P_1(x)$: $f(x) \approx P_1(x)$

In [44]:
x0,h = symbols('x_0,h')
points = [x0, x0+h]
f_points=[f.subs(x,points[0]), f.subs(x,points[1])]
In [45]:
points, f_points
Out[45]:
$\displaystyle \left( \left[ x_{0}, \ h + x_{0}\right], \ \left[ f{\left(x_{0} \right)}, \ f{\left(h + x_{0} \right)}\right]\right)$

In dem Unterpunkt Anwendungsbeispiel: Interpolation und Polynomapproximation der Vorlesung 5 hatten wir in dem Jupyter Notebook 'LagrangePolynome.ipynb' (View Notebook, Download Notebook) den analytischen Ausdruck des Lagrange Polynoms $P_n(x)$ mittels der folgenden Anweisungen berechnet (hier speziell $P_1(x)$):

In [46]:
P_1 = sum(f_points[k] * prod((x - points[i]) / (points[k] - points[i]) 
                             for i in range(len(points)) if i != k) 
          for k in range(len(points))
)
P_1.simplify()
Out[46]:
$\displaystyle \frac{\left(x - x_{0}\right) f{\left(h + x_{0} \right)} + \left(h - x + x_{0}\right) f{\left(x_{0} \right)}}{h}$

Leitet man diesen Ausdruck nach $x$ ab, so erhält man $f^\prime(x_0) \approx P_1^\prime(x_0)$ .

In [47]:
P_1.diff(x).simplify()
Out[47]:
$\displaystyle \frac{- f{\left(x_{0} \right)} + f{\left(h + x_{0} \right)}}{h}$

Der obere Ausdruck stellt die sogenannte Zweipunkte-Differentiationsregel dar.

Zweipunkteformel (n=1): $ f^\prime(x_0) \approx \frac{1}{h} \left[ f(x_0 + h) - f(x_0) \right]$

Dreipunkte-Endpunkt-Formel (n=2)¶

Wir betrachten nun den Fall $n=2$ und approximieren die Funktion mittels des zweiten Lagrange Polynoms $P_2(x)$: $f(x) \approx P_2(x)$, wobei wir hierbei die folgenden drei Punkte verwenden: ($(x_0,f(x_0)), (x_0 + h,f(x_0 + h)), (x_0 + 2h,f(x_0 + 2h)) $).

In [48]:
points = [x0, x0+h, x0+2*h]
f_points=[f.subs(x,points[0]), f.subs(x,points[1]), f.subs(x,points[2])]
In [49]:
points, f_points
Out[49]:
$\displaystyle \left( \left[ x_{0}, \ h + x_{0}, \ 2 h + x_{0}\right], \ \left[ f{\left(x_{0} \right)}, \ f{\left(h + x_{0} \right)}, \ f{\left(2 h + x_{0} \right)}\right]\right)$

Mit den oben angegebenen zwei Punkten erhält man das folgende Lagrange Polynom $P_2(x)$:

In [50]:
P_2 = sum(f_points[k] * prod((x - points[i]) / (points[k] - points[i]) 
                             for i in range(len(points)) if i != k) 
          for k in range(len(points))
)
P_2.simplify()
Out[50]:
$\displaystyle \frac{- \left(x - x_{0}\right) \left(h - x + x_{0}\right) f{\left(2 h + x_{0} \right)} + 2 \left(x - x_{0}\right) \left(2 h - x + x_{0}\right) f{\left(h + x_{0} \right)} + \left(h - x + x_{0}\right) \left(2 h - x + x_{0}\right) f{\left(x_{0} \right)}}{2 h^{2}}$

Leitet man diesen Ausdruck nach $x$ ab, so erhält man $f^\prime(x) \approx P_2^\prime(x)$

In [51]:
P_2.diff(x)
Out[51]:
$\displaystyle - \frac{\left(x - x_{0}\right) f{\left(h + x_{0} \right)}}{h^{2}} + \frac{\left(x - x_{0}\right) f{\left(2 h + x_{0} \right)}}{2 h^{2}} + \frac{\left(- 2 h + x - x_{0}\right) f{\left(x_{0} \right)}}{2 h^{2}} - \frac{\left(- 2 h + x - x_{0}\right) f{\left(h + x_{0} \right)}}{h^{2}} + \frac{\left(- h + x - x_{0}\right) f{\left(x_{0} \right)}}{2 h^{2}} + \frac{\left(- h + x - x_{0}\right) f{\left(2 h + x_{0} \right)}}{2 h^{2}}$

Betrachtet man nun speziell die Ableitung bei $f^\prime(x_0) \approx P_2^\prime(x_0)$, so erhält man die Dreipunkte-Endpunkt-Formel:

$$ \begin{equation} f^\prime(x_0) \approx \frac{1}{2h} \left[ - 3\,f(x_0) + 4 \, f(x_0 + h) - f(x_0 + 2 \, h) \right] \end{equation} $$

In [52]:
P_2.diff(x).subs(x,x_0).simplify()
Out[52]:
$\displaystyle \frac{- 3 f{\left(x_{0} \right)} + 4 f{\left(h + x_{0} \right)} - f{\left(2 h + x_{0} \right)}}{2 h}$

Dreipunkte-Mittelpunkt-Formel (n=2)¶

Wir betrachten nun abermals den Fall $n=2$ und approximieren die Funktion mittels des zweiten Lagrange Polynoms $P_2(x)$: $f(x) \approx P_2(x)$, wobei wir nun die folgenden drei Punkte verwenden: ($(x_0 -h,f(x_0 -h)), (x_0 ,f(x_0)), (x_0 + h,f(x_0 + h)) $).

In [53]:
points = [x0 -h,x0,x0+h]
f_points = [f.subs(x,points[0]), f.subs(x,points[1]), f.subs(x,points[2])]
In [54]:
points, f_points
Out[54]:
$\displaystyle \left( \left[ - h + x_{0}, \ x_{0}, \ h + x_{0}\right], \ \left[ f{\left(- h + x_{0} \right)}, \ f{\left(x_{0} \right)}, \ f{\left(h + x_{0} \right)}\right]\right)$
In [55]:
P_2_M = sum(f_points[k] * prod((x - points[i]) / (points[k] - points[i]) 
                             for i in range(len(points)) if i != k) 
          for k in range(len(points))
)
P_2_M.simplify()
Out[55]:
$\displaystyle \frac{- \left(x - x_{0}\right) \left(h - x + x_{0}\right) f{\left(- h + x_{0} \right)} + \left(x - x_{0}\right) \left(h + x - x_{0}\right) f{\left(h + x_{0} \right)} + 2 \left(h - x + x_{0}\right) \left(h + x - x_{0}\right) f{\left(x_{0} \right)}}{2 h^{2}}$

Leitet man diesen Ausdruck nach $x$ ab, so erhält man $f^\prime(x) \approx P_2^\prime(x)$

In [56]:
P_2_M.diff(x).expand()
Out[56]:
$\displaystyle - \frac{f{\left(- h + x_{0} \right)}}{2 h} + \frac{f{\left(h + x_{0} \right)}}{2 h} - \frac{2 x f{\left(x_{0} \right)}}{h^{2}} + \frac{x f{\left(- h + x_{0} \right)}}{h^{2}} + \frac{x f{\left(h + x_{0} \right)}}{h^{2}} + \frac{2 x_{0} f{\left(x_{0} \right)}}{h^{2}} - \frac{x_{0} f{\left(- h + x_{0} \right)}}{h^{2}} - \frac{x_{0} f{\left(h + x_{0} \right)}}{h^{2}}$

Betrachtet man nun speziell die Ableitung bei $f^\prime(x_0) \approx P_2^\prime(x_0)$, so erhält man die Dreipunkte-Mittelpunkt-Formel:

$$ \begin{equation} f^\prime(x_0) \approx \frac{1}{2h} \left[ f(x_0 + h) - f(x_0 - h) \right] \end{equation} $$

In [57]:
P_2_M.diff(x).subs(x,x_0).simplify()
Out[57]:
$\displaystyle \frac{- f{\left(- h + x_{0} \right)} + f{\left(h + x_{0} \right)}}{2 h}$

Fünfpunkte-Mittelpunkt-Formel (n=4)¶

Wir betrachten nun den Fall $n=4$ und approximieren die Funktion mittels des vierten Lagrange Polynoms $P_4(x)$: $f(x) \approx P_4(x)$, wobei wir die folgenden fünf Punkte verwenden: ($(x_0 - 2 \, h,f(x_0 - 2 \, h)), (x_0 - h,f(x_0 - h)), (x_0 ,f(x_0)), (x_0 + h,f(x_0 + h)), (x_0 + 2 \, h,f(x_0 + 2 \, h)) $).

In [58]:
points = [x0-2*h, x0-h, x0, x0+h, x0+2*h]
f_points = [f.subs(x,points[0]), f.subs(x,points[1]), f.subs(x,points[2]), f.subs(x,points[3]), f.subs(x,points[4])]
In [59]:
points, f_points
Out[59]:
$\displaystyle \left( \left[ - 2 h + x_{0}, \ - h + x_{0}, \ x_{0}, \ h + x_{0}, \ 2 h + x_{0}\right], \ \left[ f{\left(- 2 h + x_{0} \right)}, \ f{\left(- h + x_{0} \right)}, \ f{\left(x_{0} \right)}, \ f{\left(h + x_{0} \right)}, \ f{\left(2 h + x_{0} \right)}\right]\right)$
In [60]:
P_4_M = sum(f_points[k] * prod((x - points[i]) / (points[k] - points[i]) 
                             for i in range(len(points)) if i != k) 
          for k in range(len(points))
)
P_4_M.simplify()
Out[60]:
$\displaystyle \frac{\left(x - x_{0}\right) \left(h - x + x_{0}\right) \left(h + x - x_{0}\right) \left(2 h - x + x_{0}\right) f{\left(- 2 h + x_{0} \right)} - \left(x - x_{0}\right) \left(h - x + x_{0}\right) \left(h + x - x_{0}\right) \left(2 h + x - x_{0}\right) f{\left(2 h + x_{0} \right)} - 4 \left(x - x_{0}\right) \left(h - x + x_{0}\right) \left(2 h - x + x_{0}\right) \left(2 h + x - x_{0}\right) f{\left(- h + x_{0} \right)} + 4 \left(x - x_{0}\right) \left(h + x - x_{0}\right) \left(2 h - x + x_{0}\right) \left(2 h + x - x_{0}\right) f{\left(h + x_{0} \right)} + 6 \left(h - x + x_{0}\right) \left(h + x - x_{0}\right) \left(2 h - x + x_{0}\right) \left(2 h + x - x_{0}\right) f{\left(x_{0} \right)}}{24 h^{4}}$

Leitet man diesen Ausdruck nach $x$ ab, so erhält man $f^\prime(x) \approx P_4^\prime(x)$

In [61]:
P_4_M.diff(x).expand()
Out[61]:
$\displaystyle \frac{f{\left(- 2 h + x_{0} \right)}}{12 h} - \frac{2 f{\left(- h + x_{0} \right)}}{3 h} + \frac{2 f{\left(h + x_{0} \right)}}{3 h} - \frac{f{\left(2 h + x_{0} \right)}}{12 h} - \frac{5 x f{\left(x_{0} \right)}}{2 h^{2}} - \frac{x f{\left(- 2 h + x_{0} \right)}}{12 h^{2}} + \frac{4 x f{\left(- h + x_{0} \right)}}{3 h^{2}} + \frac{4 x f{\left(h + x_{0} \right)}}{3 h^{2}} - \frac{x f{\left(2 h + x_{0} \right)}}{12 h^{2}} + \frac{5 x_{0} f{\left(x_{0} \right)}}{2 h^{2}} + \frac{x_{0} f{\left(- 2 h + x_{0} \right)}}{12 h^{2}} - \frac{4 x_{0} f{\left(- h + x_{0} \right)}}{3 h^{2}} - \frac{4 x_{0} f{\left(h + x_{0} \right)}}{3 h^{2}} + \frac{x_{0} f{\left(2 h + x_{0} \right)}}{12 h^{2}} - \frac{x^{2} f{\left(- 2 h + x_{0} \right)}}{4 h^{3}} + \frac{x^{2} f{\left(- h + x_{0} \right)}}{2 h^{3}} - \frac{x^{2} f{\left(h + x_{0} \right)}}{2 h^{3}} + \frac{x^{2} f{\left(2 h + x_{0} \right)}}{4 h^{3}} + \frac{x x_{0} f{\left(- 2 h + x_{0} \right)}}{2 h^{3}} - \frac{x x_{0} f{\left(- h + x_{0} \right)}}{h^{3}} + \frac{x x_{0} f{\left(h + x_{0} \right)}}{h^{3}} - \frac{x x_{0} f{\left(2 h + x_{0} \right)}}{2 h^{3}} - \frac{x_{0}^{2} f{\left(- 2 h + x_{0} \right)}}{4 h^{3}} + \frac{x_{0}^{2} f{\left(- h + x_{0} \right)}}{2 h^{3}} - \frac{x_{0}^{2} f{\left(h + x_{0} \right)}}{2 h^{3}} + \frac{x_{0}^{2} f{\left(2 h + x_{0} \right)}}{4 h^{3}} + \frac{x^{3} f{\left(x_{0} \right)}}{h^{4}} + \frac{x^{3} f{\left(- 2 h + x_{0} \right)}}{6 h^{4}} - \frac{2 x^{3} f{\left(- h + x_{0} \right)}}{3 h^{4}} - \frac{2 x^{3} f{\left(h + x_{0} \right)}}{3 h^{4}} + \frac{x^{3} f{\left(2 h + x_{0} \right)}}{6 h^{4}} - \frac{3 x^{2} x_{0} f{\left(x_{0} \right)}}{h^{4}} - \frac{x^{2} x_{0} f{\left(- 2 h + x_{0} \right)}}{2 h^{4}} + \frac{2 x^{2} x_{0} f{\left(- h + x_{0} \right)}}{h^{4}} + \frac{2 x^{2} x_{0} f{\left(h + x_{0} \right)}}{h^{4}} - \frac{x^{2} x_{0} f{\left(2 h + x_{0} \right)}}{2 h^{4}} + \frac{3 x x_{0}^{2} f{\left(x_{0} \right)}}{h^{4}} + \frac{x x_{0}^{2} f{\left(- 2 h + x_{0} \right)}}{2 h^{4}} - \frac{2 x x_{0}^{2} f{\left(- h + x_{0} \right)}}{h^{4}} - \frac{2 x x_{0}^{2} f{\left(h + x_{0} \right)}}{h^{4}} + \frac{x x_{0}^{2} f{\left(2 h + x_{0} \right)}}{2 h^{4}} - \frac{x_{0}^{3} f{\left(x_{0} \right)}}{h^{4}} - \frac{x_{0}^{3} f{\left(- 2 h + x_{0} \right)}}{6 h^{4}} + \frac{2 x_{0}^{3} f{\left(- h + x_{0} \right)}}{3 h^{4}} + \frac{2 x_{0}^{3} f{\left(h + x_{0} \right)}}{3 h^{4}} - \frac{x_{0}^{3} f{\left(2 h + x_{0} \right)}}{6 h^{4}}$

Betrachtet man nun speziell die Ableitung bei $f^\prime(x_0) \approx P_4^\prime(x_0)$, so erhält man die Fünfpunkte-Mittelpunkt-Formel:

$$ \begin{equation} f^\prime(x_0) \approx \frac{1}{12 \, h} \left[ f(x_0 - 2 \, h) - 8 \, f(x_0 - h) + 8 \, f(x_0 + h) - f(x_0 + 2 \, h) \right] \end{equation} $$

In [62]:
P_4_M.diff(x).subs(x,x_0).simplify()
Out[62]:
$\displaystyle \frac{f{\left(- 2 h + x_{0} \right)} - 8 f{\left(- h + x_{0} \right)} + 8 f{\left(h + x_{0} \right)} - f{\left(2 h + x_{0} \right)}}{12 h}$