[NumCS] Chapter 2.3 done

This commit is contained in:
2025-09-30 16:04:57 +02:00
parent 19b2186cff
commit defc886090
6 changed files with 123 additions and 17 deletions

View File

@@ -59,22 +59,22 @@ 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.
Das \verb|[::-1]| dient hier lediglich dazu, den Vektor $x$ umzudrehen, sodass das richtige Resultat entsteht.
Die vollständige Implementation sieht so aus:
\begin{minted}{python}
import numpy as np
\begin{code}{python}
import numpy as np
def low_rank_matrix_vector_product(A: np.ndarray, B: np.ndarray, x: np.ndarray):
n, _ = A.shape
y = np.zeros(n)
def low_rank_matrix_vector_product(A: np.ndarray, B: np.ndarray, x: np.ndarray):
n, _ = A.shape
y = np.zeros(n)
# Compute B * x with broadcasting (x needs to be reshaped to 2D)
v = B * x[:, None]
# Compute B * x with broadcasting (x needs to be reshaped to 2D)
v = B * x[:, None]
# s is defined as the reverse cummulative sum of our vector
# (and we need it reversed again for the final calculation to be correct)
s = np.cumsum(v[::-1], axis=0)[::-1]
# s is defined as the reverse cummulative sum of our vector
# (and we need it reversed again for the final calculation to be correct)
s = np.cumsum(v[::-1], axis=0)[::-1]
y = np.sum(A * s)
\end{minted}
y = np.sum(A * s)
\end{code}
\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.
Die vollständige Implementation ist auch hier nicht schwer und sieht folgendermassen aus:
\begin{minted}{python}
\begin{code}{python}
import numpy as np
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]))
# Then multiply a with the resulting vector
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.