diff --git a/semester3/numcs/numcs-summary.pdf b/semester3/numcs/numcs-summary.pdf index a6d246b..f5ff69d 100644 Binary files a/semester3/numcs/numcs-summary.pdf and b/semester3/numcs/numcs-summary.pdf differ diff --git a/semester3/numcs/parts/01_interpolation/00_polynomial/04_chebyshev-interpolation.tex b/semester3/numcs/parts/01_interpolation/00_polynomial/04_chebyshev-interpolation.tex index 3816618..8b47fb1 100644 --- a/semester3/numcs/parts/01_interpolation/00_polynomial/04_chebyshev-interpolation.tex +++ b/semester3/numcs/parts/01_interpolation/00_polynomial/04_chebyshev-interpolation.tex @@ -131,13 +131,39 @@ Für $n \geq 15$ berechnet man $c_k$ mit der Schnellen Fourier Transformation (F \fancytheorem{Clenshaw-Algorithmus} Seien $d_{n + 2} = d_{n + 1} = 0$. Sei $d_k = c_k + (2x)d_{k + 1} - d_{k + 2} \text{ für } k = n, \ldots, 0$\\ -Dann gilt: $p(x) = \frac{1}{2}(d_0 - d_2)$ und man kann $p(x)$ mit Hilfe einer Rückwärtsrekursion berechnen +Dann gilt: $p(x) = \frac{1}{2}(d_0 - d_2)$ und man kann das Interpolationspolynom $p(x)$ mit Hilfe einer Rückwärtsrekursion berechnen Der Clenshaw-Algorithmus ist sehr stabil, auch wenn er mit (oft) unstabilen Rekursionen implementiert ist. +Auf der nächsten Seite findet sich eine saubere, effiziente Implementation des Clenshaw-Algorithmus: + +\newpage +\begin{code}{python} + def clenshaw(coeffs: np.ndarray, x: np.ndarray): + n = len(coeffs) - 1 + # initialise temporary variables + d_prev_prev, d_prev, d_curr = ( + np.zeros_like(x), + np.zeros_like(x), + np.zeros_like(x), + ) + + for k in range(n, -1, -1): # backward recursion + d_curr = coeffs[k] + 2 * x * d_prev - d_prev_prev + d_prev_prev, d_prev = d_prev, d_curr + + return d_prev - x * d_prev_prev +\end{code} -% ──────────────────────────────────────────────────────────────────── -\subsection{DFT und Chebyshev-Interpolation} -Der folgende Abschnitt wurde ausgelassen, da dieser (noch) nicht während den Vorlesungen behandelt wurde. -Er behandelt primär die Implementation der Chebyshev-Interpolation. +\innumpy kann man mit \texttt{np.polynomial.chebyshev.chebfit} ein polyfit für Chebyshev-Polynome durchführen und mit \texttt{np.polynomial.chebyshev.chebder} +die Ableitungen der Approximation berechnen. Die \texttt{chebder}-Funktion nimmt die normalen Chebyshev-Koeffizienten als Argument, die man einfach mit folgendem Code berechnen kann: +\begin{code}{python} + def get_cheb_coeffs(abscissa: np.ndarray) + n = len(abscissa) - 1 + dct_vals = scipy.fft.dct(abscissa, type=1) + + coeffs = dct_vals / n + coeffs[0] /= 2 + self.coeffs = coeffs +\end{code} diff --git a/semester3/numcs/parts/01_interpolation/01_trigonometric/05_dft-chebyshev.tex b/semester3/numcs/parts/01_interpolation/01_trigonometric/05_dft-chebyshev.tex index 29f5afb..1974c3b 100644 --- a/semester3/numcs/parts/01_interpolation/01_trigonometric/05_dft-chebyshev.tex +++ b/semester3/numcs/parts/01_interpolation/01_trigonometric/05_dft-chebyshev.tex @@ -1,6 +1,6 @@ \newsection \subsection{DFT und Chebyshev-Interpolation} -Mithilfe der DFT können günstig und einfach die Chebyshev-Koeffizienten berechnet werden. +Mithilfe der DFT können günstig und einfach die Chebyshev-Koeffizienten ($c_k$) berechnet werden. Die Idee basiert auf dem Satz 2.4.16, durch welchen schon schnell klar wird, dass es eine Verbindung zwischen den Fourier-Koeffizienten und Chebyshev-Koeffizienten gibt. Die Chebyshev-Knoten sind folgendermassen definiert: