JuliaKurs23/chapters/11_LinAlg.qmd

368 lines
7.5 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Lineare Algebra
## Normen
Um Fragen wie Kondition oder Konvergenz eines Algorithmus studieren zu können, brauchen wir eine Metrik. Für lineare Räume ist es zweckmäßig, die Metrik über eine Norm zu definieren:
$$
d(x,y) := ||x-y||
$$
### $p$-Normen
Eine einfache Klasse von Normen im $^n$ sind die $p$-Normen
$$
||\mathbf{x}||_p = \left(\sum |x_i|^p\right)^\frac{1}{p},
$$
die die die euklidische Norm $p=2$ verallgemeinern.
Sei $x_{\text{max}}$ die _betragsmäßig_ größte Komponente von $\mathbf{x}\in ^n$. Dann gilt stets
$$ |x_{\text{max}}| \le ||\mathbf{x}||_p \le n^\frac{1}{p} |x_{\text{max}}|
$$
(Man betrachte einen Vektor, dessen Komponenten alle gleich $x_{\text{max}}$ sind bzw. einen Vektor, dessen Komponenten außer $x_{\text{max}}$ alle gleich Null sind.)
Damit folgt
$$
\lim_{p \rightarrow \infty} ||\mathbf{x}||_p = |x_{\text{max}}| =: ||\mathbf{x}||_\infty.
$$
In Julia definiert das `LinearAlgebra`-Paket eine Funktion `norm(v, p)`.
```{julia}
using LinearAlgebra
v = [3, 4]
w = [-1, 2, 33.2]
@show norm(v) norm(v, 2) norm(v, 1) norm(v, 4) norm(w, Inf);
```
- Wenn das 2. Argument `p` fehlt, wird `p=2` gesetzt.
- Das 2. Argument kann auch `Inf` (also $+\infty$) sein.
- Das 1. Argument kann ein beliebiger Container voller Zahlen sein. Die Summe $\sum |x_i|^p$ erstreckt sich über *alle* Elemente des Containers.
- Damit ist für eine Matrix `norm(A)` gleich der _Frobenius-Norm_ der Matrix `A`.
```{julia}
A = [1 2 3
4 5 6
7 8 9]
norm(A) # Frobenius norm
```
Da Normen homogen unter Multiplikation mit Skalaren sind,
$||\lambda \mathbf{x}|| = |\lambda|\cdot||\mathbf{x}||$, sind sie durch die Angabe der Einheitskugel vollständig bestimmt. Subadditivität der Norm (Dreiecksungleichung) ist äquivalent zur Konvexität der Einheitskugel.
```{julia}
#| code-fold: false
#| fig-cap: "Einheitskugeln im $^2$ für verschiedene $p$-Normen: $p$=0.8; 1; 1.5; 2; 3.001 und 1000"
using Plots
colors=[:purple, :green, :red, :blue,:aqua, :black]
x=LinRange(-1, 1, 1000)
y=LinRange(-1, 1, 1000)
fig1=plot()
for p ∈ (0.8, 1, 1.5, 2, 3.001, 1000)
contour!(x,y, (x,y) -> p * norm([x, y], p), levels=[p], aspect_ratio=1,
cbar=false, color=[pop!(colors)], contour_labels=true, ylim=[-1.1, 1.1])
end
fig1
```
Wie man sieht, muß $p\ge 1$ sein, damit die Einheitskugel konvex und $||.||_p$ eine Norm ist.
Die Julia-Funktion `norm(v, p)` liefert allerdings für beliebige Parameter `p` ein Ergebnis.
### Induzierte Normen (Operatornormen)
Matrizen $A$ repräsentieren lineare Abbildungen $\mathbf{v}\mapsto A\mathbf{v}$. Die von einer Vektornorm Induzierte Matrixnorm beantwortet die Frage:
> _„Um welchen Faktor kann ein Vektor durch die Transformation $A$ maximal gestreckt werden?“_
Auf Grund der Homogenität der Norm unter Multiplikation mit Skalaren reicht es aus, das Bild der Einheitskugel unter der Transformation $A$ zu betrachten.
::: {.callout-tip}
## Definition
Sei $V$ ein Vektorraum mit einer Dimension $0<n<\infty$ und
$A$ eine $n\times n$-Matrix. Dann ist
$$
||A||_p = \max_{||\mathbf{v}||_p=1} ||A\mathbf{v}||_p
$$
:::
Induzierte Normen lassen sich für allgemeines $p$ nur schwer berechnen. Ausnahmen sind die Fälle
- $p=1$: Spaltensummennorm
- $p=2$: Spektralnorm und
- $p=\infty$: Zeilensummennorm
Diese 3 Fälle sind in Julia in der Funktion `opnorm(A, p)` aus dem `LinearAlgebra`-Paket implementiert, wobei wieder `opnorm(A) = opnorm(A, 2)` gilt.
```{julia}
A = [ 0 1
1.2 1.5 ]
@show opnorm(A, 1) opnorm(A, Inf) opnorm(A, 2) opnorm(A);
```
Das folgende Bild zeigt die Wirkung von $A$ auf Einheitsvektoren (Code durch anklicken sichtbar):
```{julia}
#| code-fold: true
#| fig-cap: "Bild der Einheitskugel unter $v \\mapsto Av$"
using CairoMakie
# Makie bug https://github.com/MakieOrg/Makie.jl/issues/3255
# Würgaround https://github.com/MakieOrg/Makie.jl/issues/2607#issuecomment-1385816645
tri = BezierPath([
MoveTo(Point2f(-0.5, -1)), LineTo(0, 0), LineTo(0.5, -1), ClosePath()
])
A = [ 0 1
1.2 1.5 ]
colorlist = resample_cmap(:hsv, 12)
t = LinRange(0, 1, 100)
xs = sin.(2π*t)
ys = cos.(2π*t)
Axys = A * [xs, ys]
u = [sin(n*π/6) for n=0:11]
v = [cos(n*π/6) for n=0:11]
x = y = zeros(12)
Auv = A * [u,v]
fig2 = Figure(size=(800, 400))
lines(fig2[1, 1], xs, ys, color=t, linewidth=5, colormap=:hsv, axis=(; aspect = 1, limits=(-2,2, -2,2),
title=L"$\mathbf{v}$", titlesize=30))
arrows!(fig2[1,1], x, y, u, v, arrowsize=10, arrowhead=tri, colormap=:hsv, linecolor=range(0,11), linewidth=3)
Legend(fig2[1,2], MarkerElement[], String[], L"⟹", width=40, height=30, titlesize=30, framevisible=false)
lines(fig2[1,3], Axys[1], Axys[2], color=t, linewidth=5, colormap=:hsv, axis=(; aspect=1, limits=(-2,2, -2,2),
title=L"$A\mathbf{v}$", titlesize=30))
arrows!(fig2[1,3], x, y, Auv[1], Auv[2], arrowsize=10, arrowhead=tri, colormap=:hsv, linecolor=range(0,11),
linewidth=3)
fig2
```
## Matrixfaktorisierungen
Eine Basisaufgabe der numerischen linearen Algebra ist die Lösung von linearen Gleichungssystemen
$$
A\mathbf{x} = \mathbf{b}.
$$
Falls keine Lösung existiert, ist man oft an der bestmöglichen Annäherung an eine Lösung interessiert, d.h., gesucht wird der Vektor $\mathbf{x}$, für den
$$
||A\mathbf{x} - \mathbf{b}|| \rightarrow \min.
$$
# Das _Linear Algebra_-Paket: eine kurze Auswahl
- zusätzliche Matrix-Typen
- Subtypen von `AbstractMatrix`: genauso verwendbar, wie andere Matrizen
- `Tridiagonal`
- `SymTridiagonal`
- `Symmetric`
- `UpperTriangular`
- ...
- Arithmetik: Matrixmultiplikation, `inv`, `det`, `exp`
- Lineare Gleichungssysteme: `\`
- Matrixfaktorisierungen
- `LU`
- `QR`
- `Cholesky`
- `SVD`
- ...
- Eigenwerte/-vektoren
- `eigen`, `eigvals`, `eigvecs`
- Zugriff auf BLAS/LAPACK-Funktionen
## Matrixtypen
```julia
using LinearAlgebra
```
```julia
A = SymTridiagonal(fill(1.0, 4), fill(-0.3, 3))
```
```julia
B = UpperTriangular(A)
```
```julia
A + B
```
### Einheitsmatrix `I`
`I` bezeichnet eine Einheitsmatrix (quadratisch, Diagonalelemente = 1, alle anderen = 0) in der jeweils erforderlichen Größe
```julia
A + 4I
```
## Faktorisierungen
### LU-Faktorisierung mit Zeilenpivoting
('Lower/Upper triangular matrix', im Deutschen auch oft "LR-Zerlegung" für "Linke/Rechte Dreiecksmatrix")
```julia
A = [0 22 1.
-1 2 3
77 18 19]
```
```julia
# Faktorisierungen geben eine spezielle Struktur zurück, die die Matrixfaktoren und weitere
# Informationen enthalten:
Af = lu(A);
@show Af.L Af.U Af.p;
```
```julia
# man kann auch gleich auf der linken Seite ein entsprechendes Tupel verwenden
l,u,p = lu(A)
l
```
```julia
u
```
```julia
p
```
Der Permutationsvektor `p` zeigt an, wie die Zeilen der Matrix permutiert wurden:
```julia
A[p, :] # 3. Zeile, 1. Zeile, 2. Zeile von A
```
Es gilt: $$ L\cdot U = PA$$
```julia
l * u - A[p,:]
```
### QR-Zerlegung
```julia
q, r = qr(A);
q
```
```julia
r
```
### Singular value decomposition
```julia
u, s, vt = svd(A);
s
```
```julia
u
```
```julia
vt
```
```julia
evalues, evectors = eigen(A)
evalues
```
```julia
evectors
```
### Lineare Gleichungssysteme
Das lineare Gleichungssystem
$$Ax = b$$
kann man in Julia einfach lösen mit
```
x = A\b
```
```julia
b = [2,3,4]
A\b
```
Dabei wird eine geeignete Matrixfaktorisierung vorgenommen (meist LU). Wenn man Lösungen zu mehreren rechten Seiten $b_1, b_2,...$ benötigt, sollte man die Faktorisierung nur einmal durchführen:
```julia
Af = factorize(A)
```
```julia
Af\b
```
```julia
Af\[5,7,9]
```
```julia
```