[NumCS] Add new innumpy command, start splines section

This commit is contained in:
2025-10-14 14:48:05 +02:00
parent 1b36e0942d
commit 07ec52eb74
9 changed files with 27 additions and 7 deletions

Binary file not shown.

View File

@@ -13,6 +13,7 @@
\setLang{de}
\setup{Numerical Methods for Computer Science}
\newcommand{\innumpy}{\fhlc{Cyan}{In \texttt{numpy}}\smallhspace}
\begin{document}
\startDocument

View File

@@ -6,7 +6,7 @@
\subsection{Rechnen mit Matrizen}
Wie in Lineare Algebra besprochen, ist das Resultat der Multiplikation einer Matrix $A \in \C^{m \times n}$ und einer Matrix $B \in \C^{n \times p}$ ist eine Matrix $AB = \in \C^{m \times p}$
\fhlc{Cyan}{In NumPy} haben wir folgende Funktionen:
\innumpy haben wir folgende Funktionen:
\begin{itemize}
\item \verb|b @ a| (oder \verb|np.dot(b, a)| oder \verb|np.einsum('i,i', b, a)| für das Skalarprodukt
\item \verb|A @ B| (oder \verb|np.einsum('ik,kj->ij', )|) für das Matrixprodukt
@@ -59,7 +59,7 @@ Sei $A = ab^\top$. Dann gilt $y = Ax \Leftrightarrow y = a(b^\top x)$, was dasse
\inlineex Für zwei Matrizen $A, B \in \R^{n \times p}$ mit geringem Rang $p \ll n$, dann kann mithilfe eines Tricks die Rechenzeit von \verb|np.triu(A @ B.T) @ x| von $\tco{pn^2}$ auf $\tco{pn}$ reduziert werden.
Die hier beschriebene Operation berechnet $\text{Upper}(AB^\top) x$ wobei $\text{Upper}(X)$ das obere Dreieck der Matrix $X$ zurück gibt.
Wir nennen diese Matrix hier $R$.
Wir können in NumPy den folgenden Ansatz verwenden, um die Laufzeit zu verringern:
\innumpy können wir den folgenden Ansatz verwenden, um die Laufzeit zu verringern:
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.
Die vollständige Implementation sieht so aus:
@@ -80,7 +80,9 @@ Die vollständige Implementation sieht so aus:
\setcounter{all}{21}
\fancydef{Kronecker-Produkt} Das Kronecker-Produkt ist eine $(ml) \times (nk)$-Matrix, für $A \in \R^{m \times n}$ und $B \in \R^{l \times k}$, die wir in NumPy einfach mit \verb|np.kron(A, B)| berechnen können (ist jedoch nicht immer ideal):
\fancydef{Kronecker-Produkt} Das Kronecker-Produkt ist eine $(ml) \times (nk)$-Matrix, für $A \in \R^{m \times n}$ und $B \in \R^{l \times k}$.
\innumpy können wir dieses einfach mit \verb|np.kron(A, B)| berechnen (ist jedoch nicht immer ideal):
\begin{align*}
A \otimes B :=
\begin{bmatrix}

View File

@@ -36,4 +36,4 @@ Zur Auswertung von $p(x)$ kann man direkt die Matrix-darstellung nutzen, oder ef
\fancydef{Horner Schema} $p(x) = (x \ldots x ( x (\alpha_n x + \alpha_{n-1}) + \ldots + \alpha_1) + \alpha_0)$
\fhlc{Cyan}{In NumPy} \verb|polyfit| liefert die direkte Auswertung, \verb|polyval| wertet Polynome via Horner-Schema aus. (Gemäss Script, in der Praxis sind diese Funktionen \verb|deprecated|)
\innumpy liefert \verb|polyfit| die direkte Auswertung, \verb|polyval| wertet Polynome via Horner-Schema aus. (Gemäss Script, in der Praxis sind diese Funktionen \verb|deprecated|)

View File

@@ -38,5 +38,5 @@ Wir formen die Fourier-Transformation um für den ersten Fall ($N = 2m$):
Der zweite Fall ist einfach eine rekursive Weiterführung des ersten Falls,
bei welchem dann das $m$ kontinuierlich weiter dividiert wird bis zum Trivialfall mit einer $1 \times 1$-Matrix.
\fhlc{Cyan}{In NumPy} gibt es die Funktionen \texttt{np.fft.fft} (Vorwärts FFT), \texttt{np.fft.ifft} (Rückwärts FFT).
\innumpy gibt es die Funktionen \texttt{np.fft.fft} (Vorwärts FFT), \texttt{np.fft.ifft} (Rückwärts FFT).
\texttt{scipy.fft} liefert dieselben Funktionen und sie sind oft etwas schneller als die von \texttt{numpy}

View File

@@ -43,7 +43,7 @@ Auf Seite 102 im Skript findet sich auch eine effiziente Implementation dessen.
\inlineremark Die Formel in Satz 2.4.16 (und in der eben erwähnten Implementierung) sind nichts anderes als eine Version der DCT (Discrete Cosine Transform).
Dies ist eine günstigere, aber beschränktere Variante der DFT, mit der nur reellwertige, gerade Funktionen interpoliert werden können.
\fhlc{Cyan}{In NumPy} benutzen wir \texttt{scipy.fft.dct}. Dazu müssen die Mesungen in den Punkten $x_j = \cos\left( (j + 0.5) \cdot \frac{\pi}{N} \right)$
\innumpy benutzen wir \texttt{scipy.fft.dct}. Dazu müssen die Mesungen in den Punkten $x_j = \cos\left( (j + 0.5) \cdot \frac{\pi}{N} \right)$
\inlineremark Die Chebyshev-Koeffizienten $c_j$ können folgendermassen berechnet werden:
\rmvspace

View File

@@ -1,4 +1,5 @@
% Lecture: \chi here are used as RELU function!
\subsection{Stückweise Lineare Interpolation}
Globale Interpolation (also Interpolation auf dem ganzen Intervall $]-\infty, \infty[$) funktioniert nur dann gut, wenn:
\rmvspace
\begin{enumerate}[label=(\alph*), noitemsep]

View File

@@ -18,7 +18,7 @@ und deren Ableitung $\psi'(t) = t(3t - 2)$. Mit demselben Variablenwechsel müss
\end{align*}
Die Interpolationsfunktion ist dann einfach die Summe $s_j(x) = p_j(x) + q_j(x) \mediumhspace \text{für } x \in [x_{j - 1}, x_j]$
\fhlc{Cyan}{In Numpy} verwendet man \texttt{scipy.interpolate.Akima1DInterpolator} oder \texttt{PchipInterpolator}, welcher ``formerhaltender'' ist,
\innumpy verwendet man \texttt{scipy.interpolate.Akima1DInterpolator} oder \texttt{PchipInterpolator}, welcher ``formerhaltender'' ist,
also wenn eine Funktion lokal monoton ist, so ist der Interpolant dort auch monoton.
Bei anderen Interpolationsmethoden ist dies nicht garantiert (so auch nicht beim \texttt{Akima1DInterpolator})

View File

@@ -0,0 +1,16 @@
\newsectionNoPB
\subsection{Splines}
\begin{definition}[]{Raum der Splines}
Sei $[a, b] \subseteq \R$ ein Intervall, sei $\mathcal{G} = \{ a = x_0 < x_1 < \ldots < x_N = b \}$ und sei $d \geq 1 \in \N$.
Die Menge
\begin{align*}
\mathcal{S}_{d, \mathcal{G}} = \{ s \in C^{d - 1}[a, b], \smallhspace s_j := s_{|[x_{j - 1}, x_j]|} \text{ ist ein polynom von Grad höchstens } d \}
\end{align*}
ist die Menge aller auf $[a, b]$ $(d - 1)$ mal stetig ableitbaren Funktionen, die auf $\mathcal{G}$ aus stückweisen Polynomen von Grad höchtens $d$ bestehen
und wir der Raum der Splines vom Grad $d$, oder der Ordnung $(d + 1)$ genannt
\end{definition}
\inlineremark Obige Definition ist undefiniert für $d = 0$, aber $\mathcal{S}_{d, \mathcal{G}}$ kann als die Menge der stückweise Konstanten Funktionen betrachtet werden.
Im Vergleich zu den Kubischen Hermite-Interpolanten sind die Kubischen-Splines (für $d = 3$) \textit{zweimal} Ableitbar statt nur \textit{einmal}
\inlineremark $\dim(\mathcal{S}_{d, \mathcal{G}}) = N + d$. Es werden oft kubische Splines in Anwendungen verwendet