mirror of
https://github.com/janishutz/eth-summaries.git
synced 2025-11-25 10:34:23 +00:00
[NumCS] Chapter 2.3 done
This commit is contained in:
Binary file not shown.
@@ -57,6 +57,16 @@
|
|||||||
\printtoc{ForestGreen}
|
\printtoc{ForestGreen}
|
||||||
|
|
||||||
|
|
||||||
|
% ────────────────────────────────────────────────────────────────────
|
||||||
|
\newpage
|
||||||
|
\setcounter{section}{-1}
|
||||||
|
\section{Introduction}
|
||||||
|
This summary is intended to give you a broad overview of the topics relevant for the exam and is not intended to serve as a full on replacement for the script.
|
||||||
|
We have decided to write it in German, as is the new script and for some of the topics that are poorly explained in the script, we have added further explanations.
|
||||||
|
|
||||||
|
The numbering should match the script's numbering exactly, making it easier for you to look up the relevant definitions, theorems, etc in context in the script.
|
||||||
|
|
||||||
|
|
||||||
% ────────────────────────────────────────────────────────────────────
|
% ────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
% ╭────────────────────────────────────────────────╮
|
% ╭────────────────────────────────────────────────╮
|
||||||
@@ -76,7 +86,7 @@
|
|||||||
\input{parts/01_interpolation/00_polynomial/00_intro.tex}
|
\input{parts/01_interpolation/00_polynomial/00_intro.tex}
|
||||||
\input{parts/01_interpolation/00_polynomial/01_monome.tex}
|
\input{parts/01_interpolation/00_polynomial/01_monome.tex}
|
||||||
\input{parts/01_interpolation/00_polynomial/02_newton-basis.tex}
|
\input{parts/01_interpolation/00_polynomial/02_newton-basis.tex}
|
||||||
\input{parts/01_interpolation/00_polynomial/03_barzycentric-formula.tex}
|
\input{parts/01_interpolation/00_polynomial/03_lagrange-and-barzycentric-formula.tex}
|
||||||
\input{parts/01_interpolation/00_polynomial/04_chebychev-interpolation.tex}
|
\input{parts/01_interpolation/00_polynomial/04_chebychev-interpolation.tex}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ Wir können in NumPy den folgenden Ansatz verwenden, um die Laufzeit zu verringe
|
|||||||
Da die Matrix $R$ eine obere Dreiecksmatrix ist, ist das Ergebnis die Teilsummen von unserem Umgekehrten Vektor $x$, also können wir mit \verb|np.cumsum(x[::-1], axis=0)[::-1]| die Kummulative Summe berechnen.
|
Da die Matrix $R$ eine obere Dreiecksmatrix ist, ist das Ergebnis die Teilsummen von unserem Umgekehrten Vektor $x$, also können wir mit \verb|np.cumsum(x[::-1], axis=0)[::-1]| die Kummulative Summe berechnen.
|
||||||
Das \verb|[::-1]| dient hier lediglich dazu, den Vektor $x$ umzudrehen, sodass das richtige Resultat entsteht.
|
Das \verb|[::-1]| dient hier lediglich dazu, den Vektor $x$ umzudrehen, sodass das richtige Resultat entsteht.
|
||||||
Die vollständige Implementation sieht so aus:
|
Die vollständige Implementation sieht so aus:
|
||||||
\begin{minted}{python}
|
\begin{code}{python}
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
def low_rank_matrix_vector_product(A: np.ndarray, B: np.ndarray, x: np.ndarray):
|
def low_rank_matrix_vector_product(A: np.ndarray, B: np.ndarray, x: np.ndarray):
|
||||||
@@ -74,7 +74,7 @@ def low_rank_matrix_vector_product(A: np.ndarray, B: np.ndarray, x: np.ndarray):
|
|||||||
s = np.cumsum(v[::-1], axis=0)[::-1]
|
s = np.cumsum(v[::-1], axis=0)[::-1]
|
||||||
|
|
||||||
y = np.sum(A * s)
|
y = np.sum(A * s)
|
||||||
\end{minted}
|
\end{code}
|
||||||
|
|
||||||
|
|
||||||
\setcounter{all}{21}
|
\setcounter{all}{21}
|
||||||
@@ -92,7 +92,7 @@ def low_rank_matrix_vector_product(A: np.ndarray, B: np.ndarray, x: np.ndarray):
|
|||||||
\fancyex{Multiplikation des Kronecker-Produkts mit Vektor} Wenn man $A \otimes B \cdot x$ berechnet, so ist die Laufzeit $\tco{m \times n \times l \times k}$, aber wenn wir den Vektor $x$ in $n$ gleich grosse Blöcke aufteilen (was man je nach gewünschter nachfolgender Operation in NumPy in $\tco{1}$ machen kann mit \verb|x.reshape(n, x.shape[0] / n)|), dann ist es möglich das Ganze in $\tco{m \cdot l \cdot k}$ zu berechnen.
|
\fancyex{Multiplikation des Kronecker-Produkts mit Vektor} Wenn man $A \otimes B \cdot x$ berechnet, so ist die Laufzeit $\tco{m \times n \times l \times k}$, aber wenn wir den Vektor $x$ in $n$ gleich grosse Blöcke aufteilen (was man je nach gewünschter nachfolgender Operation in NumPy in $\tco{1}$ machen kann mit \verb|x.reshape(n, x.shape[0] / n)|), dann ist es möglich das Ganze in $\tco{m \cdot l \cdot k}$ zu berechnen.
|
||||||
|
|
||||||
Die vollständige Implementation ist auch hier nicht schwer und sieht folgendermassen aus:
|
Die vollständige Implementation ist auch hier nicht schwer und sieht folgendermassen aus:
|
||||||
\begin{minted}{python}
|
\begin{code}{python}
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
def fast_kron_vector_product(A: np.ndarray, B: np.ndarray, x: np.ndarray):
|
def fast_kron_vector_product(A: np.ndarray, B: np.ndarray, x: np.ndarray):
|
||||||
@@ -101,6 +101,6 @@ def fast_kron_vector_product(A: np.ndarray, B: np.ndarray, x: np.ndarray):
|
|||||||
bx = B * x.reshape(A.shape[0], round(x.shape[0] / A.shape[0]))
|
bx = B * x.reshape(A.shape[0], round(x.shape[0] / A.shape[0]))
|
||||||
# Then multiply a with the resulting vector
|
# Then multiply a with the resulting vector
|
||||||
y = A * bx
|
y = A * bx
|
||||||
\end{minted}
|
\end{code}
|
||||||
|
|
||||||
Um die oben erwähnte Laufzeit zu erreichen muss erst ein neuer Vektor berechnet werden, oben im Code \verb|bx| genannt, der eine Multiplikation von \verb|Bx_i| als Einträge hat.
|
Um die oben erwähnte Laufzeit zu erreichen muss erst ein neuer Vektor berechnet werden, oben im Code \verb|bx| genannt, der eine Multiplikation von \verb|Bx_i| als Einträge hat.
|
||||||
|
|||||||
@@ -1,2 +0,0 @@
|
|||||||
\subsection{Baryzentrische Formel}
|
|
||||||
Session: Gemäss TA sehr gut beschrieben im alten Script
|
|
||||||
@@ -0,0 +1,97 @@
|
|||||||
|
\newsection
|
||||||
|
\subsection{Lagrange- und Baryzentrische Interpolationsformeln}
|
||||||
|
Session: Gemäss TA sehr gut beschrieben im alten Script
|
||||||
|
|
||||||
|
\begin{definition}[]{Lagrange Polynome}
|
||||||
|
Für Knoten (auch gennannt Stützstellen) $x_0, x_1, \ldots, x_n \in \R$ definieren wir die Lagrange-Polynome:
|
||||||
|
\begin{align*}
|
||||||
|
l_i(x) = \prod_{j = 0 \neq i}^n \frac{x - x_j}{x_i - x_j}
|
||||||
|
\end{align*}
|
||||||
|
\end{definition}
|
||||||
|
Falls $j = i$ im Produkt, so überspringt $j$ diese Zahl.
|
||||||
|
|
||||||
|
\inlineex Seien $x_0, x_1, x_2$ die Stützstellen für die Lagrange-Polynome (mit $n = 2$):
|
||||||
|
\begin{align*}
|
||||||
|
l_0(x) & = \frac{x - x_1}{x_0 - x_1} \cdot \frac{x - x_2}{x_0 - x_2} &
|
||||||
|
l_1(x) & = \frac{x - x_0}{x_1 - x_0} \cdot \frac{x - x_2}{x_1 - x_2} &
|
||||||
|
l_2(x) & = \frac{x - x_0}{x_2 - x_0} \cdot \frac{x - x_1}{x_2 - x_1}
|
||||||
|
\end{align*}
|
||||||
|
|
||||||
|
|
||||||
|
\begin{theorem}[]{Lagrange-Interpolationsformel}
|
||||||
|
Die Lagrange-Polynome $l_i$ zu den Stützstellen $(x_0, y_0), \ldots, (x_n, y_n)$ bilden eine Basis der Polynome $\mathcal{P}_n$ und es gilt:
|
||||||
|
\begin{align*}
|
||||||
|
p(x) = \sum_{i = 0}^{n} y_i l_i(x) \text{ mit } l_i(x) = \prod_{j \neq i} \frac{x - x_j}{x_i - x_j}
|
||||||
|
\end{align*}
|
||||||
|
\end{theorem}
|
||||||
|
|
||||||
|
|
||||||
|
\fancyremark{Eigenschaften der Lagrange-Polynome}
|
||||||
|
\rmvspace
|
||||||
|
\begin{multicols}{2}
|
||||||
|
\begin{enumerate}
|
||||||
|
\item $l_i(x_j) = 0 \smallhspace \forall j \neq i$
|
||||||
|
\item $l_i(x_i) = 1 \smallhspace \forall i$
|
||||||
|
\item $\deg(l_i) = n \smallhspace \forall i$
|
||||||
|
\item $\sum_{k = 0}^{n} l_k(x) = 1 \text{ und } \sum_{k = 0}^{n} l_k^{(m)}(x) = 0 \text{ für } m > 0$
|
||||||
|
\end{enumerate}
|
||||||
|
\end{multicols}
|
||||||
|
|
||||||
|
Da eine Implementation, welche direkt auf den Lagrange-Polynomen basiert, eine Laufzeit von $\tco{n^3}$ hätte, suchte man nach einer besseren Methode.
|
||||||
|
Mit der \bi{baryzentrischen Interpolationsformel} wird zuerst ein Pre-Computing auf Teilen der Lagrange-Polynome durchgeführt, was dann dazu führt, dass die Laufzeit auf $\tco{n^2}$ sinkt ($\tco{n}$ für die Auswertung der Formel und $\tco{n^2}$ für die Berechnung der $\lambda_k$):
|
||||||
|
|
||||||
|
\setcounter{numberingConfig}{0}
|
||||||
|
\begin{formula}[]{Baryzentrische Interpolationsformel}
|
||||||
|
\vspace{-1.5pc}
|
||||||
|
\begin{align*}
|
||||||
|
p(x) = \frac{\displaystyle \sum_{k = 0}^{n} \frac{\lambda_k}{x - x_k} y_k}{\displaystyle \sum_{k = 0}^{n} \frac{\lambda_k}{x - x_k}}
|
||||||
|
\end{align*}
|
||||||
|
\end{formula}
|
||||||
|
\setcounter{numberingConfig}{3}
|
||||||
|
|
||||||
|
Falls wir die Stützstellen als $(n + 1)$ Chebyshev-Abszissen $\displaystyle x_k = \cos\left( \frac{k\pi}{n} \right)$ wählen,
|
||||||
|
so sind alle $\lambda_k$ gegeben durch $\lambda_k = (-1)^k \delta_k$ mit $\delta_0 = \delta_n = 0.5$ und $\delta_i = 1$.
|
||||||
|
|
||||||
|
Mit anderen $\lambda_k$ eröffnet die baryzentrische Formel einen Weg zur Verallgemeinerung der Interpolation mittels rationaler Funktionen und ist entsprechend kein Polynom mehr.
|
||||||
|
|
||||||
|
Eine weitere Anwendung der Formel ist als Ausganspunkt für die Spektralmethode für Differenzialgleichungen.
|
||||||
|
|
||||||
|
|
||||||
|
% ────────────────────────────────────────────────────────────────────
|
||||||
|
\newpage
|
||||||
|
\subsubsection{Fehler}
|
||||||
|
Falls an den Stützstellen $x_i$ durch beispielsweise ungenaue Messungen unpräzise Werte $\tilde{y_i}$ haben, so entsteht logischerweise auch ein unpräzises Polynom $\tilde{p}(x)$.
|
||||||
|
Verglichen in der Lagrange-Basis zum korrekten Interpolationspolynom $p(x)$ ergibt sich folgender Fehler:
|
||||||
|
\begin{align*}
|
||||||
|
|p(x) - \tilde{p}(x)| = \left| \sum_{i = 0}^{n} (y_i - \tilde{y_i}) l_i(x) \right| \leq \max_{i = 0, \ldots, n} |y_i - \tilde{y_i}| \cdot \sum_{i = 0}^{n} |l_i(x)|
|
||||||
|
\end{align*}
|
||||||
|
|
||||||
|
|
||||||
|
\fancydef{Lebesgue-Konstante} Zu den Stützstellen $x_0, \ldots, x_n$ im Intervall $[a, b]$ ist sie definiert durch
|
||||||
|
\rmvspace
|
||||||
|
\begin{align*}
|
||||||
|
\Lambda_n = \max_{x \in [a, b]} \sum_{i = 0}^{n} |l_i(x)|
|
||||||
|
\end{align*}
|
||||||
|
|
||||||
|
|
||||||
|
\stepcounter{all}
|
||||||
|
\fancytheorem{Auswirkung von Messfehlern} Es gilt (wenn $\Lambda_n$ die beste Lebesgue-Konstante für die Ungleichung ist):
|
||||||
|
\rmvspace
|
||||||
|
\begin{align*}
|
||||||
|
\max_{x \in [a, b]} |p(x) - \tilde{p}(x)| \leq \Lambda_n \max_{i = 0, \ldots, n} |y_i - \tilde{y_i}|
|
||||||
|
\end{align*}
|
||||||
|
|
||||||
|
\begin{theorem}[]{Fehler}
|
||||||
|
Sei $f : [a, b] \rightarrow \R$ und $p$ das Interpolationspolynom zu $f$. Seien $x_0, \ldots, x_n$ die Stützstellen, dann gilt:
|
||||||
|
\rmvspace
|
||||||
|
\begin{align*}
|
||||||
|
||f(x) - p(x)||_{\infty} = \max_{x \in [a, b]}|f(x) - p(x)| \leq (1 + \Lambda_n) \min_{q \in \mathcal{P}_n} \max_{x \in [a, b]} |f(x) - q(x)|
|
||||||
|
\end{align*}
|
||||||
|
\end{theorem}
|
||||||
|
|
||||||
|
\stepcounter{all}
|
||||||
|
\inlineremark Für gleichmässig auf $I$ verteilte Stützstellen gilt $\displaystyle \Lambda_n \approx \frac{2^{n + 1}}{e n \log(n)}$
|
||||||
|
|
||||||
|
\shade{gray}{Wichtig:} \bi{Niemals gleichmässig verteilte Stützstellen verwenden für die Interpolation von Polynomen hohen Grades}
|
||||||
|
|
||||||
|
Präzisere Interpolationen lassen sich beispielsweise durch Unterteilen des Intervalls in kleinere Intervalle finden, indem man für jedes Intervall ein separates Polynom berechnet, oder indem eine ideale Verteilung der Stützstellen wählt (was wiederum nicht einfach zu erzielen ist, siehe nächstes Kapitel).
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
\newsection
|
||||||
\subsection{Chebychev Interpolation}
|
\subsection{Chebychev Interpolation}
|
||||||
|
|
||||||
Session: Chebyshev Pol. : Abzisse = Extrema, Knoten = Nullstellen
|
Session: Chebyshev Pol. : Abzisse = Extrema, Knoten = Nullstellen
|
||||||
|
|||||||
Reference in New Issue
Block a user