Commit d73d2566 authored by Jochen Schulz's avatar Jochen Schulz
Browse files

state before content update

parent b253e8e5
......@@ -25,4 +25,4 @@ launch_buttons:
execute:
execute_notebooks : cache # Whether to execute notebooks at build time. Must be one of ("auto", "force", "cache", "off")
cache : "_build/.jupyter_cache/" # A path to the jupyter cache that will be used to store execution artifacs. Defaults to `_build/.jupyter_cache/`
exclude_patterns : ["README.md", "*.ipynb", "visualisierung_lecture.md", "parallelisierung_lecture.md", "parallelisierung_exercise.md"] # A list of patterns to *skip* in execution (e.g. a notebook that takes a really long time)
exclude_patterns : ["README.md", "*.ipynb", "parallelisierung_lecture.md", "parallelisierung_exercise.md"] # A list of patterns to *skip* in execution (e.g. a notebook that takes a really long time)
......@@ -2,7 +2,9 @@
numbered: false
- part: Prelude
chapters:
- file: src/Linux_und_Terminals/lecture
- file: src/Linux_und_Terminals/linux_lecture
sections:
- file: src/Linux_und_Terminals/linux_exercise
- part: Basis Python
chapters:
- file: src/Allgemeines/allgemeines_lecture
......@@ -44,8 +46,12 @@
- file: src/Strings/strings_exercise
- part: Wissenschaftliches Rechnen
chapters:
- file: src/Numpy/lecture
- file: src/Numpy/numpy_lecture
sections:
- file: src/Numpy/numpy_exercise
- file: src/Lineare_Algebra/lineare_algebra_lecture
sections:
- file: src/Lineare_Algebra/lineare_algebra_exercise
- file: src/Visualisierung_mit_Holoviews/visualisierung_lecture
- file: src/Visualisierung_mit_Holoviews/holoviews_demo_lecture
- file: src/Visualisierung_mit_Holoviews/grafiken_lecture
......@@ -60,18 +66,33 @@
- file: src/Symbolisches_Rechnen/symbolisches_rechnen_lecture
sections:
- file: src/Symbolisches_Rechnen/symbolisches_rechnen_exercise
- file: src/Gleichungen/lecture
- file: src/Differentation_Integration/lecture
- file: src/Gleichungen/gleichungen_lecture
sections:
- file: src/Gleichungen/gleichungen_exercise
- file: src/Differentation/differentation_lecture
sections:
- file: src/Differentation/differentation_exercise
- file: src/Integration/integration_lecture
sections:
- file: src/Integration/integration_exercise
- file: src/Numerische_Differentation_Integration/lecture
- file: src/Interpolation/interpolation_lecture
sections:
- file: src/Interpolation/interpolation_exercise
- file: src/Nichtlineare_Gleichungen/lecture
- file: src/Wahrscheinlichkeitsrechnung/lecture
- file: src/Nichtlineare_Gleichungen/nichtlineare_gleichungen_lecture
sections:
- file: src/Nichtlineare_Gleichungen/nichtlineare_gleichungen_exercise
- file: src/Wahrscheinlichkeitsrechnung/wahrscheinlichkeitsrechnung_lecture
sections:
- file: src/Wahrscheinlichkeitsrechnung/wahrscheinlichkeitsrechnung_exercise
- part: Fortgeschritten
chapters:
- file: src/Objektorientierung/lecture
- file: src/Exceptions/lecture
- file: src/Objektorientierung/objektorientierung_lecture
sections:
- file: src/Objektorientierung/objektorientierung_exercise
- file: src/Exceptions/exceptions_lecture
sections:
- file: src/Exceptions/exceptions_exercise
- file: src/Performance/performance_lecture
sections:
- file: src/Performance/performance_exercise
......
......@@ -10,31 +10,9 @@ kernelspec:
name: python3
---
# Differentation und Integration
# Differentation: Übungen
## Aufgabe 1
Definieren Sie die Funktion
$$
f(s):= \int_0^\infty x^{s-1} e^{-x} dx, \quad s >0
$$
mit `integrate`. Das Ergebnis wird stückweise sein. Nutzen Sie dann Annahmen an `s`, so dass eine eindeutige Lösung ausgegeben wird.
```{code-cell}
import sympy as sy
x,s= sy.symbols('x,s')
sy.integrate(x**(s-1)*sy.exp(-x),(x,0,sy.oo))
```
```{code-cell}
s= sy.symbols('s', positive=True)
g = sy.integrate(x**(s-1)*sy.exp(-x),(x,0,sy.oo))
g
```
## Aufgabe 2
## Aufgabe 1
Schreiben Sie eine Funktion, die zu einem gegebenen Startwert $x_0$ und einer gegebenen symbolischen Funktion $f$ die Iterationen von
......@@ -53,6 +31,13 @@ b) Implementieren Sie die Funktion noch einmal. Diesmal wenden Sie auf die symbo
Vergleichen Sie das Verhalten der beiden Varianten.
```{code-cell}
:tags: ['hide-cell']
import sympy as sy
sy.init_printing()
```
```{code-cell}
:tags: ['hide-cell']
def newton(f, x0, x=sy.symbols('x')):
df = f.diff(x)
while True:
......@@ -61,6 +46,7 @@ def newton(f, x0, x=sy.symbols('x')):
```
```{code-cell}
:tags: ['hide-cell']
x = sy.symbols('x')
f = x**3 + 2*x + 3
......@@ -71,14 +57,17 @@ print(rootf)
```
```{code-cell}
:tags: ['hide-cell']
print(rootf.evalf())
```
```{code-cell}
:tags: ['hide-cell']
print(f.subs(x, rootf).evalf())
```
```{code-cell}
:tags: ['hide-cell']
# Das hier braucht u.U. recht lange! Ggf. auch mal mit weniger Iterationen ausprobieren.
# Aus Effizienzgründen geben wir hier den symbolischen Wert nicht aus.
g = sy.exp(-x) - x
......@@ -89,16 +78,19 @@ rootg
```
```{code-cell}
:tags: ['hide-cell']
rootg_num = rootg.evalf()
print(rootg_num)
```
```{code-cell}
:tags: ['hide-cell']
# Aus Effizienzgründen setzen wir hier nur den numerischen Wert in die Funktion ein.
print(g.subs(x, rootg_num).evalf())
```
```{code-cell}
:tags: ['hide-cell']
# lambdify-Version
def newton_numpy(f, x0, x=sy.symbols('x')):
......@@ -112,6 +104,7 @@ def newton_numpy(f, x0, x=sy.symbols('x')):
```
```{code-cell}
:tags: ['hide-cell']
for idx, rootf_numpy in enumerate(newton_numpy(f, 0)):
if idx ==4:
break
......@@ -119,6 +112,7 @@ print(rootf_numpy)
```
```{code-cell}
:tags: ['hide-cell']
for idx, rootg_numpy in enumerate(newton_numpy(g, 0)):
if idx ==4:
break
......@@ -126,6 +120,7 @@ print(rootg_numpy)
```
```{code-cell}
:tags: ['hide-cell']
# Hier sind auch problemlos wesentlich mehr Iterationen möglich
for idx, rootf_numpy in enumerate(newton_numpy(f, 0)):
if idx == 100:
......@@ -136,65 +131,13 @@ for idx, rootf_numpy in enumerate(newton_numpy(f, 0)):
# und der numerischen Welt zu bauen.
```
## Aufgabe 3\*
Gegeben seien die Listen $L1 = [x, x^3, x^5, x^7, x^9,x^{11}x^{13},x^{15},x^{17},]$ und $L2 = [x, x^2, x^6, x^{24}, x^{120}]$.
* Erstellen Sie diese beiden Listen mit Hilfe von list-comprehensions.
* Bilden Sie $L3 = L1+L2$.
* Bilden Sie von jedem Eintrag von $L3$ die Ableitung und die Stammfunktion.
* Bestimmen Sie von jedem Element von $L3$ den Funktionswert an der Stelle $x=3$ und entfernen Sie den größten Eintrag aus der resultierenden Liste.
* Speichern Sie die Funktionen aus obiger Liste jeweils in ein Dictionary ab, welches den Funktionsausdruck, die Ableitung und Stammfunktion enthält.
* Geben Sie mit Hilfe dieses Dictionaries die Funktionen mit erklärendem Text aus.
```{code-cell}
x = sy.symbols('x')
L1 = [x**(2*n-1) for n in range(1,10)]
L2 = [x**(sy.factorial(n)) for n in range(1,6)]
L3 = L1 + L2
```
```{code-cell}
[f.diff() for f in L3]
```
```{code-cell}
[f.integrate(x) for f in L3]
```
```{code-cell}
L = [f.subs(x,3) for f in L3]; L
```
```{code-cell}
m = max(L)
L.remove(m); L
```
```{code-cell}
L4=[{"Funktion":f,"diff":f.diff(x), "int":f.integrate(x)} for f in L3]; L4
```
```{code-cell}
for D in L4:
print(' Für die Funktion {} ist die Ableitung {} und die Stammfunktion {}'.format(D['Funktion'],D['diff'],D['int']) )
```
```{code-cell}
for D in L4:
print(' Für die Funktion {} ist die Ableitung {} und die Stammfunktion {}'.format(D['Funktion'],D['diff'],D['int']) )
```
```{code-cell}
for D in L4:
print ('Für die Funktion f(x)='+str(D['Funktion']) +' ist die Ableitung f`(x)='+str(D['diff'])+' und die Stammfunktion F(x)='+str(D['int']))
```
## Aufgabe 4\*
## Aufgabe 2\*
Schreiben Sie eine Funktion inklusive Hilfetext, die für eine gegebene mathematische Funktion (als Sympy-Ausdruck mit Symbol `x` als Variablen) die lokalen Extrema samt Funktionswerten und Maxima/Minima-Bestimmung ausrechnet und eine Liste von Dictionaries zurückgibt, die jeweils den Extremwert und seine Eigenschaft enthalten. Den Fall, dass die 2. Ableitung verschwindet (also *möglicherweise* ein Sattelpunkt), können Sie dabei ignorieren. Achten Sie darauf, dass wir Variablen und Lösungen in den reellen Zahlen haben.
```{code-cell}
:tags: ['hide-cell']
import sympy as sy
def extrema(f):
......@@ -233,12 +176,14 @@ def extrema(f):
```
```{code-cell}
:tags: ['hide-cell']
x = sy.symbols('x', real=True) # this is to ensure we are only in real numbers
f = (2*x**2 - 3*x)/(x - 4)
extrema(f)
```
```{code-cell}
:tags: ['hide-cell']
f = (x**3 + x)
extrema(f)
```
---
jupytext:
text_representation:
extension: .md
format_name: myst
kernelspec:
display_name: Python 3
language: python
name: python3
---
# Differentiation
## Definition
Eine Funktion $f \colon D \to \mathbb{R}$ heißt *differenzierbar* an der Stelle $x \in D$, wenn
$$
\lim_{z \to x} \frac{f(z) - f(x)}{z - x}
$$
existiert. In diesem Fall ist $f$ in $x$ auch stetig.
Der Grenzwert wird *Ableitung* oder *Differentialquotient* von $f$ an $x$ genannt und mit $f'(x) = f^{(1)}(x)$ bezeichnet. $f$ heißt differenzierbar auf $D$, wenn $f$ an allen $x \in D$ differenzierbar ist, und *stetig differenzierbar*, wenn die Ableitung selbst wieder stetig ist.
## Differentiation in SymPy
```{code-cell}
import sympy as sy
sy.init_printing()
```
In SymPy wird ein Ausdruck `expr` mit
```{code-block}
sympy.diff(expr)
```
oder
```{code-block}
expr.diff()
```
abgeleitet.
```{code-cell}
x = sy.symbols('x')
sy.diff(sy.sin(x))
```
```{code-cell}
(x**x).diff()
```
Wenn `expr` mehrere Symbole enthält, dann muss das Symbol, nach dem abgeleitet werden soll, als zusätzliches Argument an `diff()` übergeben werden.
```{code-cell}
c = sy.symbols('c')
sy.diff(c * x**2, x)
```
Ohne `x` tritt eine Exception auf.
```{code-cell}
:tags: ["raises-exception"]
sy.diff(c * x**2)
```
## Höhere Ableitungen und Ableitungen von Funktionen mehrerer Veränderlicher
Höhere Ableitungen werden induktiv definiert: Für $n > 1$ ist $f^{(n)}(x)$ die Ableitung von $f^{(n-1)}$ bei $x \in D$.
Sei $f \colon D_1 \times D_2 \to \mathbb{R}$ eine Funktion in zwei Variablen. Dann ist die partielle Ableitung von $f$ bezüglich $x$ definiert als
$$
f_x(x, y) := \lim_{z \to x} \frac{f(z, y) - f(x, y)}{z - x},
$$
wenn der Grenzwert existiert. Höhere und gemischte Ableitungen wie $f_{xy}$ werden wieder induktiv definiert; hier wird zunächst bezüglich $x$, dann bezüglich $y$ abgeleitet. Der Fall mit mehr als zwei Variablen ist analog.
Der *Satz von Schwarz* besagt, dass Stetigkeit von $f_{xy}$ und $f_{yx}$ impliziert, dass $f_{xy} = f_{yx}$ gilt.
Höhere und gemischte Ableitungen werden in SymPy durch
```{code-block}
sympy.diff(expr, x1, x2, x3, ...)
```
(oder durch `expr.diff(x1, x2, x3, ...)`) berechnet. Der Fall mehrerer identischer Variablen, also höherer Ableitungen, kann auch als
```{code-block}
sy.diff(expr, x, n)
```
berechnet werden, wobei `n` ein Integer ist.
```{code-cell}
y = sy.symbols('y')
sy.diff(c * x**2 * y**2, x, y, 2)
```
```{code-cell}
sy.diff(1/x, x, 10)
```
## Höherdimensionale Funktionen
Höherdimensionale Funktionen können mit `sympy.Matrix` repräsentiert werden.
*Beispiel:* $f: \mathbb{R}^2 \rightarrow \mathbb{R}^3$
$$
f(\rho, \phi) = \begin{pmatrix} \rho \cos(\phi) \\ \rho \sin(\phi) \\ \rho^2 \end{pmatrix}
$$
```{code-cell}
rho, phi = sy.symbols('rho, phi')
F = sy.Matrix([rho*sy.cos(phi), rho*sy.sin(phi), rho**2])
F
```
Hier funktionieren jetzt z.B. Substituieren, Differenzieren usw. wie bei einfachen Ausdrücken:
```{code-cell}
F.subs(rho, 4), F.diff(rho)
```
### Jacobi-Matrix
Die Jacobi-Matrix ist die Matrix der partiellen Ableitungen bzgl. aller Variablen, hier $\rho$ und $\phi$.
```{code-cell}
X = (rho, phi)
F.jacobian(X)
```
Schnelle numerische Berechnung als Beispiel, wieder mit `lambdify`:
```{code-cell}
f = sy.lambdify(X, F.jacobian(X))
```
```{code-cell}
f(4, 4)
```
### Symbolisch oder numerisch?
Hier haben wir nun Matrizen sowohl im numerischen Sinne (`NumPy`) als auch symbolischen Sinne kennengelernt (`SymPy`). Im Prinzip ist hier Funktionalität ein bisschen "doppelt".
Sehr kurz gefasst könnte man sagen: Numerisch ist schneller, während symbolisch genauer ist (rationale Zahlen, reelle Zahlen-Objekte). Unter anderem zeigt das Beispiel mit der Jacobi-Matrix eine gute Verbindung und Nutzung beider Welten: symbolische Ableitung und dann numerische Auswertung.
Im Übergang dieser beiden Welten helfen Funktionen wie `sy.lambdify` `sy.matrices.dense.matrix2numpy` und `sy.matrices.dense.list2numpy`.
<!-- TODO: hessian? -->
## Gewöhnliche Differentialgleichungen
Gewöhnliche Differentialgleichungen sind Bestimmungsgleichungen einer Funktion in einer Variablen, die neben der unbekannten Funktion selbst auch ihre Ableitungen enthalten. Beispiel: Die lineare Gleichung zweiter Ordnung
$$
f''(x) + c^2 f(x) = 0, \quad c > 0,
$$
hat zwei linear unabhängige Lösungen $x \mapsto \sin(cx)$ und $x \mapsto \cos(cx)$.
Gewöhnliche Differentialgleichungen können mit `sympy.dsolve` gelöst werden. Die unbekannte Funktion muss dabei als `sympy.Function` erzeugt werden.
```{code-cell}
f = sy.Function('f')
c = sy.symbols('c', real=True, positive=True)
sol = sy.dsolve(sy.diff(f(x), x, x) + c**2 * f(x), f(x))
sol
```
Die unbekannten Konstanten können durch Wahl einer Anfangsbedingung festgelegt werden. `dsolve` berücksichtigt selbst allerdings keine Anfangsbedinungen; diese müssen "von Hand" zum Bestimmen der Konstanten genutzt werden. Beispiel:
$$
f(0) = 0, \quad f'(0) = 1
$$
```{code-cell}
initial_conditions = (sol.rhs.subs(x, 0),
sol.rhs.diff(x).subs(x, 0) - 1)
unknowns = sy.symbols('C1, C2')
constants = sy.linsolve(initial_conditions, unknowns)
constants
```
```{code-cell}
substitutions = dict(zip(unknowns, constants.args[0]))
substitutions
```
```{code-cell}
sol.subs(substitutions)
```
SymPy kann auch verschiedene Typen nichtlinearer Differentialgleichungen lösen, z.B.
```{code-cell}
sy.dsolve(sy.diff(f(x), x) - 1/f(x), f(x))
```
Für einige Gleichungen gibt SymPy approximative Lösungen durch Potenzreihen, z.B. für $f''(x) = xf(x)$ (die exakten Lösungen sind hier Airy-Funktionen).
```{code-cell}
sy.dsolve(sy.diff(f(x), x, x) - x*f(x), f(x))
```
Die Ordnung und der Basispunkt der Potenzreihe lassen sich über die optionalen Parameter `x0` und `n` steuern. Standardwerte sind `x0=0` und `n=6`.
......@@ -10,7 +10,7 @@ kernelspec:
name: python3
---
# Exceptions
# Exceptions: Übungen
## Aufgabe 1
......@@ -30,6 +30,7 @@ print(cities[2]['name'])
In diesem Code gibt es diverse mögliche Fehlerquellen. Benutzen Sie Exception Handling, um hilfreichere Fehlermeldungen auszugeben und die Verarbeitung ggf. in sinnvoller Weise fortzusetzen.
```{code-cell}
:tags: ['hide-cell']
# Datei generieren:
with open('sample.csv', 'w') as f:
......@@ -43,6 +44,7 @@ with open('sample.csv', 'w') as f:
```
```{code-cell}
:tags: ['hide-cell']
cities = []
try:
with open('sample.csv', 'r') as f:
......
# Git
# Git: Übungen
## Aufgabe 1
Loggen Sie sich auf [https://gitlab.gwdg.de]() mit ihrem Studierenden-Account ein (der Nutzername ist Ihre volle Email-Adresse) und erzeugen Sie ein neues Projekt. Clonen Sie dieses Projekt in zwei separate Verzeichnisse.
Loggen Sie sich auf [https://gitlab.gwdg.de](https://gitlab.gwdg.de) mit ihrem Studierenden-Account ein (der Nutzername ist Ihre volle Email-Adresse) und erzeugen Sie ein neues Projekt. Clonen Sie dieses Projekt in zwei separate Verzeichnisse.
(a) Ziehen Sie mit diesen beiden Verzeichnissen die Schritte aus der Vorlesung nach:
......
......@@ -10,7 +10,7 @@ kernelspec:
name: python3
---
# Gleichungen
# Gleichungen: Übungen
<!--
# TODO: geht noch icht mit solveset , entfernen?
......
---
jupytext:
formats: md:myst
text_representation:
extension: .md
format_name: myst
kernelspec:
display_name: Python 3
language: python
name: python3
---
# Integration: Übungen
## Aufgabe 1
Definieren Sie die Funktion
$$
f(s):= \int_0^\infty x^{s-1} e^{-x} dx, \quad s >0
$$
mit `integrate`. Das Ergebnis wird stückweise sein. Nutzen Sie dann Annahmen an `s`, so dass eine eindeutige Lösung ausgegeben wird.
```{code-cell}
:tags: ['hide-cell']
import sympy as sy
x,s= sy.symbols('x,s')
sy.integrate(x**(s-1)*sy.exp(-x),(x,0,sy.oo))
```
```{code-cell}
:tags: ['hide-cell']
s= sy.symbols('s', positive=True)
g = sy.integrate(x**(s-1)*sy.exp(-x),(x,0,sy.oo))
g
```
## Aufgabe 2\*
Gegeben seien die Listen $L1 = [x, x^3, x^5, x^7, x^9,x^{11}x^{13},x^{15},x^{17},]$ und $L2 = [x, x^2, x^6, x^{24}, x^{120}]$.
* Erstellen Sie diese beiden Listen mit Hilfe von list-comprehensions.
* Bilden Sie $L3 = L1+L2$.
* Bilden Sie von jedem Eintrag von $L3$ die Ableitung und die Stammfunktion.
* Bestimmen Sie von jedem Element von $L3$ den Funktionswert an der Stelle $x=3$ und entfernen Sie den größten Eintrag aus der resultierenden Liste.
* Speichern Sie die Funktionen aus obiger Liste jeweils in ein Dictionary ab, welches den Funktionsausdruck, die Ableitung und Stammfunktion enthält.
* Geben Sie mit Hilfe dieses Dictionaries die Funktionen mit erklärendem Text aus.
```{code-cell}
:tags: ['hide-cell']
x = sy.symbols('x')
L1 = [x**(2*n-1) for n in range(1,10)]
L2 = [x**(sy.factorial(n)) for n in range(1,6)]
L3 = L1 + L2
```
```{code-cell}
:tags: ['hide-cell']
[f.diff() for f in L3]
```
```{code-cell}
:tags: ['hide-cell']
[f.integrate(x) for f in L3]
```
```{code-cell}
:tags: ['hide-cell']
L = [f.subs(x,3) for f in L3]; L
```
```{code-cell}
:tags: ['hide-cell']
m = max(L)
L.remove(m); L
```
```{code-cell}
:tags: ['hide-cell']
L4=[{"Funktion":f,"diff":f.diff(x), "int":f.integrate(x)} for f in L3]; L4
```
```{code-cell}
:tags: ['hide-cell']
for D in L4:
print(' Für die Funktion {} ist die Ableitung {} und die Stammfunktion {}'.format(D['Funktion'],D['diff'],D['int']) )
```
```{code-cell}
:tags: ['hide-cell']
for D in L4:
print(' Für die Funktion {} ist die Ableitung {} und die Stammfunktion {}'.format(D['Funktion'],D['diff'],D['int']) )
```
```{code-cell}
:tags: ['hide-cell']
for D in L4:
print ('Für die Funktion f(x)='+str(D['Funktion']) +' ist die Ableitung f`(x)='+str(D['diff'])+' und die Stammfunktion F(x)='+str(D['int']))
```