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

actual

parent 9a106dd2
Pipeline #222329 failed with stage
in 10 minutes and 17 seconds
......@@ -19,7 +19,7 @@ Implementieren Sie die $LU$-Zerlegung, wie in der Vorlesung beschrieben. Dabei k
Testen Sie Ihre Implementierung an der Matrix
$$
A = \begin{pmatrix} 1.1 & 2.1 & 3.1 \\ 2.2 & 3.2 & 1.2 \\ 3.3 & 1.3 & 2.3 \end{pmatrix}.
A = \begin{pmatrix} 1.1 & 2.1 & 3.1 \\ 2.2 & 3.2 & 1.2 \\ 3.3 & 2.3 & 1.3 \end{pmatrix}.
$$
*Hinweis*: Dies ist wieder ein Fall, in dem ein Debugger sehr hilfreich sein kann.
......
......@@ -3,15 +3,17 @@ jupytext:
text_representation:
extension: .md
format_name: myst
format_version: 0.13
jupytext_version: 1.10.3
kernelspec:
display_name: Python 3
display_name: Python 3 (ipykernel)
language: python
name: python3
---
# Lineare Algebra
```{code-cell}
```{code-cell} ipython3
import numpy as np
import numpy.linalg as npl
import scipy.linalg as spl
......@@ -27,26 +29,25 @@ array1 @ array2
Für 1d-Arrays berechnet `dot` das *Skalarprodukt*:
```{code-cell}
```{code-cell} ipython3
v = np.arange(3)
v.dot(v), v @ v
```
Für 2d-Arrays berechnet `dot` das *Matrix-Produkt*:
```{code-cell}
```{code-cell} ipython3
A = np.arange(9).reshape((3, 3))
A.dot(A), A @ A
```
Für 1d- und 2d-Arrays berechnet `dot` das *Matrix-Vektor-Produkt*:
```{code-cell}
```{code-cell} ipython3
A.dot(v), A @ v
```
```{code-cell}
```{code-cell} ipython3
v.dot(A), v @ A
```
......@@ -59,19 +60,18 @@ dot(a, b)[i,j,k,l] == sum(a[i,j,:] * b[k,:,l])
```
```{code-block}
(a @ b)[i,j,l] == sum(a[i,j,:] * b[k,:,l])
(a @ b)[i,j,k,l] == sum(a[i,j,:] * b[k,:,l])
```
wenn i == k oder i == 1 oder k == 1.
```{code-cell}
```{code-cell} ipython3
a = np.arange(24).reshape((2,3,4))
b = np.arange(40).reshape((2,4,5))
a @ b
(a @ b).shape
```
## Determinante
<a id="linalg"></a>
```{code-block}
......@@ -80,7 +80,7 @@ numpy.linalg.det(array)
berechnet die Determinante einer Matrix; `array` muss mindestens zwei-dimensional sein. Höher-dimensionale Arrays werden wie oben als *Arrays von Matrizen* aufgefasst.
```{code-cell}
```{code-cell} ipython3
npl.det(A)
```
......@@ -114,12 +114,12 @@ für alle `i`. Die Eigenvektoren sind auf 1 normiert.
`eig` funktioniert analog auch mit höher-dimensionalen Arrays als *Arrays von Matrizen*.
```{code-cell}
```{code-cell} ipython3
b, W = npl.eig(A)
b, W
```
```{code-cell}
```{code-cell} ipython3
A @ W - W @ np.diag(b)
```
......@@ -143,7 +143,7 @@ jedenfall solange $A$ *invertierbar* ist. Inverse Matrizen können berechnet wer
scipy.linalg.inv(A)
```
```{code-cell}
```{code-cell} ipython3
A = np.diag(np.ones(3)) - np.diag(np.ones(2), 1)
print(f'A = \n {A}')
......@@ -171,7 +171,7 @@ scipy.linalg.solve(A, y)
#### Beispiel
```{code-cell}
```{code-cell} ipython3
A = np.diag(np.ones(10)) - np.diag(np.ones(9), 1)
x = np.ones(10)
......@@ -306,13 +306,12 @@ $$
Hilbert-Matrizen sind extrem schlecht konditioniert:
```{code-cell}
```{code-cell} ipython3
H = spl.hilbert(20)
npl.cond(H)
```
```{code-cell}
```{code-cell} ipython3
x = np.ones(20)
# erzeuge rechte Seite
y = H @ x
......@@ -328,7 +327,6 @@ print(x_approx)
print(f'error in x = {npl.norm(x_approx - x) / npl.norm(x)}')
```
## Rundungsfehler
Die Kondition beschreibt die Fehleranfälligkeit des zu lösenden *Problems*. Zusätzlich können Fehler dadurch auftreten, dass Lösungs-Verfahren oft nicht exakt implementiert werden können, d.h. auch die numerische *Approximation* des zu lösenden Problems kann zu Fehlern führen, z.B. aufgrund von Rundungsfehlern.
......@@ -345,7 +343,7 @@ $$
für kleine $x$?
```{code-cell}
```{code-cell} ipython3
x = 1e-15
((x+1) - 1) / x
```
......@@ -360,14 +358,14 @@ signifikante Dezimalstellen. Bei `1 + 1e-15` werden also fast alle Binärstellen
Von `x = 1e-16` bleibt tatsächlich nichts mehr übrig:
```{code-cell}
```{code-cell} ipython3
x = 1e-16
((x+1) - 1) / x
```
Tatsächlich ist die Subtraktion zweier fast gleicher Zahlen numerisch instabil. Außerdem sieht man, dass die numerische Addition nicht assoziativ ist:
```{code-cell}
```{code-cell} ipython3
x = 1e-15
print( (x+1)-1 )
print( x+(1-1) )
......@@ -482,7 +480,16 @@ P, L, U = scipy.linalg.lu(A)
die Zerlegung explizit berechnet werden.
```{code-cell}
```{code-cell} ipython3
P, L, U = spl.lu(spl.hilbert(3))
U
P,L,U
```
```{code-cell} ipython3
LUP = spl.lu_factor(spl.hilbert(3))
LUP
```
```{code-cell} ipython3
```
......@@ -3,8 +3,10 @@ jupytext:
text_representation:
extension: .md
format_name: myst
format_version: 0.13
jupytext_version: 1.10.3
kernelspec:
display_name: Python 3
display_name: Python 3 (ipykernel)
language: python
name: python3
---
......@@ -31,7 +33,7 @@ folgt vor:
u'(x_i) \approx \frac{u(x_{i+1}) - u(x_i)}{x_{i+1} - x_i}, \quad h := \frac{1}{n-1}
$$
```{code-cell}
```{code-cell} ipython3
import numpy as np
def f(x): return x**3 + x**2
......@@ -52,12 +54,11 @@ zu bestimmen. Hier ist allerdings verlangt, dass die Funktion beliebig auswertba
Das ist jedoch nicht im Allgemeinen der Fall und falls ja, kann man auch symbolisch
differenzieren.
```{code-cell}
```{code-cell} ipython3
from scipy.misc import derivative
x[9],derivative(f, x[9], dx=1e-6)
```
## Beispiel: 1d Randwertproblem
Suche eine Funktion
......@@ -123,7 +124,7 @@ e^{k x_{n-2}}
\end{pmatrix}.
$$
```{code-cell}
```{code-cell} ipython3
import scipy.linalg as spl
def poisson1d(f, n):
......@@ -170,8 +171,7 @@ def poisson1d(f, n):
return x, y
```
```{code-cell}
```{code-cell} ipython3
import holoviews as hv
hv.extension('bokeh')
......@@ -180,7 +180,6 @@ x, y = poisson1d(lambda x: np.exp(k * x), 40)
hv.Curve((x, y)) * hv.Points((x, y)).options(size=5, color='red')
```
## Numerische Integration
![https://xkcd.com/1201/](https://imgs.xkcd.com/comics/integration_by_parts.png)
......@@ -206,7 +205,7 @@ $$
\lim_{N \to \infty} I_N(f) = \int_a^b f(x) \,dx.
$$
```{code-cell}
```{code-cell} ipython3
import numpy as np
def riemann_sum(f, a, b, N=50):
......@@ -218,12 +217,12 @@ def riemann_sum(f, a, b, N=50):
riemann_sum(lambda x: np.log(x**2), 1, 5)
```
```{code-cell}
```{code-cell} ipython3
import holoviews as hv
hv.extension('bokeh')
```
```{code-cell}
```{code-cell} ipython3
%output size=150
def curve(N=20):
......@@ -241,6 +240,7 @@ def curve(N=20):
hv.DynamicMap(curve, kdims=['N']).redim.range(N=(3, 20))
```
(integrate)=
## Integration mit Scipy
......@@ -255,7 +255,8 @@ scipy.integrate.quad(f, a, b, args=())
`args` sind zusätzliche Arguemnte, die an `f` übergeben werden.
Der Rückgabewert ist ein Tupel `(result, error_bound)`.
```{code-cell}
```{code-cell} ipython3
from scipy.integrate import quad
res = quad(lambda x: np.log(x**2), 1, 5)
......@@ -264,7 +265,7 @@ res
Absoluter Fehler (durch Benutzung von Sympy):
```{code-cell}
```{code-cell} ipython3
import sympy as sy
x = sy.symbols('x')
......@@ -276,7 +277,7 @@ abs(res[0] - exact).evalf()
`quad` hat eine Vielzahl von Optionen, die z.B. die Wahl des Quadratur-Verfahrens beeinflussen. Für weitere Details:
```{code-cell}
```{code-cell} ipython3
quad?
```
......
......@@ -3,8 +3,10 @@ jupytext:
text_representation:
extension: .md
format_name: myst
format_version: 0.13
jupytext_version: 1.10.3
kernelspec:
display_name: Python 3
display_name: Python 3 (ipykernel)
language: python
name: python3
---
......@@ -19,12 +21,13 @@ Wir können also vieles direkt in Pandas machen, was wir sonst mit `numpy/scipy`
Allerdings liefert uns Pandas sehr viel nützliche Zusatzfunktionalität und
bequeme "high-level" Funktionen für große Arrays und Tabellen.
```{code-cell}
```{code-cell} ipython3
import pandas as pd
import holoviews as hv
hv.extension('bokeh')
```
(laden_speichern)=
## Daten einlesen und speichern mit Pandas
......@@ -41,27 +44,26 @@ pandas.read_csv(filepath, sep = ',', header='infer', names=None)
- `header`: Nummer der Zeile, die zur Benennung der Spalten verwendet
werden soll und ab der die Daten beginnen.
```{code-cell}
```{code-cell} ipython3
my_dataframe = pd.read_csv('https://num.math.uni-goettingen.de/mop_data/lectures/array.csv', sep = ',', header=None)
my_dataframe
```
```{code-cell}
```{code-cell} ipython3
my_dataframe.values
```
Zum Speichern gibt es verschiedene Funktionen wie `to_csv` und `to_json`
```{code-cell}
```{code-cell} ipython3
my_dataframe.to_csv('copy.csv', sep=',', header=None)
```
```{code-cell}
```{code-cell} ipython3
my_dataframe.to_pickle('copy.p', compression='infer', protocol=4)
```
```{code-cell}
```{code-cell} ipython3
my_dataframe.to_json('copy.json', compression='infer')
```
......@@ -92,7 +94,7 @@ Sie erlauben
Als Beispiel verwenden wir Pandas zur Darstellung von Klimadaten (Index zur Beschreibung der arktischen Oszillation) (Die Daten sind von [nooa](http://www.cpc.ncep.noaa.gov/products/precip/CWlink/daily\_ao\_index/monthly.ao.index.b50.current.ascii)).
```{code-cell}
```{code-cell} ipython3
arctic_oscillation = pd.read_csv('https://num.math.uni-goettingen.de/mop_data/lectures/monthly.ao.index.b50.current.ascii', sep='\s+',
header=None, names=['year','month','value'], usecols=[0, 1, 2]
)
......@@ -103,7 +105,7 @@ als `sep` verwenden wir hier `\s+`, da die Daten durch eine unregelmäßige Anza
Wir können wie auf dictionaries mit dem Namen der Spalte darauf zugreifen:
```{code-cell}
```{code-cell} ipython3
arctic_oscillation['year'].head()
```
......@@ -115,19 +117,18 @@ der `parse_dates` Option beim Einlesen:
Weitere Möglichkeiten, wie diese Option verwendet werden kann, findet man in der Dokumentation.
```{code-cell}
```{code-cell} ipython3
arctic_oscillation = pd.read_csv('https://num.math.uni-goettingen.de/mop_data/lectures/monthly.ao.index.b50.current.ascii',
sep='\s+', parse_dates={'date':[0,1]}, header=None, names=['year','month','value'])
arctic_oscillation.head()
```
Pandas mächtige Datenanalyse Werkzeuge und Flexibilität der Dateiformate
lassen sich gut mit der Interaktivität von Holoviews und dessen Fähigkeit,
komplexe Daten zu visualisieren, kombinieren. Wir können direkt Pandas Objekte
in Holoviews verwenden und key- und value Dimensionen mit den Spalten-Namen setzen.
```{code-cell}
```{code-cell} ipython3
hv.Curve(arctic_oscillation, kdims=['date'],vdims=['value'])
```
......@@ -136,8 +137,9 @@ hv.Curve(arctic_oscillation, kdims=['date'],vdims=['value'])
Hier lesen wir nun Temperatur-daten ein, die sowohl einen Zeit-Index haben als auch
einer Koordinate zugeordnet sind (latitude und longitude).
```{code-cell}
:tags: ['remove-cell']
```{code-cell} ipython3
:tags: [remove-cell]
import requests
import io
......@@ -147,41 +149,41 @@ with open("temperature_reset.hdf", mode='wb') as file:
file.write(response.content)
```
```{code-cell}
```{code-cell} ipython3
temperatureframe = pd.read_hdf("temperature_reset.hdf", key='myIdentifier')
```
Größe des Frames:
```{code-cell}
```{code-cell} ipython3
temperatureframe.shape
```
Die ersten paar Einträge:
```{code-cell}
```{code-cell} ipython3
temperatureframe.head()
```
Zufällige Einträge:
```{code-cell}
```{code-cell} ipython3
temperatureframe.sample(n = 4)
```
Index:
```{code-cell}
```{code-cell} ipython3
temperatureframe.index
```
```{code-cell}
```{code-cell} ipython3
temperatureframe.index.unique()
```
Es gibt 12 Monate:
```{code-cell}
```{code-cell} ipython3
temperatureframe.index.nunique()
```
......@@ -190,9 +192,10 @@ Unser Beispiel Dataframe enthält für jeden Monat genau einen Wert pro Koordina
Sortieren (geht sowohl mit den Spalten als auch mit dem Index):
```{code-cell}
```{code-cell} ipython3
temperatureframe.sort_values('time').head()
```
(pandas_zugriff)=
### Zugriff und Slicing
......@@ -201,17 +204,17 @@ Eine Spalte eines Dataframes ist ein `Series` Objekt.
Auf ein Dataframe wie ein `Series`-Objekt lassen sich viele nützliche Methoden anwenden.
```{code-cell}
```{code-cell} ipython3
type(temperatureframe['tem'])
```
```{code-cell}
```{code-cell} ipython3
temperatureframe['tem']
```
Mittelwert ausrechnen (hier z.B. der Temperatur):
```{code-cell}
```{code-cell} ipython3
temperatureframe['tem'].mean()
```
......@@ -221,48 +224,48 @@ Für das Auswählen von Zeilen gibt es mehrere Möglichkeiten:
- `.loc` wählt Zeilen anhand des Namens ihres Index aus. Man kann beispielsweise eine Liste von labels `['a', 'b', 'c']` übergeben.
Beiden kann aber auch ein boolean array oder eine Funktion (callable) übergeben werden.
```{code-cell}
```{code-cell} ipython3
temperatureframe.iloc[0:15:1]
```
Das Dataframe ist mit Zahlen von 1 bis 12 indiziert. Diese stehen für Monate.
Mit `loc` können wir also folgendermaßen alle Zeilen für den Januar aufrufen:
```{code-cell}
```{code-cell} ipython3
temperatureframe.loc[1]
```
Wir können durch neue Zuweisung auch Werte überschreiben:
```{code-cell}
```{code-cell} ipython3
temperatureframe['tem'].iloc[100]
```
<!--
#TODO evtl. kopie und keine änderung des objektes
-->
```{code-cell}
```{code-cell} ipython3
temperatureframe['tem'].iloc[100] = 42
```
```{code-cell}
```{code-cell} ipython3
temperatureframe['tem'].iloc[100]
```
Wie in numpy können wir auch mittels boolean masks indizieren:
```{code-cell}
```{code-cell} ipython3
temperatureframe['tem']>0
```
```{code-cell}
```{code-cell} ipython3
temperatureframe[temperatureframe['tem']>0].head()
```
Im Index-Zugriff können auch beliebig viele Bedingungen verknüpft werden:
```{code-cell}
```{code-cell} ipython3
temperatureframe[(temperatureframe['tem']>-5)&(temperatureframe['tem']<5)].head()
```
......@@ -272,7 +275,7 @@ Wir erzeugen nun ein Plot Objekt aus dem Datensatz
und beschriften Key- und Value-dimensions, damit Holoviews die Spalten richtig interpretiert
und direkt sinnvoll plottet.
```{code-cell}
```{code-cell} ipython3
hv.HeatMap(temperatureframe, kdims=['longitude', 'latitude'], vdims = ['tem'])
```
......@@ -281,22 +284,23 @@ Es gibt allerdings mehrere verschiedene Zeiten (Monate), die wiederum mehrmals a
Um Klarheit zu schaffen, wählen wir jetzt in den Daten einen Monat aus:
```{code-cell}
```{code-cell} ipython3
temperatureframe.loc[1].head()
```
und machen einen plot daraus:
```{code-cell}
```{code-cell} ipython3
hv.HeatMap(temperatureframe.loc[1], kdims=['longitude', 'latitude'], vdims = ['tem'])
```
und mit HoloMap können wir uns alle eindeutigen Monate (12) ansehen und durchgehen:
```{code-cell}
```{code-cell} ipython3
plots = {k:hv.HeatMap(temperatureframe.loc[k], kdims=['longitude', 'latitude'], vdims = ['tem']) for k in temperatureframe.index.unique()}
hv.HoloMap(plots).options(height=400,width=700)
```
<!--
Sollten Fehleinträge in den Daten sein, wie z.B. Not A Number (NaN) zerstören
diese evtl. folge-Operationen.
......@@ -317,13 +321,13 @@ plot.data.loc[plot.data.index==11].dropna().head()
Mithilfe von `.groupby()` können wir Daten in Gruppen aufteilen, innerhalb dieser Gruppen Operationen ausführen und sie dann wieder zusammenfügen.
Hier mitteln wir über die Temperatur eines Jahres, also jeweils über alle Zeilen mit gleichen Koordinaten und gleichem Monat.
```{code-cell}
```{code-cell} ipython3
year_average = temperatureframe.groupby(['latitude', 'longitude']).mean()
```
Dabei werden `'latitude'` und `'longitude'` zu einem Multiindex zusammengefasst:
```{code-cell}
```{code-cell} ipython3
year_average.head()
```
......@@ -332,16 +336,17 @@ Ist das DataFrame durch einen Multiindex indiziert, kann jede Dimension zum Ausw
Dazu übergeben wir `loc` ein Tupel aus slices.
Hier wollen wir alle Einträge für `'latitude'` auswählen, aber `'longitude'` auf -10 bis 10 beschränken.
Anstelle von `:` kann auch eine Liste von Spalten angegeben werden.
```{code-cell}
```{code-cell} ipython3
year_average.loc[(slice(None), slice(-10.0, 10)),:]
```
Das Ergebnis der Gruppierung können wir dann plotten als Temperatur über Koordinaten.
```{code-cell}
```{code-cell} ipython3
hv.HeatMap(year_average, kdims=['longitude', 'latitude'], vdims = ['tem']).options(height=500,width=800)
```
(merge)=
## Mehrere Tabellen zusammenführen
......@@ -349,29 +354,26 @@ Wir können mit Pandas wie mit einer relationalen Datenbank arbeiten.
Hier schauen wir uns das Verbinden von zwei Tabellen an.
Dafür besorgen wir uns zunächst zwei passende Tabellen/Daten:
```{code-cell}
```{code-cell} ipython3
fossil_df = pd.read_csv('https://num.math.uni-goettingen.de/mop_data/lectures/fossil.csv', sep = ',', header=0, index_col='Rank')
```
```{code-cell}
```{code-cell} ipython3
fossil_df.tail()
```
```{code-cell}
```{code-cell} ipython3
renew_df = pd.read_csv('https://num.math.uni-goettingen.de/mop_data/lectures/renewable.csv', sep = ',', header=0)
```
```{code-cell}
```{code-cell} ipython3