% TODO: Make all [H] -> [t]
\chapter{Decoding under Detector Error Models}

In \Cref{ch:Fundamentals} we introduced the fundamentals of classical
error correction, before moving on to quantum information science and
finally combining the two in \acf{qec}.
In \Cref{ch:Fault tolerance} we then turned to fault-tolerance, with
a focus on a specific way of implementing it, called \acfp{dem}.
In this chapter, we move on from the fundamental concepts and examine
how to apply them in practice.
Specifically, we concern ourselves with the practical aspects of decoding
under \acp{dem}.

We investigate decoding \acf{qldpc} codes under \acp{dem} in particular.
We focus on \ac{qldpc} codes, as they have emerged as leading
candidates for practical quantum error correction, offering the
ability to encode more logical qubits per physical qubit than surface
codes while maintaining favorable threshold properties
\cite[Sec.~1]{bravyi_high-threshold_2024}.
Because of this, the decoding algorithms we consider will all be
related to \acf{bp} in some way.
Our aim is to build a fault-tolerant \ac{qec} system that works well
even under consideration of circuit-level noise.
We must overcome two main challenges to achieve this.

First, recall the problems related to degeneracy, which is inherent
to quantum codes.
Because multiple minimum-weight codewords exist, the \ac{bp}
algorithm becomes uncertain of the direction to proceed in.
Additionally, the commutativity conditions of the stabilizers
necessitate the existence of short cycles.
These two aspects together lead to substantial convergence problems
of \ac{bp} for quantum codes, when it is used on it's own.

Second, the consideration of circuit-level noise introduces many more
error locations into the circuit.
Using \acp{dem}, we construct a new circuit code and model each of
these error locations as a new \acf{vn}.
We also perform multiple rounds of syndrome measuremetns,
exacerbating the problem.
This leads to a massively increased computational complexity and
latency of the decoding process.
In our experiments using the $\llbracket 144,12,12 \rrbracket$
\acf{bb} code with $12$ syndrome measurement rounds, for example, the
number of \acp{vn} was increased from $144$ to $9504$, and the
number of \acfp{cn} was increased from $72$ to $1008$.

The first problem is not inherent to \acp{dem} or fault-tolerance,
but rather quantum codes in general.
Many different approaches to solving it exist, usually centered
around somehow modifying \ac{bp}.
The most popular approach is combining a few initial
iterations of \ac{bp} with a second decoding algorithm, \ac{osd}
\cite{roffe_decoding_2020}.
Other approaches exist, such as \ac{aed}
\cite{koutsioumpas_automorphism_2025}, were multiple variations of
the code are decoded simultaneously to increase the chances of convergence.
Here, we will focus on the \acf{bpgd} algorithm
\cite{yao_belief_2024} we already introduced in \Cref{ch:Fundamentals},
for reasons that will become clear later in the chapter.

The second problem is inherent to decoding using \acp{dem}.
This is an area that has been less studied.
As we saw in \Cref{sec:Quantum Error Correction}, for \ac{qec},
latency is the main constraint, not raw computational complexity.
The main way this is addressed in the literature is \emph{sliding
window decoding}, which attempts to divide the overall decoding
problem into many smaller ones that can be solved more efficiently.

% TODO: This could potentially be abit more text (e.g., go into
% SC-LDPC like structure that serves as the inspiration for the
% warm-start decoding. Or just go into warm-start decoding)
We will start by briefly reviewing the existing work related to
sliding-window decoding,
before focusing on one specific realization.
We will then introduce a modification to the existing algorithm and
perform numerical simulations to evaluate it.

% and reducing latency is the main goal of the existing literature.
% This is generally done using windowing approaches; either
% sliding-window based, where the latency is reduced due an earlier
% start to the decoding process \cite{kuo_fault-tolerant_2024}%
% \cite{huang_improved_2023}\cite{huang_increasing_2024}\cite{gong_toward_2024},
% or by decoding multiple windows in parallel
% \cite{skoric_parallel_2023}\cite{tan_scalable_2023}.
% This work is based on the sliding-window method.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Sliding-Window Decoding}
\label{sec:Sliding-Window Decoding}

% Spacetime codes

\ac{qec} codes are often viewed through the lenses of the
\emph{space} and \emph{time} dimensions.
Both directions add redundancy, but they do so in a different way and
guard against different defects.
The space dimension corresponds to the redundancy added through the
code itself, while the time dimension corresponds to the repetition
of the syndrome measurements \cite[Sec.~IV.B]{dennis_topological_2002}.

% Basic idea

The idea of sliding-window decoding is to exploit the time-like
structure by splitting the circuit into overlapping windows along the
time dimension.
Each of these windows is then decoded separately.

%%%%%%%%%%%%%%%%
\subsection{Review of Existing Literature}
\label{subsec:Review of Existing Literature}

\begin{figure}[t]
    \centering

    \tikzset{
        literature/.append style={
            minimum width=6mm,
            minimum height=6mm,
            text width=18mm,
            align=left,
        }
    }
    \tikzset{
        heading/.append style={
            draw=black,
            minimum width=22mm,
            minimum height=6mm,
            align=left,
            rounded corners = 1mm,
        }
    }

    \tikzexternaldisable
    \begin{tikzpicture}[node distance = 0mm and 0mm]
        % tex-fmt: off
        \node[heading, minimum width=15mm, fill=gray!25]                  (code)  {Code};
        \node[heading, below right=2mm and -5mm of code, fill=orange!20]  (top)   {Topological};
        \node[heading, below right=45mm and -5mm of code, fill=orange!20] (qldpc) {QLDPC};

        \node[literature, below right=1mm and -12mm of top] (dennis) {\cite{dennis_topological_2002}};
        \node[literature, below=of dennis]                  (tan)    {\cite{tan_scalable_2023}};
        \node[literature, below=of tan]                     (skoric) {\cite{skoric_parallel_2023}};
        \node[literature, below=of skoric]                  (bombin) {\cite{bombin_modular_2023}};
        \node[literature, below=of bombin]                  (kuo)    {\cite{kuo_fault-tolerant_2024}};

        \node[literature, below right=1mm and -12mm of qldpc] (huang) {\cite{huang_improved_2023},\cite{huang_increasing_2024}};
        \node[literature, below=of huang]                     (gong)  {\cite{gong_toward_2024}};
        \node[literature, below=of gong]                      (kang)  {\cite{kang_quits_2025}};

        \coordinate (code-anchor)  at ($(code.south) + (-2mm,0)$);
        \coordinate (top-anchor)   at ($(top.south) + (-5mm,0)$);
        \coordinate (qldpc-anchor) at ($(qldpc.south) + (-5mm,0)$);

        \draw (code-anchor) |- (top);
        \draw (code-anchor) |- (qldpc);

        \draw (top-anchor) |- (dennis);
        \draw (top-anchor) |- (tan);
        \draw (top-anchor) |- (skoric);
        \draw (top-anchor) |- (bombin);
        \draw (top-anchor) |- (kuo);

        \draw (qldpc-anchor) |- (huang);
        \draw (qldpc-anchor) |- (gong);
        \draw (qldpc-anchor) |- (kang);

        \draw [
            line width=1pt,
            decorate,
            decoration={brace,amplitude=2mm,raise=5mm}
        ]
        (dennis.north east) -- (dennis.south east)
        node[midway,right,xshift=10mm]{Sequential};

        \draw [
            line width=1pt,
            decorate,
            decoration={brace,amplitude=2mm,raise=5mm}
        ]
        (tan.north east) -- (kuo.south east)
        node[midway,right,xshift=10mm]{Parallel};

        \draw [
            line width=1pt,
            decorate,
            decoration={brace,amplitude=2mm,raise=5mm}
        ]
        (huang.north east) -- (kang.south east)
        node[midway,right,xshift=10mm]{Sequential};
        % tex-fmt: on
    \end{tikzpicture}
    \tikzexternalenable

    \caption{Overview of literature on sliding-window decoding.}
    \label{fig:literature}
\end{figure}

% Some general notes

\Cref{fig:literature} gives an overview over the existing body of work
related to sliding-window decoding.
The papers \cite{huang_improved_2023} and \cite{huang_increasing_2024} are
lumped together, as they share the same content;
one is simply preprint published earlier.
We will only refer to \cite{huang_increasing_2024} in the following.
\cite{kang_quits_2025} is somewhat special in that the authors focus
more on the introduction of a new simluator framework they call
QUITS, rather than the performance of sliding-window decoding itself.
\cite{gong_toward_2024} and \cite{kang_quits_2025} have made their
software freely available online%
\footnote{
    https://github.com/mkangquantum/quits
}%
\footnote{
    https://github.com/gongaa/SlidingWindowDecoder
}.
A final thing to note is that \cite{dennis_topological_2002} never
explicitly mention sliding windows, they call their scheme
``overlapping recovery''.

% Topological vs QLDPC

Research has focused on two categories of \ac{qec} codes, topological
and \ac{qldpc} codes.
Most of the work on topological codes has treated surface codes,
with the exception of \cite{kuo_fault-tolerant_2024} where toric
codes were considered.
With regard to \ac{qldpc} codes, in \cite{huang_increasing_2024}
they examine \emph{hypergraph product} (\acs{hgp}) and
\emph{lifted-product} (\acs{lp}) codes.
HGP codes are constructed from the product of two classical codes,
while LP codes generalize this construction by additionally applying
a lift to reduce the qubit overhead.
In \cite{kang_quits_2025}, \emph{balanced product codes} (\acs{bpc})
are additionally considered.
Like HGP codes, BPC codes are derived from a product construction,
but exploit an additional symmetry to yield fewer physical qubits for
the same code parameters.
Finally, in \cite{gong_toward_2024} the authors explore \ac{bb} codes.

% Sequential vs parallel

After having divided the whole circuit into separate windows, the question
arises of how exactly to realize the decoding.
There are two main approaches, with differing mechanisms of reducing
the latency.
Some papers decode the sliding windows in a parallel fashion.
The benefit in this case is the option to more effectively utilize
classical hardware for decoding.
Others choose a sequential approach.
Here, decoding can start earlier, as there is no need to wait for the
syndrome measurements of all windows before beginning with the decoding.
With the exception of \cite{dennis_topological_2002}, literature
treating topological codes has mostly focused on parallel decoding
while literature treating \ac{qldpc} codes has wholely considered
sequential decoding.

% Deep-dive into QLDPC methods

For this work, the publications treating \ac{qldpc} codes are
especially interesting.
The experimental conditions for these are summarized in
\Cref{table:experimental_conditions}.
As we noted above, \ac{hgp} and \ac{lp} codes are considered in
\cite{huang_increasing_2024},
\ac{hgp}, \ac{lp} and \ac{bpc} codes are considered in \cite{kang_quits_2025},
and \ac{bb} codes are considered in \cite{gong_toward_2024}.
The employed noise models also differ;
\cite{huang_increasing_2024} use phenomenological noise, while
\cite{gong_toward_2024} and \cite{kang_quits_2025} use circuit-level noise.
Finally, \cite{gong_toward_2024} introduce their own variation of
\ac{bpgd}, \ac{bp} with \ac{gdg}, while \cite{huang_increasing_2024}
and \cite{kang_quits_2025} use \ac{bp} + \ac{osd}.
We would additionally like to note that only in
\cite{gong_toward_2024} and \cite{kang_quits_2025} do the authors
explicitly work with the \ac{dem} formalism.

\renewcommand{\arraystretch}{1.1}
\setlength{\tabcolsep}{12pt}
\begin{table}[t]
    \centering
    \caption{Experimental conditions for papers related to \ac{qldpc} codes.}
    \vspace*{3mm}
    \label{table:experimental_conditions}
    \begin{tabular}{l|ccc}
        % tex-fmt: off
        Publication                                                            &    Code                       & Noise Model                     & Decoder \\ \hline
        \hspace{-2.5mm}\cite{huang_improved_2023},\cite{huang_increasing_2024} & \acs{hgp}, \acs{lp}           & Phenomenological noise & \acs{bp} + \acs{osd} \\
        \hspace{-2.5mm}\cite{gong_toward_2024}                                 & \acs{bb}                      & Circuit-level noise             & \acs{bp} + \acs{gdg} \\
        \hspace{-2.5mm}\cite{kang_quits_2025}                                  & \acs{hgp}, \acs{lp}, \acs{bpc}  & Circuit-level noise             & \acs{bp} + \ac{osd}
        % tex-fmt: on
    \end{tabular}
\end{table}

% \red{
%     Existing work
%     \begin{itemize}
%         \item \cite{gong_toward_2024}
%             \begin{itemize}
%                 \item BB codes (QLDPC)
%                 \item Circuit-level noise
%                 \item Sequential
%                 \item Cites $\underbrace{\cite{dennis_topological_2002}
%                         \cite{tan_scalable_2023}
%                     \cite{skoric_parallel_2023}}_\text{Surface code}
%                     \underbrace{\cite{huang_improved_2023}}_\text{QLDPC,Phenomenological}$
%             \end{itemize}
%         \item \cite{huang_improved_2023}
%             \begin{itemize}
%                 \item Hypergraph product codes, Lifted product codes (QLDPC)
%                 \item Phenomenological noise
%                 \item Sequential
%                 \item Cites $\underbrace{\cite{dennis_topological_2002}
%                         [Huang, Brown, 2021]
%                         \cite{skoric_parallel_2023}
%                         \cite{tan_scalable_2023}
%                     \cite{bombin_modular_2023}}_\text{Surface code}$
%             \end{itemize}
%         \item \cite{dennis_topological_2002}
%             \begin{itemize}
%                 \item Surface code (Topological)
%                 \item No idea what noise, don't care either (Gong et
%                     al. say circuit-level noise)
%                 \item ``Overlapping recovery'' -> Sequential
%             \end{itemize}
%         \item \cite{tan_scalable_2023}
%             \begin{itemize}
%                 \item Surface code (Topological)
%                 \item Circuit-level noise
%                 \item Parallel
%                 \item Cites \cite{dennis_topological_2002}
%             \end{itemize}
%         \item \cite{skoric_parallel_2023}
%             \begin{itemize}
%                 \item Surface code (Topological)
%                 \item Circuit-level noise
%                 \item Parallel
%                 \item Cites \cite{dennis_topological_2002}
%             \end{itemize}
%         \item \cite{huang_increasing_2024}
%             \begin{itemize}
%                 \item Same as \cite{huang_improved_2023}
%             \end{itemize}
%         \item \cite{kuo_fault-tolerant_2024}
%             \begin{itemize}
%                 \item Toric codes (Topological)
%                 \item Circuit-level noise
%                 \item Parallel
%                 \item Cites \cite{dennis_topological_2002}
%                     \cite{tan_scalable_2023}
%                     \cite{skoric_parallel_2023} \cite{gong_toward_2024}
%             \end{itemize}
%         \item \cite{bombin_modular_2023}
%             \begin{itemize}
%                 \item Surface codes (Topological)
%                 \item No idea if it's even fault-tolerant
%                 \item Parallel
%                 \item Cites \cite{dennis_topological_2002}
%                     \cite{tan_scalable_2023}
%                     \cite{skoric_parallel_2023} \cite{leverrier_decoding_2022}
%             \end{itemize}
%             % This is not BP and not parallelization over the time dimension
%             % \item \cite{leverrier_decoding_2022}
%             %     \begin{itemize}
%             %         \item Quantum tanner codes (QLDPC)
%             %         \item Parallel
%             %         \item No idea if it's even fault-tolerant
%             %         \item Cites [don't care]
%             %     \end{itemize}
%         \item \cite{kang_quits_2025}
%             \begin{itemize}
%                 \item Cites \cite{huang_increasing_2024} \ldots
%             \end{itemize}
%     \end{itemize}
% }

%%%%%%%%%%%%%%%%
\subsection{Window Splitting and Sequential Sliding-Window Decoding}
\label{subsec:Window Splitting and Sequential Sliding-Window Decoding}

In this section, we will examine the methodology by which a detector
error matrix is divided into overlapping windows.
The algorithm detailed here follows \cite{kang_quits_2025}, whose
work is in turn based on \cite{huang_increasing_2024}.

% Very high-level overview

Sliding-window decoding is made possible by the time-like structure
of the syndrome extraction circuitry.
This is epecially clearly visible under the \ac{dem} formalism, where
this manifests as a block-diagonal structure of the detector
error matrix $\bm{H}$.
Note that this presupposes a choice of detectors as seen in
\Cref{subsec:Detector Error Matrix}.
This block-diagonal structure introduces some locality in the
interdependence between \acp{vn} and \acp{cn}.
For each local set of \acp{vn}, there is only a local set of connected \acp{cn}.
We exploit this fact by cutting the matrix into overlapping windows.
\Cref{fig:windowing_pcm} depicts this process using the $\llbracket
72, 6, 6 \rrbracket$ BB code as an example.

% High-level overview

How the locality is leveraged can be understood by considering the
decoding process.
After decoding a window, there is a subset of \acp{cn} that no longer
contribute to decoding, as they are not connected to any \acp{vn}
considered for the subsequent windows.
We call the set of \acp{vn} connected to those \acp{cn} the
\emph{commit region} and we wish to commit them before moving to the
next window, i.e., fix the values we estimate for the corresponding bits.
As mentioned above, the benefit of this sequential sliding-window
decoding approach
is that the decoding process can begin as soon as the syndrome
measurements for the first window are complete.

% W and F and why we look at rows, not columns

There are two degrees of freedom in how we perform the windowing.
The \emph{window size} $W \in \mathbb{N}$ represents the number of
syndrome extraction rounds lumped into one window.
The \emph{step size} $F \in \mathbb{N}$ represents the number of
syndrome extraction rounds passed over before starting the next window.
$W$ controls the size of the windows while $F$ controls the overlap
between them.
As illustrated in \Cref{fig:windowing_pcm}, $W$ and $F$ control the
window dimensions and locactions by defining the related \acp{cn},
not the \acp{vn}.
This is because while the number of overall \acp{cn} is only affected
by the choice of the underlying code and the number of syndrome
measurement rounds, the number of \acp{vn} depends on the noise model
and is difficult to predict beforehand.

\begin{figure}[t]
    \centering

    \hspace*{-114mm}%
    \begin{tikzpicture}
        \draw[decorate, decoration={brace, amplitude=10pt}, line width=1pt]
        (0,0) -- (3.1,0) node[midway, above=4mm] {Commit region};
    \end{tikzpicture}

    \centering
    \includegraphics[scale=0.75]{res/72_bb_dem.pdf}

    \vspace*{-25.3mm}

    \hspace*{-98mm}%
    \begin{tikzpicture}
        \draw[{Latex}-{Latex}, line width=.7pt] (0,   -0.75mm) -- (0,  5mm);
        \draw[line width=1pt]                   (-1mm,-0.75mm) --
        (3mm,-0.75mm);
        \draw[line width=1pt]                   (-1mm,5mm)     -- (3mm,5mm);
        \node[left] at                          (-2mm,2.125mm) {$\sim W$};

        \draw[{Latex}-{Latex}, line width=.3pt] (6.5cm,1.6mm)  -- (6.5cm,5mm);
        \draw[line width=1pt]                   (6.5cm,4.9mm)  -- (6.5cm,7mm);
        \node[above] at                         (6.5cm,7mm) {$\sim F$};
    \end{tikzpicture}

    \vspace*{10mm}

    \caption{
        Visualization of the windowing process on a detector
        error matrix generated from the $\llbracket 72, 6, 6
        \rrbracket$ BB code.
    }
    \label{fig:windowing_pcm}
\end{figure}

% Notation recap

We briefly reintroduce the notation important for the definition of the windows.
We use the variables $n,m \in \mathbb{N}$ to describe the number of
\acp{vn} and \acp{cn} respectively.
We index the \acp{vn} using the variable $i \in \mathcal{I} :=
[0:n-1]$ and the \acp{cn} using the variable $j \in \mathcal{J} := [ 0 : m-1]$.
Finally, we call $\mathcal{N}_\text{V}(i) = \left\{ i\in \mathcal{I}:
\bm{H}_{j,i} = 1 \right\}$ and $\mathcal{N}_\text{C}(j) := \left\{ j
\in \mathcal{J} : \bm{H}_{j,i} = 1 \right\}$ the neighborhoods of the
corresponding nodes.
In this case, we take $\bm{H} \in \mathbb{F}_2^{m\times n}$ to be the
check matrix of the underlying code, from which the \ac{dem} was generated.
We use $m_\text{DEM}, \mathcal{I}_\text{DEM}$, and $\mathcal{J}_\text{DEM}$
to refer to the respective values defined from the detector error matrix.

% How we get the corresponding rows

We begin by describing the sets of \acp{cn} relevant to each window.
For indexing, we use the variable $\ell \in [0:n_\text{win} - 1]$,
where $n_\text{win} \in \mathbb{N}$ is the number of windows.
Because we defined the step size $F$ as the number of syndrome
extraction rounds to skip, the first \ac{cn} of window $\ell$ should have index
$\ell F m$.
Similarly, because of the way we defined the step size $W$, the
number of \acp{cn} should be $Wm$ for all but the last window.
The number of \acp{cn} in the last window may differ if there are
not enough \acp{cn} left to completely fill it.
We thus define
\begin{align*}
    \mathcal{J}_\text{win}^{(\ell)} &:= \left\{ j\in \mathcal{J}_\text{DEM}:~
        \ell F m \le j < \min \left\{m_\text{DEM}, (\ell F + W) m \right\}
    \right\} \\[2mm]
    & \hspace{30mm} \text{and} \\[2mm]
    \mathcal{J}_\text{commit}^{(\ell)} &:= \left\{ j\in \mathcal{J}_\text{DEM}:~
        \ell F m \le j < \min \left\{m_\text{DEM}, (\ell + 1) F m \right\}
    \right\}
    .%
\end{align*}
$\mathcal{J}_\text{win}^{(\ell)}$ is the set of all \acp{cn} in the
window while $\mathcal{J}_\text{commit}^{(\ell)}$ is the set of \acp{cn}
that do not contribute to the next window and whose neighboring
\acp{vn} will thus be comitted.
We can additionally define the set of \acp{vn} that are shared between windows
$\ell$ and $\ell + 1$ as $\mathcal{J}_\text{overlap}^{(\ell)} :=
\mathcal{J}_\text{win}^{(\ell)}\setminus \mathcal{J}_\text{commit}^{(\ell)}$.

% How we get the corresponding columns

We can now turn our attention to defining the sets of \acp{vn} relevant
to each window.
We first introduce a helper function $i_\text{max} :
\mathcal{P}(\mathbb{N}) \to \mathbb{N}$, which takes a set of
\ac{cn} indices and returns the largest neighboring \ac{vn} index.
We define
\begin{align*}
    i_\text{max}\left( \mathcal{S} \right) := \max \left\{ i\in
    \mathcal{N}_\text{C}(j) : j\in \mathcal{S} \right\}
    ,
\end{align*}
where we set $i_\text{max} (\emptyset) = -1$ by convention%
\footnote{
    This has the effect of later automatically setting the lower
    bounds for the indices in $\mathcal{I}_\text{commit}^{(\ell)}$
    and $\mathcal{I}_\text{win}^{(\ell)}$ appropriately.
}%
.
The commit region of window $\ell$ should include all of the \acp{vn}
neighboring any of the \acp{cn} in $\mathcal{J}_\text{commit}^{(\ell)}$.
Consequently, the maximum index of the \acp{vn} we consider should be
$i_\text{max}(\mathcal{J}_\text{commit}^{(\ell)})$.
Additionally, the set of \acp{vn} comitted in the next window should
start immediately afterwards.
We thus define
\begin{align*}
    \mathcal{I}_\text{commit}^{(\ell)}
    &:= \left\{i \in \mathcal{I}_\text{DEM} :~
        i_\text{max}\left( \mathcal{J}_\text{commit}^{(\ell-1)} \right)
        < i \le
        i_\text{max}\left( \mathcal{J}_\text{commit}^{(\ell)} \right)
    \right\}\\[2mm]
    & \hspace{39mm} \text{and} \\[2mm]
    \mathcal{I}_\text{win}^{(\ell)}
    &:= \left\{i \in \mathcal{I}_\text{DEM} :~
        i_\text{max}\left( \mathcal{J}_\text{commit}^{(\ell-1)} \right)
        < i \le
        i_\text{max}\left( \mathcal{J}_\text{win}^{(\ell)} \right)
    \right\}
    .%
\end{align*}
Note that we have
\begin{align*}
    \bigcup_{\ell=0}^{n_\text{win}-1}
    \mathcal{I}_\text{commit}^{(\ell)} = \mathcal{I}
\end{align*}
and after decoding all windows we will therefore have committed all \acp{vn}.

\begin{figure}[t]
    \centering

    \begin{tikzpicture}
        \def\sx{1.5}
        \def\sy{1.5}

        \coordinate (a00) at (0,0);
        \coordinate (a01) at (0,      3*\sy);
        \coordinate (a11) at (6*\sx,  3*\sy);
        \coordinate (a10) at (6*\sx,  0*\sy);

        \coordinate (b00) at (3.2*\sx, -1*\sy);
        \coordinate (b01) at (3.2*\sx,  2*\sy);
        \coordinate (b11) at (9.2*\sx,  2*\sy);
        \coordinate (b10) at (9.2*\sx, -1*\sy);

        \fill[gray!40] (a00) -- (a00 |- b01) -- (b01) -- (b01 |- a00) -- cycle;

        \draw (a00) -- (a01) -- (a11) -- (a10) -- cycle;
        \draw[densely dashed] (b00) -- (b01) -- (b11) -- (b10) -- cycle;

        \draw [
            decorate,
            decoration={brace,amplitude=3mm,raise=1mm}
        ]
        (a01) -- (a11)
        node[midway,above,yshift=4mm]{$\mathcal{I}_\text{win}^{(\ell)}$};

        \draw [
            decorate,
            decoration={brace,amplitude=3mm,raise=1mm}
        ]
        (a00 -| b00) -- (a00)
        node[midway,below,yshift=-4mm]{$\mathcal{I}_\text{commit}^{(\ell)}$};

        \draw [
            decorate,
            decoration={brace,amplitude=3mm,raise=1mm}
        ]
        (a00) -- (a01)
        node[midway,xshift=-3mm,left]{$\mathcal{J}_\text{win}^{(\ell)}$};

        \draw [
            decorate,
            decoration={brace,amplitude=3mm,raise=1mm}
        ]
        (a11) -- (a11 |- b11)
        node[midway,xshift=3mm,right]{$\mathcal{J}_\text{commit}^{(\ell)}$};

        \draw [
            decorate,
            decoration={brace,amplitude=3mm,raise=1mm}
        ]
        (a11 |- b11) -- (a10)
        node[midway,xshift=3mm,right]{$\mathcal{J}_\text{overlap}^{(\ell)}
            := \mathcal{J}_\text{win}^{(\ell)} \setminus
        \mathcal{J}_\text{commit}^{(\ell)}$};

        \node[align=center] at ($(a00)!0.5!(b01)$)
        {%
            $\bm{H}_\text{overlap}^{(\ell)}$ \\[3mm]
            $=
            \left(\bm{H}_\text{DEM}\right)_{\mathcal{J}_\text{overlap}^{(\ell)},
            \mathcal{I}_\text{commit}^{(\ell)}}$%
        };
    \end{tikzpicture}

    \caption{Visual representation of notation used for window splitting.}
    \label{fig:vis_rep}
\end{figure}

% Syndrome update

\Cref{fig:vis_rep} illustrates the meaning of the various sets of nodes.
We can also see a particular point we have to be careful about when
moving on to decode the next window.
While the \acp{vn} in $\mathcal{J}_\text{commit}^{(\ell)}$ have no
bearing on the further decoding process, the values commit for the
\acp{vn} in $\mathcal{I}_\text{commit}^{(\ell)}$ do.
This is the case because these \acp{vn} have neighboring \acp{cn} in
the next window.
The part of the detector error matrix $\bm{H}_\text{DEM}$ describing
these connections is
$\bm{H}_\text{overlap}^{(\ell)} =
\left(\bm{H}_\text{DEM}\right)_{\mathcal{J}_\text{overlap}^{(\ell)},
\mathcal{I}_\text{commit}^{(\ell)}}$.
We have to account for this fact by updating the syndrome $\bm{s}$
based on the committed bit values.
Specifically, if $\bm{e}_\text{commit}^{(\ell)}$ describes the error
estimates commited after decoding window $\ell$, we have to set
\begin{align*}
    \bm{s}_{\mathcal{J}_\text{overlap}^{(\ell)}} =
    \bm{H}_\text{overlap}^{(\ell)}
    \left( \bm{e}_\text{commit}^{(\ell)} \right)^\text{T}
    .%
\end{align*}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Warm-Start Sliding-Window Decoding}
\label{sec:warm_start_bp}

% Intro

The sliding-window structure visible in \Cref{fig:windowing_pcm} is
highly reminicent of the way \ac{sc}-\ac{ldpc} codes are decoded.
Switching our viewpoint to the Tanner graph depicted in
\Cref{fig:windowing_tanner}, however, we can see an important
difference between \ac{sc}-\ac{ldpc} decoding and the
sliding-window decoding procedure detailed above.
While the windowing process is similar, the algorithm above
reinitializes the decoder to start from a clean state when moving to
the next window.
It therefore does not make use of the integral property of
\ac{sc}-\ac{ldpc} decoding of exploiting the spatially coupled
structure by passing soft information from earlier to later spatial positions.

We propose a modification to the procedure detailed in
\Cref{subsec:Window Splitting and Sequential Sliding-Window Decoding}:
Instead of zero-initializing the \ac{bp} messages of the next window,
we perform a \emph{warm start} by initializing the messages in the
overlapping region to the values last held during the decoding of the
previous window.

\begin{figure}[t]
    \centering

    \tikzset{
        VN/.style={
            circle, fill=KITgreen, minimum width=1mm, minimum height=1mm,
        },
        CN/.style={
            rectangle, fill=KITblue, minimum width=1mm, minimum height=1mm,
        },
    }

    \begin{tikzpicture}[node distance = 5mm]
        \node[VN]                  (vn00) {};
        \node[VN, below = of vn00] (vn01) {};
        \node[VN, below = of vn01] (vn02) {};
        \node[VN, below = of vn02] (vn03) {};
        \node[VN, below = of vn03] (vn04) {};

        \coordinate (temp) at ($(vn01)!0.5!(vn02)$);

        \node[CN, left =10mm of temp] (cn00) {};
        \node[CN, below = of cn00] (cn01) {};

        \draw (vn00) -- (cn00);
        \draw (vn01) -- (cn00);
        \draw (vn03) -- (cn00);
        \draw (vn01) -- (cn01);
        \draw (vn02) -- (cn01);
        \draw (vn04) -- (cn01);

        \foreach \i in {1,2,3,4} {
            \pgfmathtruncatemacro{\prev}{\i-1}

            \node[VN, right = 25mm of vn\prev 0] (vn\i0) {};
            \node[VN, below = of vn\i0]          (vn\i1) {};
            \node[VN, below = of vn\i1]          (vn\i2) {};
            \node[VN, below = of vn\i2]          (vn\i3) {};
            \node[VN, below = of vn\i3]          (vn\i4) {};

            \coordinate (temp) at ($(vn\i1)!0.5!(vn\i2)$);

            \node[CN, left = 10mm of temp] (cn\i0) {};
            \node[CN, below = of cn\i0]     (cn\i1) {};

            \draw (vn\i0) -- (cn\i0);
            \draw (vn\i1) -- (cn\i0);
            \draw (vn\i3) -- (cn\i0);
            \draw (vn\i1) -- (cn\i1);
            \draw (vn\i2) -- (cn\i1);
            \draw (vn\i4) -- (cn\i1);
        }

        \foreach \i in {1,2,3,4} {
            \pgfmathtruncatemacro{\prev}{\i-1}

            \draw (vn\prev 3) -- (cn\i 0);
            \draw (vn\prev 4) -- (cn\i 1);
        }

        \node[
            draw, inner sep=5mm,line width=1pt,
            fit=(vn00)(vn04)(cn00)(cn01)(vn20)(vn24)(cn20)(cn21)
        ]
        (box1) {};
        \node[
            draw, dashed, inner sep=5mm, inner ysep=8mm,line width=1pt,
            fit=(vn10)(vn14)(cn10)(cn11)(vn30)(vn34)(cn30)(cn31)
        ]
        (box2) {};

        % Marker for W on the bottom
        \draw[line width=1pt]
        ([yshift=-5mm, line width=1pt]box1.south west) -- ++(0,-4mm)
        coordinate (dim1l);
        \draw[line width=1pt]
        ([yshift=-5mm]box1.south east) -- ++(0,-4mm)
        coordinate (dim1r);
        \draw[{Latex}-{Latex}, line width=1pt]
        ([yshift=1mm]dim1l) -- ([yshift=1mm]dim1r)
        node[midway, below=2pt] {$W$};

        % Marker for F on top
        \draw[line width=1pt]
        ([yshift=3mm]box2.north west) -- ++(0,4mm)
        coordinate (dim3l);
        \draw[line width=1pt]
        ([yshift=3mm]box2.north west -| box1.north west) -- ++(0,4mm)
        coordinate (dim3r);
        \draw[{Latex}-{Latex}, line width=1pt]
        ([yshift=-1mm]dim3l) -- ([yshift=-1mm]dim3r)
        node[midway, above=2pt] {$F$};

        % Arrow on the top right
        \draw[-{Latex}, line width=1pt]
        ([yshift=8mm] box1.north east) -- ++(28mm,0);
    \end{tikzpicture}

    \caption{Visualization of the windowing process on the Tanner graph.}
    \label{fig:windowing_tanner}
\end{figure}

%%%%%%%%%%%%%%%%
\subsection{Warm-Start Belief Propagation Decoding}
\label{subsec:Warm-Start Belief Propagation Decoding}

% Warm-Start decoding for BP

\content{Pass messages to next window}
\content{(?) Explicitly mention initialization using only CN->VN
messages + swapping of CN and VN update?}
\content{(?) Algorithm}

\begin{figure}[t]
    \centering

    \tikzset{
        VN/.style={
            circle, fill=KITgreen, minimum width=1mm, minimum height=1mm,
        },
        CN/.style={
            rectangle, fill=KITblue, minimum width=1mm, minimum height=1mm,
        },
    }

    \begin{tikzpicture}[node distance = 5mm]
        \node[VN]                  (vn00) {};
        \node[VN, below = of vn00] (vn01) {};
        \node[VN, below = of vn01] (vn02) {};
        \node[VN, below = of vn02] (vn03) {};
        \node[VN, below = of vn03] (vn04) {};

        \coordinate (temp) at ($(vn01)!0.5!(vn02)$);

        \node[CN, left =10mm of temp] (cn00) {};
        \node[CN, below = of cn00] (cn01) {};

        \draw (vn00) -- (cn00);
        \draw (vn01) -- (cn00);
        \draw (vn03) -- (cn00);
        \draw (vn01) -- (cn01);
        \draw (vn02) -- (cn01);
        \draw (vn04) -- (cn01);

        \foreach \i in {1,2,3,4} {
            \pgfmathtruncatemacro{\prev}{\i-1}

            \node[VN, right = 25mm of vn\prev 0] (vn\i0) {};
            \node[VN, below = of vn\i0]          (vn\i1) {};
            \node[VN, below = of vn\i1]          (vn\i2) {};
            \node[VN, below = of vn\i2]          (vn\i3) {};
            \node[VN, below = of vn\i3]          (vn\i4) {};

            \coordinate (temp) at ($(vn\i1)!0.5!(vn\i2)$);

            \node[CN, left = 10mm of temp] (cn\i0) {};
            \node[CN, below = of cn\i0]     (cn\i1) {};

            \draw (vn\i0) -- (cn\i0);
            \draw (vn\i1) -- (cn\i0);
            \draw (vn\i3) -- (cn\i0);
            \draw (vn\i1) -- (cn\i1);
            \draw (vn\i2) -- (cn\i1);
            \draw (vn\i4) -- (cn\i1);
        }

        \foreach \i in {1,2,3,4} {
            \pgfmathtruncatemacro{\prev}{\i-1}

            \draw (vn\prev 3) -- (cn\i 0);
            \draw (vn\prev 4) -- (cn\i 1);
        }

        \node[
            draw, inner sep=5mm,line width=1pt,
            fit=(vn00)(vn04)(cn00)(cn01)(vn20)(vn24)(cn20)(cn21)
        ]
        (box1) {};
        \node[
            draw, dashed, inner sep=5mm, inner ysep=8mm,line width=1pt,
            fit=(vn10)(vn14)(cn10)(cn11)(vn30)(vn34)(cn30)(cn31)
        ]
        (box2) {};

        \draw[KITorange, line width=2pt] (cn10) -- (vn10);
        \draw[KITorange, line width=2pt] (cn10) -- (vn11);
        \draw[KITorange, line width=2pt] (cn10) -- (vn13);
        \draw[KITorange, line width=2pt] (cn11) -- (vn11);
        \draw[KITorange, line width=2pt] (cn11) -- (vn12);
        \draw[KITorange, line width=2pt] (cn11) -- (vn14);

        \draw[KITorange, line width=2pt] (vn13) -- (cn20);
        \draw[KITorange, line width=2pt] (vn14) -- (cn21);

        \draw[KITorange, line width=2pt] (cn20) -- (vn20);
        \draw[KITorange, line width=2pt] (cn20) -- (vn21);
        \draw[KITorange, line width=2pt] (cn20) -- (vn23);
        \draw[KITorange, line width=2pt] (cn21) -- (vn21);
        \draw[KITorange, line width=2pt] (cn21) -- (vn22);
        \draw[KITorange, line width=2pt] (cn21) -- (vn24);

        % Marker for W on the bottom
        \draw[line width=1pt]
        ([yshift=-5mm, line width=1pt]box1.south west) -- ++(0,-4mm)
        coordinate (dim1l);
        \draw[line width=1pt]
        ([yshift=-5mm]box1.south east) -- ++(0,-4mm)
        coordinate (dim1r);
        \draw[{Latex}-{Latex}, line width=1pt]
        ([yshift=1mm]dim1l) -- ([yshift=1mm]dim1r)
        node[midway, below=2pt] {$W$};

        % Marker for F on top
        \draw[line width=1pt]
        ([yshift=3mm]box2.north west) -- ++(0,4mm)
        coordinate (dim3l);
        \draw[line width=1pt]
        ([yshift=3mm]box2.north west -| box1.north west) -- ++(0,4mm)
        coordinate (dim3r);
        \draw[{Latex}-{Latex}, line width=1pt]
        ([yshift=-1mm]dim3l) -- ([yshift=-1mm]dim3r)
        node[midway, above=2pt] {$F$};

        % Arrow on the top right
        \draw[-{Latex}, line width=1pt]
        ([yshift=8mm] box1.north east) -- ++(28mm,0);
    \end{tikzpicture}

    \caption{
        Visualization of the messages used for the
        initialization of the next window.
    }
    \label{fig:messages_tanner}
\end{figure}

%%%%%%%%%%%%%%%%
\subsection{Warm-Start Belief Propagation with Guided Decimation Decoding}
\label{subsec:Warm-Start Belief Propagation with Guided Decimation Decoding}

% Warm-Start decoding for BPGD

\content{Modified structure of BPGD $\rightarrow$ In addition to
messages, pass decimation info}
\content{(?) Explicitly mention decimation info = channel llrs?}
\content{(?) Algorithm}

\begin{figure}[t]
    \centering

    \tikzset{
        VN/.style={
            circle, fill=KITgreen, minimum width=1mm, minimum height=1mm,
        },
        CN/.style={
            rectangle, fill=KITblue, minimum width=1mm, minimum height=1mm,
        },
    }

    \begin{tikzpicture}[node distance = 5mm]
        \node[VN]                  (vn00) {};
        \node[VN, below = of vn00] (vn01) {};
        \node[VN, below = of vn01] (vn02) {};
        \node[VN, below = of vn02] (vn03) {};
        \node[VN, below = of vn03] (vn04) {};

        \coordinate (temp) at ($(vn01)!0.5!(vn02)$);

        \node[CN, left =10mm of temp] (cn00) {};
        \node[CN, below = of cn00] (cn01) {};

        \draw (vn00) -- (cn00);
        \draw (vn01) -- (cn00);
        \draw (vn03) -- (cn00);
        \draw (vn01) -- (cn01);
        \draw (vn02) -- (cn01);
        \draw (vn04) -- (cn01);

        \foreach \i in {1,2,3,4} {
            \pgfmathtruncatemacro{\prev}{\i-1}

            \node[VN, right = 25mm of vn\prev 0] (vn\i0) {};
            \node[VN, below = of vn\i0]          (vn\i1) {};
            \node[VN, below = of vn\i1]          (vn\i2) {};
            \node[VN, below = of vn\i2]          (vn\i3) {};
            \node[VN, below = of vn\i3]          (vn\i4) {};

            \coordinate (temp) at ($(vn\i1)!0.5!(vn\i2)$);

            \node[CN, left = 10mm of temp] (cn\i0) {};
            \node[CN, below = of cn\i0]     (cn\i1) {};

            \draw (vn\i0) -- (cn\i0);
            \draw (vn\i1) -- (cn\i0);
            \draw (vn\i3) -- (cn\i0);
            \draw (vn\i1) -- (cn\i1);
            \draw (vn\i2) -- (cn\i1);
            \draw (vn\i4) -- (cn\i1);
        }

        \foreach \i in {1,2,3,4} {
            \pgfmathtruncatemacro{\prev}{\i-1}

            \draw (vn\prev 3) -- (cn\i 0);
            \draw (vn\prev 4) -- (cn\i 1);
        }

        \node[
            draw, inner sep=5mm,line width=1pt,
            fit=(vn00)(vn04)(cn00)(cn01)(vn20)(vn24)(cn20)(cn21)
        ]
        (box1) {};
        \node[
            draw, dashed, inner sep=5mm, inner ysep=8mm,line width=1pt,
            fit=(vn10)(vn14)(cn10)(cn11)(vn30)(vn34)(cn30)(cn31)
        ]
        (box2) {};

        \draw[KITorange, line width=2pt] (cn10) -- (vn10);
        \draw[KITorange, line width=2pt] (cn10) -- (vn11);
        \draw[KITorange, line width=2pt] (cn10) -- (vn13);
        \draw[KITorange, line width=2pt] (cn11) -- (vn11);
        \draw[KITorange, line width=2pt] (cn11) -- (vn12);
        \draw[KITorange, line width=2pt] (cn11) -- (vn14);

        \draw[KITorange, line width=2pt] (vn13) -- (cn20);
        \draw[KITorange, line width=2pt] (vn14) -- (cn21);

        \draw[KITorange, line width=2pt] (cn20) -- (vn20);
        \draw[KITorange, line width=2pt] (cn20) -- (vn21);
        \draw[KITorange, line width=2pt] (cn20) -- (vn23);
        \draw[KITorange, line width=2pt] (cn21) -- (vn21);
        \draw[KITorange, line width=2pt] (cn21) -- (vn22);
        \draw[KITorange, line width=2pt] (cn21) -- (vn24);

        \node[VN, draw=KITorange, fill=KITorange] at (vn10) {};
        \node[VN, draw=KITorange, fill=KITorange] at (vn11) {};
        \node[VN, draw=KITorange, fill=KITorange] at (vn12) {};
        \node[VN, draw=KITorange, fill=KITorange] at (vn13) {};
        \node[VN, draw=KITorange, fill=KITorange] at (vn14) {};

        \node[VN, draw=KITorange, fill=KITorange] at (vn20) {};
        \node[VN, draw=KITorange, fill=KITorange] at (vn21) {};
        \node[VN, draw=KITorange, fill=KITorange] at (vn22) {};
        \node[VN, draw=KITorange, fill=KITorange] at (vn23) {};
        \node[VN, draw=KITorange, fill=KITorange] at (vn24) {};

        % Marker for W on the bottom
        \draw[line width=1pt]
        ([yshift=-5mm, line width=1pt]box1.south west) -- ++(0,-4mm)
        coordinate (dim1l);
        \draw[line width=1pt]
        ([yshift=-5mm]box1.south east) -- ++(0,-4mm)
        coordinate (dim1r);
        \draw[{Latex}-{Latex}, line width=1pt]
        ([yshift=1mm]dim1l) -- ([yshift=1mm]dim1r)
        node[midway, below=2pt] {$W$};

        % Marker for F on top
        \draw[line width=1pt]
        ([yshift=3mm]box2.north west) -- ++(0,4mm)
        coordinate (dim3l);
        \draw[line width=1pt]
        ([yshift=3mm]box2.north west -| box1.north west) -- ++(0,4mm)
        coordinate (dim3r);
        \draw[{Latex}-{Latex}, line width=1pt]
        ([yshift=-1mm]dim3l) -- ([yshift=-1mm]dim3r)
        node[midway, above=2pt] {$F$};

        % Arrow on the top right
        \draw[-{Latex}, line width=1pt]
        ([yshift=8mm] box1.north east) -- ++(28mm,0);
    \end{tikzpicture}

    \caption{
        Visualization of the messages and decimation information used for the
        initialization of the next window.
    }
    \label{fig:messages_decimation_tanner}
\end{figure}

\section{Numerical Results}
\label{sec:Numerical Results}

% Intro

In this section, we perform numerical experiments to evaluate the
modification to sliding-window decoding we introduced in
\Cref{sec:warm_start_bp}.
We chose to carry out our simulations on \ac{bb} codes, as they have
recently emerged as particularly promising candidates for practical
\ac{qec}, offering high encoding rates and large minimum distances
while admitting short-depth syndrome extraction circuits
\cite[Sec.~1]{bravyi_high-threshold_2024}.
Specifically, we chose the $\llbracket 144, 12, 12 \rrbracket$ BB
code, as it represents a good trade-off between code size and
simulation tractability \cite{gong_toward_2024}.
We employ standard circuit-based depolarizing noise as described in
\Cref{subsec:Choice of Noise Model}, and report performance in terms
of the per-round \ac{ler} as defined in
\Cref{subsec:Per-Round Logical Error Rate}.
All datapoints have been generated by simulating at least $200$
logical error events.

For the practical aspects of implementation, several layers of
abstraction must be considered.
The lowest layer is the circuit-level simulator.
This serves as the backbone of all further simulations, handling the
quantum mechanical aspects of the system, including the modeling of
noise on gates, idling qubits, and measurements according to the
chosen noise model.

Moving one level of abstraction higher, the syndrome extraction
circuit itself must be generated.
This entails defining the gate schedule for the ancilla measurements
and specifying the error locations introduced by the chosen noise
model, both of which depend on the code and noise model in question.

Even further up, given an already constructed syndrome extraction
circuit and the resulting \acf{dem}, we must split the detector error
matrix into separate windows and manage the interplay between the
inner decoders acting on those individual windows.

Finally, we require the decoder itself, which operates on a
\acf{pcm} and a syndrome, with no dependence on the complexity of the
layers below.

In our implementation, Stim \cite{gidney_stim_2021} served as the
circuit-level simulator, chosen for its efficiency and native support
for the \ac{dem} formalism.
For the circuit generation, we employed utilities from QUITS
\cite{kang_quits_2025}, which provides syndrome extraction circuitry
generation for a number of different \ac{qldpc} codes.
We initially created a Python implementation, which used QUITS for the window
splitting and subsequent sliding-window decoding as well.
The \ac{bp} and \ac{bpgd} decoders were also initially implemented in Python.
After a preliminary investigation, we opted for a complete
reimplementation in Rust to achieve higher simulation speeds due to
the compiled nature of the language.
We reimplemented both the window splitting and the decoders themselves.

% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \section{Numerical results}
%
% % Intro
%
% In this section, we perform numerical experiments to evaluate the
% modification to sliding-window decoding we introduced in
% \Cref{sec:warm_start_bp}.
% We chose to carry out our simulations on \ac{bb} codes, as they
% \red{[something about qldpc codes being a hot topic in the literature
% currently because of some promising properties]}.
% Specifically, we chose the $\llbracket 144, 12, 12 \rrbracket$ BB
% code, as this \red{[something something]}.\\
% \red{[Circuit-level noise]} \\
% \red{[Per-round LER]} \\
% All datapoints have been generated by simulating at least $200$
% logical error events.
%
% For the practical aspects of implementation, several layers of
% abstraction must be considered.
% The lowest layer is the circuit-level simulator.
% This serves as the backbone of all further simulations.
% It takes care of the quantum mechanical aspects of the system.
% \red{It is, for example, responsible for the introduction of noise
% [rephrase this]}.
%
% Moving one level of abstraction higher, aside from the circuit
% simulation itself, the circuit also has to be generated.
% E.g., the syndrome extraction circuitry must be defined and possible
% sources of noise must be modeled.
% This heavily depends on the code in question and the chosen noise model.
% \red{[Find something more to say]}
%
% Even further up, we have already defined syndrome extraction
% circuitry and built the \acf{dem}.
% We must now split the detector error matrix into separate windows and
% manage the interplay of the inner decoders acting on the individual
% windows themselves.
% \red{[Find something more to say]}
%
% Finally, we require the decoder itself.
% This simply gets a \acf{pcm} and a syndrome with no regard
% \red{[Rephrase this] for the complexity in the rest of the system}.
%
% In our implementations, Stim \cite{gidney_stim_2021} served as the
% circuit-level simulator \red{[Possibly mention why stim was chosen]}.
% For the circuit generation, we employed utilities from QUITS
% \cite{kang_quits_2025}, where syndrome extraction circuitry
% generation is implemented for a number of different \ac{qldpc} codes.
% An initial Python implementation used QUITS for the window
% splitting and subsequent sliding-window decoding as well.
% The \ac{bp} and \ac{bpgd} decoders were also initially implemented in Python.
% After a preliminary investigation, we opted for a complete
% reimplementation in Rust to achieve higher simulation speeds due to
% the compiled nature of the language.
% We reimplemented both the window splitting and the decoders themselves.

%%%%%%%%%%%%%%%%
\subsection{Belief Propagation}
\label{subsec:Belief Propagation}

% Simulation setup

\content{Use min-sum}

\begin{figure}[H]
    \centering
    \begin{tikzpicture}
        \begin{axis}[
                width=\figwidth,
                height=\figheight,
                ymode=log,
                legend style={
                    cells={anchor=west},
                    cells={align=left},
                },
                enlargelimits=false,
                ymin=1e-5, ymax=2e-1,
                grid=both,
                legend pos = south east,
                xtick={0.001,0.0015,...,0.004},
                xticklabel style={/pgf/number format/fixed},
                xticklabel style={/pgf/number format/precision=4},
                scaled x ticks=false,
                xlabel={Physical error rate},
                ylabel={Per-round-LER},
            ]

            \foreach \W/\col/\mark in
            {3/KITred/triangle*,4/KITblue/diamond*,5/KITorange/square*} {
                \edef\temp{\noexpand
                    \addplot+[mark=\mark, solid, mark
                    options={fill=\col}, \col]
                    table[
                        col sep=comma, x=physical_p,
                        y=LER_per_round,
                    ]
                    {res/sim/WF/WindowingSyndromeMinSumDecoder/max_iter_200/pass_soft_info_False/F_1/W_\W/LERs.csv};
                }
                \temp

                \addlegendentryexpanded{$W = \W$}
            }

            \addplot+[mark=*, solid, mark options={fill=black}, black]
            table[
                col sep=comma, x=physical_p,
                y=LER_per_round,
            ]
            {res/sim/whole/SyndromeMinSumDecoder/max_iter_200/LERs.csv};

            \addlegendentry{Whole}
        \end{axis}
    \end{tikzpicture}

    \caption{
        Comparison of the decoding performance of the $\llbracket
        144,12,12 \rrbracket$ \ac{bb} code under min-sum decoding
        ($200$ iterations) for different window sizes.
        The step size was fixed to $F=1$, $12$ rounds of syndrome
        extraction were performed and the noise model is
        standard circuit-based depolarizing noise.
    }
\end{figure}

\begin{figure}[H]
    \centering
    \begin{tikzpicture}
        \begin{axis}[
                width=\figwidth,
                height=\figheight,
                ymode=log,
                legend style={
                    cells={anchor=west},
                    cells={align=left},
                },
                enlargelimits=false,
                ymin=1e-5, ymax=2e-1,
                grid=both,
                legend pos = south east,
                xtick={0.001,0.0015,...,0.004},
                xticklabel style={/pgf/number format/fixed},
                xticklabel style={/pgf/number format/precision=4},
                scaled x ticks=false,
                xlabel={Physical error rate},
                ylabel={Per-round-LER},
                extra description/.code={
                    \node[rotate=90, anchor=south]
                    at ([xshift=10mm]current axis.east)
                    {Warm s. (---), Cold s. (- - -)};
                },
            ]

            \foreach \W/\col/\mark in
            {3/KITred/triangle,4/KITblue/diamond,5/KITorange/square} {
                \edef\temp{\noexpand
                    \addplot+[
                        mark=\mark, densely dashed, mark options={fill=\col},
                        \col, forget plot
                    ]
                    table[
                        col sep=comma, x=physical_p,
                        y=LER_per_round,
                    ]
                    {res/sim/WF/WindowingSyndromeMinSumDecoder/max_iter_200/pass_soft_info_False/F_1/W_\W/LERs.csv};
                }
                \temp
            }

            \foreach \W/\col/\mark in
            {3/KITred/triangle*,4/KITblue/diamond*,5/KITorange/square*} {
                \edef\temp{\noexpand
                    \addplot+[mark=\mark, solid, mark
                    options={fill=\col}, \col]
                    table[
                        col sep=comma, x=physical_p,
                        y=LER_per_round,
                    ]
                    {res/sim/WF/WindowingSyndromeMinSumDecoder/max_iter_200/pass_soft_info_True/F_1/W_\W/LERs.csv};
                }
                \temp

                \addlegendentryexpanded{$W = \W$}
            }

            \addplot+[mark=*, solid, mark options={fill=black}, black]
            table[
                col sep=comma, x=physical_p,
                y=LER_per_round,
            ]
            {res/sim/whole/SyndromeMinSumDecoder/max_iter_200/LERs.csv};

            \addlegendentry{Whole}
        \end{axis}
    \end{tikzpicture}

    \caption{
        Comparison of the decoding performance of cold and warm-start
        decoding under the $\llbracket 144,12,12 \rrbracket$ \ac{bb}
        code for different window sizes.
        Decoding was performed using the min-sum algorithm ($200$
        iterations).
        The step size was fixed to $F=1$, $12$ rounds of syndrome
        extraction were performed and the noise model is
        standard circuit-based depolarizing noise.
    }
\end{figure}

\begin{figure}[H]
    \centering
    \begin{tikzpicture}
        \begin{axis}[
                width=\figwidth,
                height=\figheight,
                ymode=log,
                legend style={
                    cells={anchor=west},
                    cells={align=left},
                },
                enlargelimits=false,
                ymin=1e-5, ymax=2e-1,
                grid=both,
                legend pos = south east,
                xtick={0.001,0.0015,...,0.004},
                xticklabel style={/pgf/number format/fixed},
                xticklabel style={/pgf/number format/precision=4},
                scaled x ticks=false,
                xlabel={Physical error rate},
                ylabel={Per-round-LER},
                extra description/.code={
                    \node[rotate=90, anchor=south]
                    at ([xshift=10mm]current axis.east)
                    {Warm s. (---), Cold s. (- - -)};
                },
            ]

            \foreach \F/\col/\mark in
            {3/KITred/triangle,2/KITblue/diamond,1/KITorange/square} {
                \edef\temp{\noexpand
                    \addplot+[
                        mark=\mark, densely dashed, mark options={fill=\col},
                        \col, forget plot
                    ]
                    table[
                        col sep=comma, x=physical_p,
                        y=LER_per_round,
                    ]
                    {res/sim/WF/WindowingSyndromeMinSumDecoder/max_iter_200/pass_soft_info_False/F_\F/W_5/LERs.csv};
                }
                \temp
            }

            \foreach \F/\col/\mark in
            {3/KITred/triangle*,2/KITblue/diamond*,1/KITorange/square*} {
                \edef\temp{\noexpand
                    \addplot+[mark=\mark, solid, mark
                    options={fill=\col}, \col]
                    table[
                        col sep=comma, x=physical_p,
                        y=LER_per_round,
                    ]
                    {res/sim/WF/WindowingSyndromeMinSumDecoder/max_iter_200/pass_soft_info_True/F_\F/W_5/LERs.csv};
                }
                \temp

                \addlegendentryexpanded{$F = \F$}
            }
        \end{axis}
    \end{tikzpicture}

    \caption{
        Comparison of the decoding performance of cold and warm-start
        decoding under the $\llbracket 144,12,12 \rrbracket$ \ac{bb}
        code for different step sizes.
        Decoding was performed using the min-sum algorithm ($200$
        iterations).
        The window size was fixed to $W=5$, $12$ rounds of syndrome
        extraction were performed and the noise model is
        standard circuit-based depolarizing noise.
    }
\end{figure}

\begin{figure}[H]
    \centering
    \begin{subfigure}{0.48\textwidth}
        \centering
        \hspace*{-6mm}
        \begin{tikzpicture}
            \begin{axis}[
                    width=8cm,
                    height=6cm,
                    ymode=log,
                    % xmode=log,
                    legend style={
                        cells={anchor=west},
                        cells={align=left},
                    },
                    enlargelimits=false,
                    ymin=1e-3, ymax=1e-1,
                    grid=both,
                    legend pos = north east,
                    xtick={32,512,1024,2048,4096},
                    % xtick={0.001,0.0015,...,0.004},
                    xticklabels =
                    {$32$,$512$,$1{,}024$,,$2{,}048$,,$3{,}072$,,$4{,}096$},
                    xtick={32, 512, 1024, 1536, 2048, 2560, 3072, 3584, 4096},
                    xticklabel style={/pgf/number format/fixed},
                    xticklabel style={/pgf/number format/precision=4},
                    x tick label style={rotate=45, anchor=north east,
                    inner sep=1mm},
                    scaled x ticks=false,
                    xlabel={Number of BP iterations},
                    ylabel={Per-round-LER},
                    % extra description/.code={
                    %     \node[rotate=90, anchor=south]
                    %     at ([xshift=10mm]current axis.east)
                    %     {Warm s. (---), Cold s. (- - -)};
                    % },
                ]

                \foreach \W/\col/\mark in
                {3/KITred/triangle,4/KITblue/diamond,5/KITorange/square} {
                    \edef\temp{\noexpand
                        \addplot+[mark=\mark, densely dashed,
                        forget plot, \col]
                        table[
                            col sep=comma, x=max_iter,
                            y=LER_per_round,
                        ]
                        {res/sim/max_iter/WindowingSyndromeMinSumDecoder/p_0.0025/pass_soft_info_False/F_1/W_\W/LERs.csv};
                    }
                    \temp
                }

                \foreach \W/\col/\mark in
                {3/KITred/triangle*,4/KITblue/diamond*,5/KITorange/square*} {
                    \edef\temp{\noexpand
                        \addplot+[mark=\mark, solid, mark
                        options={fill=\col}, \col]
                        table[
                            col sep=comma, x=max_iter,
                            y=LER_per_round,
                        ]
                        {res/sim/max_iter/WindowingSyndromeMinSumDecoder/p_0.0025/pass_soft_info_True/F_1/W_\W/LERs.csv};
                    }
                    \temp

                    \addlegendentryexpanded{$W = \W$}
                }
            \end{axis}
        \end{tikzpicture}

        \caption{Comparison of window sizes for $F=1$.}
    \end{subfigure}%
    \hfill%
    \begin{subfigure}{0.48\textwidth}
        \centering
        \begin{tikzpicture}
            \begin{axis}[
                    width=8cm,
                    height=6cm,
                    ymode=log,
                    % xmode=log,
                    legend style={
                        cells={anchor=west},
                        cells={align=left},
                    },
                    enlargelimits=false,
                    ymin=1e-3, ymax=1e-1,
                    grid=both,
                    legend pos = north east,
                    xtick={32,512,1024,2048,4096},
                    % xtick={0.001,0.0015,...,0.004},
                    xticklabels =
                    {$32$, $512$,$1{,}024$,,$2{,}048$,,$3{,}072$,,$4{,}096$},
                    xtick={32, 512, 1024, 1536, 2048, 2560, 3072, 3584, 4096},
                    xticklabel style={/pgf/number format/fixed},
                    xticklabel style={/pgf/number format/precision=4},
                    x tick label style={rotate=45, anchor=north east,
                    inner sep=1mm},
                    scaled x ticks=false,
                    xlabel={Number of BP iterations},
                    yticklabels={\empty},
                    % ylabel={Per-round-LER},
                    extra description/.code={
                        \node[rotate=90, anchor=south]
                        at ([xshift=10mm]current axis.east)
                        {Warm s. (---), Cold s. (- - -)};
                    },
                ]

                \foreach \F/\col/\mark in
                {3/KITred/triangle,2/KITblue/diamond,1/KITorange/square} {
                    \edef\temp{\noexpand
                        \addplot+[mark=\mark, densely dashed,
                        forget plot, \col]
                        table[
                            col sep=comma, x=max_iter,
                            y=LER_per_round,
                        ]
                        {res/sim/max_iter/WindowingSyndromeMinSumDecoder/p_0.0025/pass_soft_info_False/F_\F/W_5/LERs.csv};
                    }
                    \temp
                }

                \foreach \F/\col/\mark in
                {3/KITred/triangle*,2/KITblue/diamond*,1/KITorange/square*} {
                    \edef\temp{\noexpand
                        \addplot+[mark=\mark, solid, mark
                        options={fill=\col}, \col]
                        table[
                            col sep=comma, x=max_iter,
                            y=LER_per_round,
                        ]
                        {res/sim/max_iter/WindowingSyndromeMinSumDecoder/p_0.0025/pass_soft_info_True/F_\F/W_5/LERs.csv};
                    }
                    \temp

                    \addlegendentryexpanded{$F = \F$}
                }
            \end{axis}
        \end{tikzpicture}

        \caption{Comparison of step sizes for $W=5$.}
    \end{subfigure}

    \caption{
        Comparison of cold and warm-start sliding-window
        min-sum decoding for the $\llbracket 144, 12, 12 \rrbracket$
        \ac{bb} code
        under circuit-level noise.
        $12$ rounds of syndrome extraction were performed and
        standard circuit-based depolarizing noise was chosen as the
        noise model.
        The physical error probabilty was fixed to $0.0025$.
    }
\end{figure}

%%%%%%%%%%%%%%%%
\subsection{Belief Propagation with Guided Decimation}
\label{subsec:Belief Propagation with Guided Decimation}

\begin{figure}[H]
    \centering
    \hspace*{-6mm}
    \begin{subfigure}{0.5\textwidth}
        \centering
        \begin{tikzpicture}
            \begin{axis}[
                    width=8cm,
                    height=6cm,
                    ymode=log,
                    legend style={
                        cells={anchor=west},
                        cells={align=left},
                    },
                    enlargelimits=false,
                    ymin=1e-5, ymax=2e-1,
                    grid=both,
                    legend pos = south east,
                    xtick={0.001,0.0015,...,0.004},
                    xticklabel style={/pgf/number format/fixed},
                    xticklabel style={/pgf/number format/precision=4},
                    x tick label style={rotate=45, anchor=north east,
                    inner sep=1mm},
                    scaled x ticks=false,
                    xlabel={Physical error rate},
                    ylabel={Per-round-LER},
                    % extra description/.code={
                    %     \node[rotate=90, anchor=south]
                    %     at ([xshift=10mm]current axis.east)
                    %     {Warm s. (---), Cold s. (- - -)};
                    % },
                ]

                \foreach \W/\col/\mark in
                {3/KITred/triangle,4/KITblue/diamond,5/KITorange/square} {
                    \edef\temp{\noexpand
                        \addplot+[
                            mark=\mark, densely dashed, mark
                            options={fill=\col},
                            \col, forget plot
                        ]
                        table[
                            col sep=comma, x=physical_p,
                            y=LER_per_round,
                        ]
                        {res/sim/WF/WindowingSyndromeSpaGdDecoder/max_iter_5000/pass_soft_info_False/F_1/W_\W/LERs.csv};
                    }
                    \temp
                }

                \foreach \W/\col/\mark in
                {3/KITred/triangle*,4/KITblue/diamond*,5/KITorange/square*} {
                    \edef\temp{\noexpand
                        \addplot+[mark=\mark, solid, mark
                        options={fill=\col}, \col]
                        table[
                            col sep=comma, x=physical_p,
                            y=LER_per_round,
                        ]
                        {res/sim/WF/WindowingSyndromeSpaGdDecoderPassDecimation/max_iter_5000/pass_soft_info_True/F_1/W_\W/LERs.csv};
                    }
                    \temp

                    \addlegendentryexpanded{$W = \W$}
                }
            \end{axis}
        \end{tikzpicture}

        \caption{Comparison of window sizes for $F=1$.}
    \end{subfigure}%
    \hfill%
    \begin{subfigure}{0.5\textwidth}
        \centering
        \begin{tikzpicture}
            \begin{axis}[
                    width=8cm,
                    height=6cm,
                    ymode=log,
                    legend style={
                        cells={anchor=west},
                        cells={align=left},
                    },
                    enlargelimits=false,
                    ymin=1e-5, ymax=2e-1,
                    grid=both,
                    legend pos = south east,
                    xtick={0.001,0.0015,0.002,...,0.004},
                    xticklabel style={/pgf/number format/fixed},
                    xticklabel style={/pgf/number format/precision=4},
                    x tick label style={rotate=45, anchor=north east,
                    inner sep=1mm},
                    scaled x ticks=false,
                    xlabel={Physical error rate},
                    yticklabels={\empty},
                    % ylabel={Per-round-LER},
                    extra description/.code={
                        \node[rotate=90, anchor=south]
                        at ([xshift=10mm]current axis.east)
                        {Warm s. (---), Cold s. (- - -)};
                    },
                ]

                \foreach \F/\col/\mark in
                {3/KITred/triangle,2/KITblue/diamond,1/KITorange/square} {
                    \edef\temp{\noexpand
                        \addplot+[
                            mark=\mark, densely dashed, mark
                            options={fill=\col},
                            \col, forget plot
                        ]
                        table[
                            col sep=comma, x=physical_p,
                            y=LER_per_round,
                        ]
                        {res/sim/WF/WindowingSyndromeSpaGdDecoder/max_iter_5000/pass_soft_info_False/F_\F/W_5/LERs.csv};
                    }
                    \temp
                }

                \foreach \F/\col/\mark in
                {3/KITred/triangle*,2/KITblue/diamond*,1/KITorange/square*} {
                    \edef\temp{\noexpand
                        \addplot+[mark=\mark, solid, mark
                        options={fill=\col}, \col]
                        table[
                            col sep=comma, x=physical_p,
                            y=LER_per_round,
                        ]
                        {res/sim/WF/WindowingSyndromeSpaGdDecoderPassDecimation/max_iter_5000/pass_soft_info_True/F_\F/W_5/LERs.csv};
                    }
                    \temp

                    \addlegendentryexpanded{$F = \F$}
                }
            \end{axis}
        \end{tikzpicture}

        \caption{Comparison of step sizes for $W=5$.}
    \end{subfigure}

    \caption{
        Comparison of the decoding performance of cold and warm-start
        decoding under the $\llbracket 144,12,12 \rrbracket$ \ac{bb}.
        Decoding was performed using the \ac{bpgd} algorithm with
        $T=1$ and no limit on the number of outer iterations.
        The information used for the warm-start intialization
        included both the messages on the Tanner graph and decimation
        information.
        $12$ rounds of syndrome extraction were performed and
        standard circuit-based depolarizing noise was chosen as the
        noise model.
    }
\end{figure}

\begin{figure}[H]
    \centering
    \hspace*{-6mm}
    \begin{subfigure}{0.48\textwidth}
        \centering
        \begin{tikzpicture}
            \begin{axis}[
                    width=8cm,
                    height=6cm,
                    ymode=log,
                    % xmode=log,
                    legend style={
                        cells={anchor=west},
                        cells={align=left},
                    },
                    enlargelimits=false,
                    ymin=1e-3, ymax=1e-1,
                    grid=both,
                    legend pos = south west,
                    xtick={32,512,1024,2048,4096},
                    % xtick={0.001,0.0015,...,0.004},
                    xticklabels =
                    {$32$,$512$,$1{,}024$,,$2{,}048$,,$3{,}072$,,$4{,}096$},
                    xtick={32, 512, 1024, 1536, 2048, 2560, 3072, 3584, 4096},
                    xticklabel style={/pgf/number format/fixed},
                    xticklabel style={/pgf/number format/precision=4},
                    x tick label style={rotate=45, anchor=north east,
                    inner sep=1mm},
                    scaled x ticks=false,
                    xlabel={Number of BP iterations},
                    ylabel={Per-round-LER},
                    % extra description/.code={
                    %     \node[rotate=90, anchor=south]
                    %     at ([xshift=10mm]current axis.east)
                    %     {Warm s. (---), Cold s. (- - -)};
                    % },
                ]

                \foreach \W/\col/\mark in
                {3/KITred/triangle,4/KITblue/diamond,5/KITorange/square} {
                    \edef\temp{\noexpand
                        \addplot+[mark=\mark, densely dashed,
                        forget plot, \col]
                        table[
                            col sep=comma, x=max_iter,
                            y=LER_per_round,
                        ]
                        {res/sim/max_iter/WindowingSyndromeSpaGdDecoderPassDecimation/p_0.0025/pass_soft_info_False/F_1/W_\W/LERs.csv};
                    }
                    \temp
                }

                \foreach \W/\col/\mark in
                {3/KITred/triangle*,4/KITblue/diamond*,5/KITorange/square*} {
                    \edef\temp{\noexpand
                        \addplot+[mark=\mark, solid, mark
                        options={fill=\col}, \col]
                        table[
                            col sep=comma, x=max_iter,
                            y=LER_per_round,
                        ]
                        {res/sim/max_iter/WindowingSyndromeSpaGdDecoderPassDecimation/p_0.0025/pass_soft_info_True/F_1/W_\W/LERs.csv};
                    }
                    \temp

                    \addlegendentryexpanded{$W = \W$}
                }
            \end{axis}
        \end{tikzpicture}

        \caption{Comparison of window sizes for $F=1$.}
    \end{subfigure}%
    \hfill%
    \begin{subfigure}{0.48\textwidth}
        \centering
        \begin{tikzpicture}
            \begin{axis}[
                    width=8cm,
                    height=6cm,
                    ymode=log,
                    % xmode=log,
                    legend style={
                        cells={anchor=west},
                        cells={align=left},
                    },
                    enlargelimits=false,
                    ymin=1e-3, ymax=1e-1,
                    grid=both,
                    legend pos = south west,
                    xtick={32,512,1024,2048,4096},
                    % xtick={0.001,0.0015,...,0.004},
                    xticklabels =
                    {$32$,$512$,$1{,}024$,,$2{,}048$,,$3{,}072$,,$4{,}096$},
                    xtick={32, 512, 1024, 1536, 2048, 2560, 3072, 3584, 4096},
                    xticklabel style={/pgf/number format/fixed},
                    xticklabel style={/pgf/number format/precision=4},
                    x tick label style={rotate=45, anchor=north east,
                    inner sep=1mm},
                    scaled x ticks=false,
                    xlabel={Number of BP iterations},
                    % ylabel={Per-round-LER},
                    yticklabels={\empty},
                    extra description/.code={
                        \node[rotate=90, anchor=south]
                        at ([xshift=10mm]current axis.east)
                        {Warm s. (---), Cold s. (- - -)};
                    },
                ]

                \foreach \F/\col/\mark in
                {3/KITred/triangle,2/KITblue/diamond,1/KITorange/square} {
                    \edef\temp{\noexpand
                        \addplot+[mark=\mark, densely dashed,
                        forget plot, \col]
                        table[
                            col sep=comma, x=max_iter,
                            y=LER_per_round,
                        ]
                        {res/sim/max_iter/WindowingSyndromeSpaGdDecoderPassDecimation/p_0.0025/pass_soft_info_False/F_\F/W_5/LERs.csv};
                    }
                    \temp
                }

                \foreach \F/\col/\mark in
                {3/KITred/triangle*,2/KITblue/diamond*,1/KITorange/square*} {
                    \edef\temp{\noexpand
                        \addplot+[mark=\mark, solid, mark
                        options={fill=\col}, \col]
                        table[
                            col sep=comma, x=max_iter,
                            y=LER_per_round,
                        ]
                        {res/sim/max_iter/WindowingSyndromeSpaGdDecoderPassDecimation/p_0.0025/pass_soft_info_True/F_\F/W_5/LERs.csv};
                    }
                    \temp

                    \addlegendentryexpanded{$F = \F$}
                }
            \end{axis}
        \end{tikzpicture}

        \caption{
            Comparison of step sizes for $W=5$.
        }
    \end{subfigure}

    \caption{
        Comparison of the decoding performance of cold and warm-start
        decoding for the $\llbracket 144,12,12 \rrbracket$ \ac{bb}
        under circuit-level noise.
        Decoding was performed using the \ac{bpgd} algorithm with
        $T=1$.
        The number of iterations refers to the outer \ac{bpgd}
        iterations, i.e., the number of decimations.
        The information used for the warm-start intialization
        included only the messages on the Tanner graph.
        $12$ rounds of syndrome extraction were performed and
        standard circuit-based depolarizing noise was chosen as the
        noise model.
        The physical error probabilty was fixed to $0.0025$.
    }
\end{figure}

\begin{figure}[H]
    \centering
    \hspace*{-6mm}
    \begin{subfigure}{0.5\textwidth}
        \centering
        \begin{tikzpicture}
            \begin{axis}[
                    width=8cm,
                    height=6cm,
                    ymode=log,
                    legend style={
                        cells={anchor=west},
                        cells={align=left},
                    },
                    enlargelimits=false,
                    ymin=1e-5, ymax=2e-1,
                    grid=both,
                    legend pos = south east,
                    xtick={0.001,0.0015,...,0.004},
                    xticklabel style={/pgf/number format/fixed},
                    xticklabel style={/pgf/number format/precision=4},
                    x tick label style={rotate=45, anchor=north east,
                    inner sep=1mm},
                    scaled x ticks=false,
                    xlabel={Physical error rate},
                    ylabel={Per-round-LER},
                    % extra description/.code={
                    %     \node[rotate=90, anchor=south]
                    %     at ([xshift=10mm]current axis.east)
                    %     {Warm s. (---), Cold s. (- - -)};
                    % },
                ]

                \foreach \W/\col/\mark in
                {3/KITred/triangle,4/KITblue/diamond,5/KITorange/square} {
                    \edef\temp{\noexpand
                        \addplot+[
                            mark=\mark, densely dashed, mark
                            options={fill=\col},
                            \col, forget plot
                        ]
                        table[
                            col sep=comma, x=physical_p,
                            y=LER_per_round,
                        ]
                        {res/sim/WF/WindowingSyndromeSpaGdDecoder/max_iter_5000/pass_soft_info_False/F_1/W_\W/LERs.csv};
                    }
                    \temp
                }

                \foreach \W/\col/\mark in
                {3/KITred/triangle*,4/KITblue/diamond*,5/KITorange/square*} {
                    \edef\temp{\noexpand
                        \addplot+[mark=\mark, solid, mark
                        options={fill=\col}, \col]
                        table[
                            col sep=comma, x=physical_p,
                            y=LER_per_round,
                        ]
                        {res/sim/WF/WindowingSyndromeSpaGdDecoder/max_iter_5000/pass_soft_info_True/F_1/W_\W/LERs.csv};
                    }
                    \temp

                    \addlegendentryexpanded{$W = \W$}
                }
            \end{axis}
        \end{tikzpicture}

        \caption{Comparison of window sizes for $F=1$.}
    \end{subfigure}%
    \hfill%
    \begin{subfigure}{0.5\textwidth}
        \centering
        \begin{tikzpicture}
            \begin{axis}[
                    width=8cm,
                    height=6cm,
                    ymode=log,
                    legend style={
                        cells={anchor=west},
                        cells={align=left},
                    },
                    enlargelimits=false,
                    ymin=1e-5, ymax=2e-1,
                    grid=both,
                    legend pos = south east,
                    xtick={0.001,0.0015,0.002,...,0.004},
                    xticklabel style={/pgf/number format/fixed},
                    xticklabel style={/pgf/number format/precision=4},
                    x tick label style={rotate=45, anchor=north east,
                    inner sep=1mm},
                    scaled x ticks=false,
                    xlabel={Physical error rate},
                    yticklabels={\empty},
                    % ylabel={Per-round-LER},
                    extra description/.code={
                        \node[rotate=90, anchor=south]
                        at ([xshift=10mm]current axis.east)
                        {Warm s. (---), Cold s. (- - -)};
                    },
                ]

                \foreach \F/\col/\mark in
                {3/KITred/triangle,2/KITblue/diamond,1/KITorange/square} {
                    \edef\temp{\noexpand
                        \addplot+[
                            mark=\mark, densely dashed, mark
                            options={fill=\col},
                            \col, forget plot
                        ]
                        table[
                            col sep=comma, x=physical_p,
                            y=LER_per_round,
                        ]
                        {res/sim/WF/WindowingSyndromeSpaGdDecoder/max_iter_5000/pass_soft_info_False/F_\F/W_5/LERs.csv};
                    }
                    \temp
                }

                \foreach \F/\col/\mark in
                {3/KITred/triangle*,2/KITblue/diamond*,1/KITorange/square*} {
                    \edef\temp{\noexpand
                        \addplot+[mark=\mark, solid, mark
                        options={fill=\col}, \col]
                        table[
                            col sep=comma, x=physical_p,
                            y=LER_per_round,
                        ]
                        {res/sim/WF/WindowingSyndromeSpaGdDecoder/max_iter_5000/pass_soft_info_True/F_\F/W_5/LERs.csv};
                    }
                    \temp

                    \addlegendentryexpanded{$F = \F$}
                }
            \end{axis}
        \end{tikzpicture}

        \caption{Comparison of step sizes for $W=5$.}
    \end{subfigure}

    \caption{
        Comparison of the decoding performance of cold and warm-start
        decoding for the $\llbracket 144,12,12 \rrbracket$ \ac{bb}
        under circuit-level noise.
        Decoding was performed using the \ac{bpgd} algorithm with
        $T=1$ and no limit on the number of outer iterations.
        The information used for the warm-start intialization
        included only the messages on the Tanner graph.
        $12$ rounds of syndrome extraction were performed and
        standard circuit-based depolarizing noise was chosen as the
        noise model.
    }
\end{figure}

\begin{figure}[H]
    \centering
    \hspace*{-6mm}
    \begin{subfigure}{0.48\textwidth}
        \centering
        \begin{tikzpicture}
            \begin{axis}[
                    width=8cm,
                    height=6cm,
                    ymode=log,
                    % xmode=log,
                    legend style={
                        cells={anchor=west},
                        cells={align=left},
                    },
                    enlargelimits=false,
                    ymin=1e-3, ymax=1e-1,
                    grid=both,
                    legend pos = north east,
                    xtick={32,512,1024,2048,4096},
                    % xtick={0.001,0.0015,...,0.004},
                    xticklabels =
                    {$32$,$512$,$1{,}024$,,$2{,}048$,,$3{,}072$,,$4{,}096$},
                    xtick={32, 512, 1024, 1536, 2048, 2560, 3072, 3584, 4096},
                    xticklabel style={/pgf/number format/fixed},
                    xticklabel style={/pgf/number format/precision=4},
                    x tick label style={rotate=45, anchor=north east,
                    inner sep=1mm},
                    scaled x ticks=false,
                    xlabel={Number of BP iterations},
                    ylabel={Per-round-LER},
                    % extra description/.code={
                    %     \node[rotate=90, anchor=south]
                    %     at ([xshift=10mm]current axis.east)
                    %     {Warm s. (---), Cold s. (- - -)};
                    % },
                ]

                \foreach \W/\col/\mark in
                {3/KITred/triangle,4/KITblue/diamond,5/KITorange/square} {
                    \edef\temp{\noexpand
                        \addplot+[mark=\mark, densely dashed,
                        forget plot, \col]
                        table[
                            col sep=comma, x=max_iter,
                            y=LER_per_round,
                        ]
                        {res/sim/max_iter/WindowingSyndromeSpaGdDecoder/p_0.0025/pass_soft_info_False/F_1/W_\W/LERs.csv};
                    }
                    \temp
                }

                \foreach \W/\col/\mark in
                {3/KITred/triangle*,4/KITblue/diamond*,5/KITorange/square*} {
                    \edef\temp{\noexpand
                        \addplot+[mark=\mark, solid, mark
                        options={fill=\col}, \col]
                        table[
                            col sep=comma, x=max_iter,
                            y=LER_per_round,
                        ]
                        {res/sim/max_iter/WindowingSyndromeSpaGdDecoder/p_0.0025/pass_soft_info_True/F_1/W_\W/LERs.csv};
                    }
                    \temp

                    \addlegendentryexpanded{$W = \W$}
                }
            \end{axis}
        \end{tikzpicture}

        \caption{Comparison of window sizes for $F=1$.}
    \end{subfigure}%
    \hfill%
    \begin{subfigure}{0.48\textwidth}
        \centering
        \begin{tikzpicture}
            \begin{axis}[
                    width=8cm,
                    height=6cm,
                    ymode=log,
                    % xmode=log,
                    legend style={
                        cells={anchor=west},
                        cells={align=left},
                    },
                    enlargelimits=false,
                    ymin=1e-3, ymax=1e-1,
                    grid=both,
                    legend pos = north east,
                    xtick={32,512,1024,2048,4096},
                    % xtick={0.001,0.0015,...,0.004},
                    xticklabels =
                    {$32$,$512$,$1{,}024$,,$2{,}048$,,$3{,}072$,,$4{,}096$},
                    xtick={32, 512, 1024, 1536, 2048, 2560, 3072, 3584, 4096},
                    xticklabel style={/pgf/number format/fixed},
                    xticklabel style={/pgf/number format/precision=4},
                    x tick label style={rotate=45, anchor=north east,
                    inner sep=1mm},
                    scaled x ticks=false,
                    xlabel={Number of BP iterations},
                    % ylabel={Per-round-LER},
                    yticklabels={\empty},
                    extra description/.code={
                        \node[rotate=90, anchor=south]
                        at ([xshift=10mm]current axis.east)
                        {Warm s. (---), Cold s. (- - -)};
                    },
                ]

                \foreach \F/\col/\mark in
                {3/KITred/triangle,2/KITblue/diamond,1/KITorange/square} {
                    \edef\temp{\noexpand
                        \addplot+[mark=\mark, densely dashed,
                        forget plot, \col]
                        table[
                            col sep=comma, x=max_iter,
                            y=LER_per_round,
                        ]
                        {res/sim/max_iter/WindowingSyndromeSpaGdDecoder/p_0.0025/pass_soft_info_False/F_\F/W_5/LERs.csv};
                    }
                    \temp
                }

                \foreach \F/\col/\mark in
                {3/KITred/triangle*,2/KITblue/diamond*,1/KITorange/square*} {
                    \edef\temp{\noexpand
                        \addplot+[mark=\mark, solid, mark
                        options={fill=\col}, \col]
                        table[
                            col sep=comma, x=max_iter,
                            y=LER_per_round,
                        ]
                        {res/sim/max_iter/WindowingSyndromeSpaGdDecoder/p_0.0025/pass_soft_info_True/F_\F/W_5/LERs.csv};
                    }
                    \temp

                    \addlegendentryexpanded{$F = \F$}
                }
            \end{axis}
        \end{tikzpicture}

        \caption{
            Comparison of step sizes for $W=5$.
        }
    \end{subfigure}

    \caption{
        Comparison of the decoding performance of cold and warm-start
        decoding for the $\llbracket 144,12,12 \rrbracket$ \ac{bb}
        under circuit-level noise.
        Decoding was performed using the \ac{bpgd} algorithm with
        $T=1$.
        The number of iterations refers to the outer \ac{bpgd}
        iterations, i.e., the number of decimations.
        The information used for the warm-start intialization
        included only the messages on the Tanner graph.
        $12$ rounds of syndrome extraction were performed and
        standard circuit-based depolarizing noise was chosen as the
        noise model.
        The physical error probabilty was fixed to $0.0025$.
    }
\end{figure}

