Skip to content

Commit 3db4a60

Browse files
committed
document mathematics of dense LU factorization
Signed-off-by: Martijn Govers <Martijn.Govers@Alliander.com>
1 parent 3a83315 commit 3db4a60

File tree

1 file changed

+123
-5
lines changed

1 file changed

+123
-5
lines changed

docs/advanced_documentation/algorithms/lu-solver.md

Lines changed: 123 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,16 @@ candidate.
5151
#### Pivot operations
5252

5353
Pivoting of blocks is expensive, both computationally and memory-wise, as it interferes with the
54-
sparse block structure of the matrix equations. To this end, a pre-fixed permutation can be chosen
55-
to avoid bock pivoting at a later stage.
54+
sparse block structure of the matrix equations by introducing new potentially non-zero elements,
55+
called _fill-ins_, during the process of Gaussian elimination. To this end, a pre-fixed permutation
56+
can be chosen to avoid bock pivoting at a later stage.
5657

5758
The [topological structure](#topological-structure) of the grid does not change during the
5859
solving phase, so the permutation can be obtained by the minimum degree algorithm from just the
59-
topology alone, at the cost of potential [ill-conditioned pivot elements](#pivot-perturbation).
60+
topology alone, which seeks to minimize the amount of fill-ins. Note that even if a matrix block
61+
is topologically relevant does not imply that it is always non-zero. This may result in potentially
62+
[ill-conditioned pivot elements](#pivot-perturbation), which will be discussed in a different
63+
section.
6064

6165
### Power system equation properties
6266

@@ -112,6 +116,46 @@ The power grid model uses a modified version of the
112116
(credits go to the original author). The modification adds opt-in support for
113117
[pivot perturbation](#pivot-perturbation).
114118

119+
#### Dense LU factorization process
120+
121+
The Gaussian elimination process itself is as usual. Let
122+
$M_p\equiv\begin{bmatrix}m_p && \vec{r}_p^T \\ \vec{q}_p && \hat{M}_p\end{bmatrix}$, where $p$ is
123+
the current pivot element at the top left of the matrix, $\vec{q}$ and $\vec{r}_p^T$ are the
124+
associated column and row vectors containing the rest of the pivot column and row and $\hat{M}_p$ is
125+
the bottom-right block of the matrix. Gaussian elimination constructs the matrices
126+
127+
$$
128+
\begin{align*}
129+
L_p &= \begin{bmatrix} 1 && \vec{0}^T \\ m_p^{-1} \vec{q}_p && \hat{D}_p\end{bmatrix}
130+
Q_p &= \begin{bmatrix} m_p && \vec{r}_p^T \\ \vec{0} && \hat{M}_p - m_p^{-1} \vec{q}_p \vec{r}_p^T\end{bmatrix} \equiv \begin{bmatrix} 1 && \tilde{\vec{r}}_p^T \\ \vec{0} && M_{p+1} \end{bmatrix}
131+
\end{align*}
132+
$$
133+
134+
where $\hat{D}$ is the matrix with ones on the diagonal and zeros as off-diagonal elements.
135+
136+
Iterating this process yields the matrices
137+
138+
$$
139+
\begin{align*}
140+
L = L_0 L_1 \cdots L_{N-1} &= \begin{bmatrix}
141+
1 && 0 && \cdots \\
142+
m_0^{-1} \vec{q}_0 && 1 && \ddots \\
143+
&& m_1^{-1} \vec{q}_1 && \ddots \\
144+
&& && \ddots
145+
\end{bmatrix} \\
146+
Q = Q_0 Q_1 \cdots Q_{N-1} &= \begin{bmatrix}
147+
m_0 && \vec{r}_0^T && && \\
148+
0 && m_1 && \vec{r}_1^T && \\
149+
\vdots && \ddots && \ddots && \ddots
150+
\end{bmatrix}
151+
\end{align*}
152+
$$
153+
154+
The process described in the above assumes no pivot permutations were necessary. If permutations
155+
are required, they are kept track of in a separate permution matrix, so that $A = LUP$.
156+
157+
#### Dense LU factorization algorithm
158+
115159
Let $M\equiv M\left[0:N, 0:N\right]$ be the $N\times N$-matrix and $M\left[i,j\right]$ its element
116160
at (0-based) indices $(i,j)$, where $i,j = 0..(N-1)$.
117161

@@ -144,9 +188,82 @@ the `SparseMatrixError` immediately, we break from the loop and throw after that
144188
change the functional behavior.
145189
```
146190

147-
### Block-sparse LU decomposition
191+
### Block-sparse LU factorization
192+
193+
The LU factorization process for block-sparse matrices is similar to that for dense matrices.
194+
195+
#### Block-sparse indices
196+
197+
The structure of the block-sparse matrices is as follows.
198+
199+
* The $N\times N$ block matrix $M$ is interpreted as $M\equiv M\left[0:N, 0:N\right]$, with
200+
$M\left[i,j\right]$ its block element at (0-based) indices $(i,j)$, where $i,j = 0..(N-1)$.
201+
* In turn, let $M[i,j] \equiv M_{i,j}\left[0:N_{i,j},0:N_{i,j}\right]$ be the dense block with
202+
dimensions $N_i\times N_j$.
203+
204+
This can be graphically represented as
205+
206+
$$
207+
\begin{align*}
208+
M &\equiv \begin{pmatrix}
209+
M_{0,0} && \cdots && M_{0,N-1} \\
210+
\vdots && \ddots && \vdots \\
211+
M_{N-1,0} && \cdots && M_{N-1,N-1}
212+
\end{pmatrix} \\
213+
&\equiv \begin{pmatrix}
214+
\begin{pmatrix}
215+
M_{0,0}\left[0,0\right] && \cdots && M_{0,0}\left[0,N_j-1\right] \\
216+
\vdots && \ddots && \vdots \\
217+
M_{0,0}\left[N_i-1,0\right] && \cdots && M_{0,0}\left[N_i-1,N_j-1\right]
218+
\end{pmatrix} && \cdots && \begin{pmatrix}
219+
M_{0,N-1}\left[0,0\right] && \cdots && M_{0,N-1}\left[0,N_j-1\right] \\
220+
\vdots && \ddots && \vdots \\
221+
M_{0,N-1}\left[N_i-1,0\right] && \cdots && M_{0,N-1}\left[N_i-1,N_j-1\right] \end{pmatrix} \\
222+
\vdots && \ddots && \vdots \\
223+
\begin{pmatrix}
224+
M_{N-1,0}\left[0,0\right] && \cdots && M_{N-1,0}\left[0,N_j-1\right] \\
225+
\vdots && \ddots && \vdots \\
226+
M_{N-1,0}\left[N_i-1,0\right] && \cdots && M_{N-1,0}\left[N_i-1,N_j-1\right]
227+
\end{pmatrix} && \cdots && \begin{pmatrix}
228+
M_{N-1,N-1}\left[0,0\right] && \cdots && M_{N-1,N-1}\left[0,N_j-1\right] \\
229+
\vdots && \ddots && \vdots \\
230+
M_{N-1,N-1}\left[N_i-1,0\right] && \cdots && M_{N-1,N-1}\left[N_i-1,N_j-1\right] \end{pmatrix}
231+
\end{pmatrix}
232+
\end{align*}
233+
$$
234+
235+
Because of the sparse structure and the fact that all $M_{i,j}$ have the same shape, it is much more
236+
efficient to store the blocks $M_{i,j}$ in a vector $M_{\tilde{k}}$ where $\tilde{k}$ is a reordered
237+
index from $(i,j) \mapsto \tilde{k}$. This mapping, in turn, is stored as an index pointer, i.e., a
238+
vector of vectors of indices, with the outer index given by the row-index $i$, and the inner vector
239+
containing the values of $j$ for which $M_{i,j}$ may be non-zero. All topologically relevant matrix
240+
elements, as well as [fill-ins](#pivot-operations), are included in this mapping. The following
241+
illustrates this mapping.
242+
243+
$$
244+
\begin{align*}
245+
\begin{pmatrix}
246+
M_{0,0} && && && M_{0,3} \\
247+
&& M_{1,1} && M_{1,2} && \\
248+
&& M_{2,1} && M_{2,2} && M_{2,3} \\
249+
M_{3,0} && && M_{3,2} && M_{3,3}
250+
\end{pmatrix} &\equiv
251+
\begin{bmatrix}
252+
M_{0,0} && M_{0,3} && M_{1,1} && M_{1,2} && M_{2,1} && M_{2,2} && M_{2,3} && M_{3,0} && M_{3,2} && M_{3,3} && \\
253+
[[0 && 3] && [1 && 2] && [1 && 2 && 3] && [0 && 2 && 3]] && \\
254+
[0 && && 2 && && 4 && && 7 && && 10]
255+
\end{bmatrix}
256+
\end{align*}
257+
$$
258+
259+
In the right-hand side, the upper row contains the present block entries and the bottom row their
260+
column indices. The row indices are implied by the index of the inner vector in the outer one.
261+
262+
Looping over the rows and columns becomes trivial. Let $\text{indptr}$ be the nested list of column
263+
indices. The double loop becomes:
148264

149-
TODO
265+
1. Loop all rows: $i=0..(N-1)$:
266+
1. The list of indices for this row is
150267

151268
### Pivot perturbation
152269

@@ -346,6 +463,7 @@ The algorithm is as follows:
346463
Let $M\equiv M\left[0:N, 0:N\right]$ be the $N\times N$-matrix with a block-sparse structure and
347464
$M\left[i,j\right]$ its block element at (0-based) indices $(i,j)$, where $i,j = 0..(N-1)$. In turn,
348465
let $M[i,j] \equiv M_{i,j}\left[0:N_{i,j},0:N_{i,j}\right]$ be the dense block with dimensions
466+
$N_i\times N_j$.
349467

350468
1. Set $\text{norm} \gets 0$.
351469
2. Loop over all block-rows: $i = 0..(N-1)$:

0 commit comments

Comments
 (0)