%==============================================================================
\chapter{In silico quantitative mapping of force-pCa curves to whole heart contraction and relaxation}\label{cha:chapter8}
%==============================================================================
%
%
%
\begin{remark}{Outline}
    In this chapter, we focus on the assessment of the steady-state F-pCa relationship (this is traditionally used to assess the myofilament $\Ca$ sensitivity) and its quantitative mapping to the LV contractile function. We start by investigating the F-pCa curve using the cell contraction sub-model of our full personalised SHAM rat heart contraction model (Section~\ref{sec:cellcontr}). Next, using a combination of simulators and emulators (Section~\ref{subsec:quantlink}), we show that changes in key features of the F-pCa curve cannot be uniquely described by changes in the sarcomere properties (Sections~\ref{sec:changespCa50result1}--\ref{sec:changespCa50result2}). At the same time, we show that changes in the LV function (e.g. ejection fraction, isovolumetric relaxation time, peak pressure) cannot be uniquely described by changes in the sarcomere properties (Section~\ref{sec:changesLVfunctionresult}). By coupling these two pieces of information, we demonstrate that the mapping from the F-pCa curve to the LV function and the corresponding inverse mapping are non-unique (Section~\ref{sec:ch8nonuniquemappings}). We then include a discussion of results and address specific limitations (Section~\ref{sec:ch8discussion}), and we conclude with a brief summary (Section~\ref{sec:ch8summary}).
\end{remark}

%
%
%
\section{Motivation}\label{sec:ch8motivation}
One potential assessment for sarcomere modulators is their impact on the F-pCa~\cite{Walker:2010}, which is a technique that is widely used in many HF diseases including rare/genetic diseases such as dilated and hypertrophic cardiomyopathies~\cite{Groen:2020,Bai:2013,Michael:2016,Kirschner:2005,Harris:2002}, as well as for HF with reduced and preserved ejection fraction~\cite{Nagy:2015,Kampourakis:2018,Kieu:2019,Awinda:2021,Mamidi:2018,Sparrow:2020}. The impact on the F-pCa curve is often examined in terms of observed shifts in the curve half-maximal activation ($\pCaf$), which is used as an index of $\Ca$ sensitivity. Leftward shifts in the $\pCaf$ are expected to improve contractility, whereas rightward shifts to decrease contractility. Sometimes there is an assumption that changes in $\Ca$ sensitivity are a surrogate for changes in whole heart function and that these changes are monotonic in that, for instance, an increase in myofilament $\Ca$ sensitivity (i.e. a leftward shift) would improve the whole heart cardiac output. In this case study, whose related manuscript is currently in submission~\cite{Longobardi:2022}, we discuss the limitations of such an assumption and demonstrate why the dynamic whole heart behaviour cannot be predicted or assessed with a shift in the F-pCa curve alone.

\vspace{0.2cm}
We use a mathematical model of active tension generation at the sarcomere level in LV rat myocytes to elucidate the relationship between sarcomere properties and the steady-state F-pCa curve. We next use our previously developed multi-scale model of SHAM rat heart, which integrates the cell tension model within a $3$D biventricular rat heart contraction model (Section~\ref{sec:ch7rat_heart_contraction_model}) and provides a quantitative link between sarcomere properties and whole heart contractile function to investigate the mapping from F-pCa curves to the LV function. In particular, using our framework, we are able to quantitatively link changes in the F-pCa curve to/from changes in the LV function for the first time to the best of our knowledge. Previously, shifts in the F-pCa curve were linked to changes in cellular tension~\cite{Chung:2016} but not to the whole-organ dynamic contractile behaviour and without investigating the inverse mapping. We use our modelling framework to show that observations made at the sarcomere level (e.g. a leftward shift in the F-pCa curve) do not uniquely map to desired effects at the whole-organ level (e.g. an increase in EF or improved relaxation). We also show that the opposite holds: given a change in LV function, there exist many ways this could have been achieved through sarcomeric modulation, and thus the same change in LV function can correspond to different shifts in the F-pCa curve. The implications of these phenomena on using F-pCa curves to interpret whole heart dynamics are discussed in Section~\ref{sec:ch8discussion}.

%
%
%
\section{Methods}\label{sec:ch8methods}

%
%
%
\subsection{Cellular contraction model}\label{sec:cellcontr}
We employed the Land et al.~\cite{Land:2012} myocyte contraction model (Section~\ref{sec:ch2contractionmodel}) to simulate active tension generation at the sarcomere level and isometric steady-state F-pCa relationship in the rat heart. Parameters were all set to the personalised SHAM rat model values (Table~\ref{tab:bestfitparametersvalues}) when applicable, or to the Land et al.~\cite{Land:2012} model baseline values when otherwise.

\vspace{0.2cm}
We recall that an experimentally derived F-pCa curve can be described by a Hill-type relationship between the force ($F$) and the negative logarithm of the $\Ca$ concentration ($\pCa$)~\cite{Walker:2010}:
%
\begin{equation}
    \frac{F}{F_0} = \frac{1}{1+10^{h(\pCaf-\pCa)}}
\end{equation}

\noindent
where $F_{0}$ is the maximal reference force and $\pCaf$ and $h$ are, respectively, the negative logarithm of the half-maximal effective $\Ca$ concentration and the Hill coefficient of this relationship. It immediately follows that F-pCa curves are uniquely determined by the $\pCaf$ and $h$ values. We have also seen that the steady-state force solution of the Land et al.~\cite{Land:2012} model can be derived analytically, where both the $\pCaf$ and $h$ features are expressed in terms of model parameters. In particular, we recall that the $\pCaf$ was given as:
%
\begin{align}
    & \pCaf(\mathbf{p}) =  -\log\left[\Caif\left(\frac{\koff}{\kon}\frac{\trpnf}{1-\trpnf}\right)^{1/\ntrpn}\right]\,,\quad\text{with} \label{eq:pCa50}\\
    & \mathbf{p} := (\Caif, \kon, \koff, \trpnf, \ntrpn) \label{eq:pCa50params}
\end{align}

\vspace{0.2cm}\noindent
In the next section, we shall make use of equations~\eqref{eq:pCa50}--\eqref{eq:pCa50params} to investigate on F-pCa curve shifts.

%
%
%
\subsection{Non-unique mapping of changes in $\pCaf$ to changes in sarcomere properties}\label{sec:changespCa50}
A given change ($\Delta$) in the $\pCaf$ feature value of the F-pCa curve can be written as:
%
\begin{equation}\label{eq:delta}
    \Delta = \pCaf^{\text{new}} - \pCaf
\end{equation}

\vspace{0.2cm}\noindent
where $\pCaf^{\text{new}}$ is the feature value characterising the newly observed F-pCa curve. We tested whether a shift of $\Delta$ units in the $\pCaf$ could be the result of unique changes in sarcomere properties. Testing for non-unique changes was carried out analytically and numerically (as visualised in Figure~\ref{fig:2perclwrwshift}) in the case where the change was driven by perturbations in one model parameter (Section~\ref{sec:changespCa50result1}), and numerically (as visualised in Figure~\ref{fig:pca50isolines}) in the case where this was driven by perturbations in two model parameters (Section~\ref{sec:changespCa50result2}).

\vspace{0.2cm}
In the one-parameter case, it sufficed to prove that for each parameter $p_i,\,i=1,\,\dots,\,5$ of equation~\eqref{eq:pCa50params} there exists a scaling coefficient $\alpha_i\in\mathbb{R}$ such that
%
\begin{equation}
    \mathbf{p}^{\text{new}} := (p_1,\,\dots,\,\p_{i-1},\,\alpha_i\times\p_i,\,p_{i+1},\,\dots,\,p_5)
\end{equation}

\noindent
is such that
%
\begin{equation}
    \pCaf^{\text{new}} = \pCaf(\mathbf{p}^{\text{new}})
\end{equation}

\vspace{0.2cm}\noindent
We computed this scaling coefficient for each parameter $\p_i$ by solving for $\alpha_i$ equation~\eqref{eq:delta} for a given $\Delta$.

\vspace{0.2cm}
In the two-parameter case, we proceeded as follows. We allowed $2$ parameters to take equally-spaced values within a $\pm\SI{50}{\percent}$ perturbation around their baseline values (Table~\ref{tab:bestfitparametersvalues}). We then generated a $2$D uniform grid from all the combinations of $2$ parameter values and used the Land et al.~\cite{Land:2012} cell contraction model to calculate the $\pCaf$ value at each parameter point of the grid. By plotting the resulting $\pCaf$ values across the grid as a heat map, we could discern regions in the $2$D parameter space that share the same $\pCaf$ value (isolines). The same process was repeated for pairs of parameters coming from vector $\mathbf{p}$ (equation~\eqref{eq:pCa50params}), which was shown to regulate the $\pCaf$ feature of the F-pCa curve (equation~\eqref{eq:pCa50}).

%
%
%
\subsection{The relationship between sarcomere properties and LV function}\label{subsec:quantlink}
To quantitatively link sarcomere properties to the LV function, we employed the personalised model of $3$D biventricular healthy (SHAM) rat heart contraction derived in Chapter~\ref{cha:chapter4} and extended in Chapter~\ref{cha:chapter7}. This model integrates the Land et al.~\cite{Land:2012} cell contraction model in the context of whole-organ simulations.

\vspace{0.2cm}
We have seen (Section~\ref{sec:ch7rat_heart_contraction_model}) that this model can be represented as a multi-scale function (simulator) that maps a $16$D vector of input parameters $\mathbf{x}$ to a scalar quantity of interest $y_j$ (e.g. $y_1=\textrm{EDV}$, $y_2=\textrm{ESV}$, etc.):
%
\begin{align}\label{eq:fsimul}
    f_{\textrm{simul}}\colon\mathbb{R}^{16} &\to\mathbb{R}\times\mathbb{R}\times\dots \\
    \mathbf{x} &\mapsto (y_1,\,y_2,\dots) \nonumber
\end{align}

\vspace{0.2cm}\noindent
At the same time, we have replaced (Section~\ref{sec:ch7training_dataset_emulators_global_sensitivity_analysis}) the simulator with a fast-evaluating surrogate model (emulator), based on Gaussian process emulation.

\vspace{0.2cm}
We used the simulator to investigate the dependence of LV volume features, namely EDV, ESV, SV, and EF, on model parameters. Specifically, we were interested in the dependence of the features on the $\Caif$, $\koff$, $\ntrpn$ and $\trpnf$ parameters as these directly modulated the $\pCaf$ feature of the F-pCa curve (equation~\eqref{eq:pCa50}). For each parameter, we performed the following operations. First, the simulator was run at $128$ input points $\mathbf{x}_i,\,i=1,\dots,128$, which had all their $16$ components fixed to baseline values (Table~\ref{tab:bestfitparametersvalues}) but the component corresponding to the examined parameter, which instead was set to $128$ equally-spaced values between $-\SI{50}{\percent}$ and $\SI{50}{\percent}$ of perturbation values from baseline. The LV volume features were then extracted from the simulated $128$ LV volume transients so that we could plot the variation of each feature as a function of the parameter variations around its baseline value.

\vspace{0.2cm}
We then used the emulator to perform a GPE-based GSA. We calculated the Sobol' first-order, second-order and total effects (Section~\ref{sec:ch3globalsensitivityanalysis}) as a measure of model outputs' sensitivity to model inputs. We evaluated the impact of $\Caif$, $\koff$, $\ntrpn$, $\trpnf$ parameters into affecting the total variance of EDV, ESV, SV, EF features. Parameters whose Sobol' indices' distributions' expectation was below the threshold $0.01$ were determined to have negligible effects.

%
%
%
\subsection{Non-unique mapping of changes in LV function to changes in sarcomere properties}\label{sec:changesLVfunction}
Left ventricular EF can be continuously monitored noninvasively as an index of LV systolic function in patients enrolled for clinical trials investigating HF treating drugs. However, it is important to discern whether detected changes in the EF value directly result from a specific cellular modulation caused by the administered drug or not. From a modelling perspective and in the context of sarcomere modulators, we can test whether changes observed in the LV function at the whole-organ level, as described by the EF feature, can be uniquely explained in terms of sarcomere properties' changes.

\vspace{0.2cm}
We therefore proceeded as in Section~\ref{sec:changespCa50} by generating a $2$D uniform grid of parameter values for each considered pair of parameters modulating the F-pCa curve (equation~\eqref{eq:pCa50}). We then used the emulator to predict the EF value at each parameter point of the grid. By plotting the resulting EF values across the grid as a heat map, we could again discern regions in the $2$D parameter space that share the same EF value (isolines).

%
%
%
\subsection{Non-unique mapping of F-pCa curve to LV function and of LV function to F-pCa curve}
In order to test if the mapping from the F-pCa curve to LV function is not unique, we considered all the parameter points of the $2$D grids generated in Section~\ref{sec:changespCa50} that produced the same shift in the reference $\pCaf$ feature value. As mentioned previously, these points all belong to isolines of the local $2$D parameter space. We then used the emulator to map the points to the corresponding organ-level EF value.

\vspace{0.2cm}
We also tested if the inverse mapping from the LV function to the F-pCa curve is not unique. For this purpose, we considered all the parameter points of the $2$D grids generated in Section~\ref{sec:changesLVfunction} that produced the same shift in the reference EF feature value. We then used the cellular contraction sub-model of the full simulator to map the points to the corresponding cell-level $\pCaf$ value.

%
%
%
\section{Results}

%
%
%
\subsection{Non-monotonic relationship between sarcomere parameters and LV function}
The variations of EDV, ESV, SV and EF features as a function of the $4$ considered F-pCa curve-modulating parameters (equation~\eqref{eq:pCa50}) are non-linear and non-monotonic, as shown in Figure~\ref{fig:EFvsparamsnonmonotonic}. An example of full simulator outputs comprising LV volume and pressure transients and PV loops is provided in Figure~\ref{fig:EFvskoff} for the EF-vs-$\koff$ case.

\begin{figure}[h!]
    \myfloatalign
    \includegraphics[width=\textwidth]{figures/chapter08/Fig1.pdf}
    \caption{The full $3$D biventricular rat heart contraction model is run at a fixed parameter set with only one parameter taking equally-spaced values in the $\pm\SI{50}{\percent}$ range of perturbation from its baseline value (vertical red dashed lines). The converging mechanics simulations' output PV loops are analysed to extract the corresponding EDV, ESV, SV and EF features' values (open blue dots), given as percentages from their baseline values (horizontal red dashed lines). The process is repeated separately for each parameter regulating the $\pCaf$ feature of the F-pCa curve. A linear regression (LR) model with second-order degree polynomials is fitted to the data (blue lines) to facilitate the visualisation of non-linear and non-monotonic relationships between the features and each of the parameters considered.}
    \label{fig:EFvsparamsnonmonotonic}
\end{figure}

\begin{figure}[h!]
    \myfloatalign
    \includegraphics[width=\textwidth]{figures/chapter08/Fig2.pdf}
    \caption{The full $3$D biventricular rat heart contraction model is run at a fixed parameter set with only one parameter varying around its baseline value. The resulting LV volume and pressure transients and corresponding PV loops are plotted for some of the parameter values (full lines in blue variants) and compared to the reference parameter set mechanics solution (dashed black line). Example showing $\koff$ parameter variation in the range obtained as a $\pm\SI{40}{\percent}$ perturbation of its baseline value.}
    \label{fig:EFvskoff}
\end{figure}

\vspace{0.2cm}
The obtained GSA Sobol' sensitivity indices are displayed as donut charts in Figure~\ref{fig:gsarestr}. We can see that the reference thin filament $\Ca$ sensitivity ($\Caif$) is the most important parameter in explaining the total variance of EDV, ESV, SV and EF features. The second most important parameter is the degree of cooperativity of $\Ca$ binding to TnC ($\ntrpn$), followed by the fraction of bound $\Ca$-TnC complexes for half-maximal cross-bridges activation ($\trpnf$) and the unbinding rate of $\Ca$ from TnC ($\koff$).

\begin{figure}[h!]
    \myfloatalign
    \includegraphics[width=\textwidth]{figures/chapter08/Fig3.pdf}
    \caption{The impact of $\pCaf$-modulating, sarcomere parameters on EDV, ESV, SV and EF organ-scale LV feature. The contribution of each parameter is represented by the sum of its first- and second-order effects. For each LV feature, higher-order interactions (up to the fourth order) are represented by the sum of all total effects minus the sum of all first- and second-order effects.}
    \label{fig:gsarestr}
\end{figure}

%
%
%
\subsection{$\pCaf$ changes are non-uniquely explained by sarcomere alterations: the one-parameter case}\label{sec:changespCa50result1}
We show that an observed change in $\pCaf$ can be caused by multiple different changes in sarcomere proprieties represented by model parameters. For each parameter $p_i,\,i=1,\,\dots,\,5$ of equation~\eqref{eq:pCa50params}, we report in Table~\ref{tab:alphavalues} the corresponding scaling coefficient $\alpha_i,\,i=1,\,\dots,\,5$ that would yield a shift of exactly $\Delta$ units in the $\pCaf$ value. This proves that an observed change in the F-pCa cannot be uniquely explained by a change in a specific sarcomere property. An example of $\pm\SI{2}{\percent}$ shift from a reference $\pCaf$ value is displayed in Figure~\ref{fig:2perclwrwshift}.

\begin{table}[h!]
    \myfloatalign
    \begin{tabularx}{\textwidth}{XX}
        \toprule
        \tableheadline{Parameter} & \tableheadline{Scaling coefficient $\alpha$} \\
        \midrule
        & \\
        $\Caif$ & $10^{\Delta}$ \\ & \\
        $\kon$ & $10^{-\Delta\cdot\ntrpn}$ \\ & \\
        $\koff$ & $10^{\Delta\cdot\ntrpn}$ \\ & \\
        $\trpnf$ & $\dfrac{10^{\Delta\cdot\ntrpn}}{\trpnf(10^{\Delta\cdot\ntrpn}-1)+1}$ \\ & \\
        $\ntrpn$ & $\dfrac{\log\left(\frac{\koff}{\kon}\frac{\trpnf}{1-\trpnf}\right)}{\Delta\cdot\ntrpn+\log\left(\frac{\koff}{\kon}\frac{\trpnf}{1-\trpnf}\right)}$ \\ & \\
        \bottomrule
    \end{tabularx}
    \caption{The mapping of sarcomere properties to F-pCa variations is non-unique. By scaling each parameter $p_i$ by the corresponding $\alpha_i$ coefficient, the cellular contraction model simulates a $\pCaf$ value which is shifted by exactly $\Delta$ units from the reference value.}
    \label{tab:alphavalues}
\end{table}

\begin{figure}[h!]
    \myfloatalign
    \includegraphics[width=0.8\textwidth]{figures/chapter08/Fig4.pdf}
    \caption{Different parameters can be individually perturbed to achieve the very same shift in the force-calcium relationship. Example showing $\SI{2}{\percent}$ leftwards (upper plot) and rightwards (bottom plot) shifts of the reference $\pCaf$ value. As $\trpnf$ and $\ntrpn$ also regulate the F-pCa curve's Hill coefficient (equation~\eqref{eq:h}), notice that for these two parameters the shift in the $\pCaf$ value is also affecting the curve's slope.}
    \label{fig:2perclwrwshift}
\end{figure}

%
%
%
\subsection{$\pCaf$ changes are non-uniquely explained by sarcomere alterations: the two-parameter case}\label{sec:changespCa50result2}
$\pCaf$ evaluation on $2$-parameter grids highlighted the presence of isolines, whose parameter points induce the same $\pCaf$ feature value (Figure~\ref{fig:pca50isolines}A). This means that moving between any two points on two isolines will result in the same shift in $\pCaf$, demonstrating also in the two-parameter case the non-uniqueness of changes in the half-activation of the F-pCa curve and a change in sarcomere properties.

%
%
%
\subsubsection{Non-unique mapping of F-pCa curve to LV function}\label{sec:fpcatolvnonuniquemapping}
Parameter points inducing the same shifts in the $\pCaf$ feature value (isolines of Figure~\ref{fig:pca50isolines}A) are quantitatively linked to different EF feature values (Figure~\ref{fig:pca50isolines}B), showing that the mapping from F-pCa curve to LV function is not unique.

\begin{figure}[h!]
    \myfloatalign
    \includegraphics[width=\textwidth]{figures/chapter08/Fig5.pdf}
    \caption{For each pair of parameters regulating the $\pCaf$ feature of the F-pCa curve, a $2$D uniform grid is constructed using a $\pm\SI{50}{\percent}$ perturbation around the reference parameter set values (black dots). (A) The cell contraction model is then used to calculate the $\pCaf$ feature value at every parameter point of the grid, and each grid is plotted as a heat map with values given as percentages from the control $\pCaf$ value. Contour plots are finally added to highlight the presence of isolines, whose many different parameter sets induce the same shift ($-\SI{2}{\percent}$ dotted, $\SI{0}{\percent}$ full, $+\SI{2}{\percent}$ dashed black lines) in the control $\pCaf$ value. (B) Parameter points from the obtained isolines are mapped by the emulator into EF feature values. These values (given as percentages of the control EF value) are represented by different colour intensities used to colour each parameter point in the isolines, showing that parameters that share the same $\pCaf$ values are linked to different EF values.}
    \label{fig:pca50isolines}
\end{figure}

%
%
%
\subsection{LV function changes are non-uniquely explained by sarcomere alterations}\label{sec:changesLVfunctionresult}
EF evaluation on $2$-parameter grids highlighted the presence of isolines, where all parameter combinations along these lines result in the same predicted EF (Figure~\ref{fig:EFisolines}A). This means that moving between any two points on each isoline will result in the same EF, demonstrating the non-uniqueness of the LV function and sarcomere properties.

%
%
%
\subsubsection{Non-unique mapping of LV function to F-pCa curve}\label{sec:lvtofpcanonuniquemapping}
Parameter points that give rise to the same predicted EF value (isolines of Figure~\ref{fig:EFisolines}A) are quantitatively linked to different $\pCaf$ values (Figure~\ref{fig:EFisolines}B), showing that the mapping from LV function to the F-pCa curve is not unique.

\begin{figure}[h!]
    \myfloatalign
    \includegraphics[width=\textwidth]{figures/chapter08/Fig6.pdf}
    \caption{For each pair of parameters regulating the $\pCaf$ feature of the F-pCa curve, a $2$D uniform grid is constructed using a $\pm\SI{50}{\percent}$ perturbation around the reference parameter set values (black dots). (A) A trained emulator is then used to predict the $\textrm{EF}$ feature value at every parameter point of the grid, and each grid is plotted as a heat map with values given as percentages from the control $\textrm{EF}$ value. Contour plots are finally added to highlight the presence of isolines (full black lines), whose many different parameter sets induce the same $\SI{0}{\percent}$ shift in the control $\textrm{EF}$ value. (B) Parameter points from the obtained isolines are mapped by the cell contraction model into $\pCaf$ feature values. These values (given as percentages of the control $\pCaf$ value) are represented by different colour intensities used to colour each parameter point in the isolines, showing that parameters that share the same $\textrm{EF}$ values are linked to different $\pCaf$ values.}
    \label{fig:EFisolines}
\end{figure}

%
%
%
\subsection{Non-unique mapping from/to F-pCa curve to/from LV function}\label{sec:ch8nonuniquemappings}
In Sections~\ref{sec:changespCa50result1}--\ref{sec:changespCa50result2}, we proved that changes in the $\pCaf$ value are not uniquely caused by changes in sarcomere properties. In Section~\ref{sec:fpcatolvnonuniquemapping}, we also showed that changes in the EF value are not uniquely caused by changes in the $\pCaf$ value. Because of these two findings, we can state that observed changes in the F-pCa curve cannot be uniquely mapped to changes in the LV function.

\vspace{0.2cm}
At the same time, in Section~\ref{sec:changesLVfunctionresult} we proved that changes in the EF feature value are not uniquely caused by changes in sarcomere properties. In Section~\ref{sec:lvtofpcanonuniquemapping}, we also showed that changes in the $\pCaf$ feature value are not uniquely caused by changes in the $\textrm{EF}$ value. Because of these two other findings, we can state that observed changes in the LV function cannot be uniquely mapped to changes in the F-pCa curve.

%
%
%
\section{Discussion}\label{sec:ch8discussion}
In this study, we have made use of mathematical models to characterise the relationship between sarcomere properties and the LV contractile function in the healthy rat heart. We have highlighted the presence of complex nonlinearities; in particular, we have demonstrated that the relationship between myofilaments' features (e.g. $\Caif$) and PV loop characteristics (e.g. EF) is non-monotonic. As these sarcomere properties also define the steady-state F-pCa relationship in the cardiac muscle, we extended this result in terms of shifts in the F-pCa curve that are often examined when experimentally assessing the effect of sarcomere-targeting pharmacological compounds. Therefore, we have provided both analytical and simulation study evidence that alterations in the F-pCa curve can cause very different changes in whole heart function. At the same time, we have shown that observed changes in the LV function cannot be attributed to a unique modification in sarcomere properties. Although in the previous sections we have characterised the LV function using EF, the obtained results generally hold for many other clinically relevant indexes of LV systolic and diastolic function, e.g. IVRT and PeakP, as visualised in Figures~\ref{fig:IVRTisolines}--\ref{fig:PeakPisolines}. To design new treatment strategies, solely looking at the induced shift in the $\pCaf$ feature value of the F-pCa curve on its own is therefore not enough to predict or to understand predictions of how this will be translated into whole-organ function changes.

\begin{figure}[ht!]
    \myfloatalign
    \includegraphics[width=\textwidth]{figures/chapter08/Fig6_IVRT.pdf}
    \caption{The same IVRT value (A) can be linked to different $\pCaf$ values (B) (i.e. to differently shifted F-pCa curves).}
    \label{fig:IVRTisolines}
\end{figure}

\begin{figure}[ht!]
    \myfloatalign
    \includegraphics[width=\textwidth]{figures/chapter08/Fig6_PeakP.pdf}
    \caption{The same PeakP value (A) can be linked to different $\pCaf$ values (B) (i.e. to differently shifted F-pCa curves).}
    \label{fig:PeakPisolines}
\end{figure}

\vspace{0.2cm}
Also, when studying myofilament $\Ca$ sensitivity using F-pCa curves, simply considering the $\pCaf$ value as a stand-alone measurement is not sufficient for translation into dynamic contraction and relaxation. This concept was previously shown for single-cell dynamics by Chung et al.~\cite{Chung:2016} who highlighted the importance of biophysical measures of $\koff$ and $\kon$ to help predict tension dynamics at the cellular level. However, in this work, we expand this concept further to the whole heart level by analysing LV features and exploring the inverse mapping from LV features to F-pCa curves, highlighting the non-uniqueness of both forward and inverse mapping between F-pCa and LV features. We emphasise that, for instance, an increase in $\Ca$ sensitivity, i.e. a leftward shift in the F-pCa curve, will have two effects. First, it will increase residual tension, decreasing EDV; second, it will increase end-systolic tension, decreasing ESV. The balance of these two effects will impact the change in SV and EF for a given change in $\Ca$ sensitivity. This impact of changes in $\pCaf$ depends on the starting F-pCa curve, the $\Ca$ transient, cardiac material properties and boundary conditions. Determining these multi-scale relationships from experimental preparations remains challenging.

\vspace{0.2cm}
The performed GSA interpreted the variability of EDV, ESV, SV and EF in terms of the uncertainty in F-pCa curve-modulating sarcomere parameters, and it emphasised the importance of the $\Ca$ sensitivity in affecting these PV loop characteristics. Deeper insight can be gained if we look at higher-order interactions' effects. Although these are present for all the four LV features considered, they are remarkably high only for the SV and EF features, explaining more than half of the total variance for SV and almost half of the total variance for EF. We can notice that for the EDV and ESV features, higher-order interactions' effects are instead small, and dominating effects are mostly of the first-order type. Conversely, for the SV and EF features where higher order interactions' effects are high, dominating lower-order effects are mostly of the second-order type. All these considerations can be summarised by stating that although it is possible to interpret changes in terms of the individual contribution of parameters for the EDV and ESV features, this is not the case for SV and EF features. In this sense, it is more the combined effect of the whole sarcomere to determine the LV function rather than single myofilament components.

\vspace{0.2cm}
Indications from the GSA coupled with the information of F-pCa curve vs LV function non-monotonicity shed new light on the problem of interpreting pharmacological interventions' effects on the F-pCa curve in terms of the desired effects on whole-heart function. This concept is illustrated via the schematic in Figure~\ref{fig:schematic}, which highlights existing feedback mechanisms that regulate contraction in the heart. Modulation of the $\Ca$ transient can directly affect the active tension which is generated within the sarcomere, and alteration of the sarcomere generated force will eventually affect the PV loop. As the force-volume relationships at the end-diastolic and end-systolic pressures are fixed, sarcomere interventions that aim at shifting the F-pCa might result in no change in LV contractile function. For this reason, treatment strategies should aim at altering both the end-systolic and end-diastolic force-volume relationships or altering one while maintaining the other to yield an effect on EF.

\begin{figure}[ht!]
    \myfloatalign
    \includegraphics[width=\textwidth]{figures/chapter08/Fig7.pdf}
    \caption{Force-LV volume curves at the end-diastolic and end-systolic pressures (top right, orange and green lines) can be separately manipulated to modulate the LV contractile function. However, interventions on calcium transient (bottom left, blue line) and sarcomeric generated force (top left, orange and green full lines) both manifest as modifications of the former curves, which in turn causes modification of the PV loop (bottom right, blue full line). In addition, pharmacological modulations on the sarcomere might cause a shift of the force-calcium relationship (top left, orange and green dashed lines). However, this will preserve the EF (bottom right, blue dashed line) without improving LV contractile function, which was the desired outcome of the performed sarcomeric intervention.}
    \label{fig:schematic}
\end{figure}

%
%
%
\subsection{Limitations}\label{sec:ch8limitations}
The limitations of this study mainly concern the adopted modelling/emulation framework, and are presented fully in Chapter~\ref{cha:chapter9}, Section~\ref{sec:ch9limitations}.

%
%
%
\section{Summary}\label{sec:ch8summary}
We have used a biophysically detailed mathematical model of a healthy rat heart contraction to quantitatively map sarcomere properties to whole heart function. Using this mapping, we demonstrated that the relationship between the F-pCa curve and LV function is non-linear and non-monotonic. This results in the non-interpretability of observed changes in the LV function in terms of unique sarcomere modulations, which highlights the need for muscle experimental findings to be put into a broader context where not only the $\pCaf$ and Hill coefficient but also active and passive force, length and velocity dependencies, calcium transient and boundary conditions are analysed.


\documentclass[dvipdfmx,uplatex,a4paper]{article}
\def\vector#1{\mbox{\boldmath $#1$}}
\usepackage[hiresbb]{graphicx}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{ascmac}
\usepackage{braket}
\usepackage{circuitikz}
\usepackage{cite}
\usepackage{comment}
\usepackage{float}
\usepackage{listings}
\usepackage{nameref}
\usepackage{siunitx}
\usepackage{tikz}
\usepackage[version=3]{mhchem}

\usepackage[colorlinks=true, bookmarks=true,
bookmarksnumbered=true, bookmarkstype=toc, linkcolor=blue,
urlcolor=blue, citecolor=blue]{hyperref}

\makeatletter
 \renewcommand{\theequation}{
   \thesubsection.\arabic{equation}}
  \@addtoreset{equation}{section}
\makeatother

\title{Solve RGB+ LEDs PWM from Chromaticity}
\author{CHINZEI, Kiyoyuki}
\date{\today}
\begin{document}
\maketitle

\begin{abstract}
This article\footnote{To cite, please refer to https://github.com/kchinzei/kch-rgbw-lib/docs/rgbw\_solver.pdf} is a private note to develop \texttt{kch-rgbw-lib}, a TypeScript library in \href{https://github.com/kchinzei/kch-rgbw-lib}{github} and \href{https://www.npmjs.com/package/kch-rgbw-lib}{npm}. \texttt{Kch-rgbw-lib} provides classes and functions for multicolor LED, including color space conversions between HSV, RGB, XYZ and xyY and calculation of accurate color composition. This article gives a general solution of multi-number (more than R-G-B) LEDs to represent composite colors. It is not intended to carry new, comprehensive, or most efficient ideas. This document is granted under MIT License.
\end{abstract}

\section{Define the Problem}
\subsection{Past works}\label{s_intro}
Obtaining accurate colors by mixing R-G-B light sources has been utilized as color displays since 1950s. As various colors are available by LED, recent topics are solutions of color composite with additional color sources typically for OLED applications \cite{Chi2011, Lee2014}. Usually white light sources are used as an additional light source \cite{AN1562, Chi2011, Lee2014}. For display purposes additional colors other than R-G-B have been also used to expand the possible color ranges (gamut)\cite{Wikipedia_multicolor}. Sharp once added yellow in Aquos flat-panel TV, but they initially researched 5-primary color display \cite{Sharp2011}. Amber \cite{AN2026}, turquoise, and violet can be other colors to expand the gamut.

\subsection{Given parameters and assumptions}\label{s_assumptions}
We have $N \geq 3$ color sources (LEDs) with chromaticity $(x_i, y_i)$ and maximum luminance $Y_i$, where $i=1 \ldots N$. Our problem is to find the optimum composite output ratio (PWM output) $\boldsymbol{\alpha} = [\alpha_1 \cdots \alpha_N]^T$ where $0 \leq \alpha_i \leq 1$ to represent a given color input with chromaticity $(x, y)$ and luminance $Y$.

Here, we set our goal of optimization as the following:
\begin{enumerate}
  \item\label{I_max_luminance} Under physical constraint $0 \leq Y \leq  Y_1 + \cdots + Y_N$,
  \item\label{I_solution} Obtain exact composite color to represent $(x, y, Y)$.
  \item\label{I_inside_gamut} If $(x, y)$ is outside the gamut of color source, the nearest color in it is used.
  It can be achieved by projecting the input to the gamut contour.
  \item\label{I_min_energy} When possible, minimize energy consumption $E$, \\
  \begin{equation}
    \label{E_min_energy}
    E = \sum_1^N \alpha_i W_i
  \end{equation}
  where $W_i$ is the power of each LED at the maximum luminance.
  \item\label{I_lifetime} When possible, average turn-on time of LEDs to equalize LEDs lifetime,
  \item\label{I_small_alpha} When possible, set $\alpha_i$ to null when it's very small.
  It is preferable to avoid jitter at low PWM output.
\end{enumerate}

It is a typical linear programming (LP) problem. When $N=3$, e.g. R-G-B color sources only, it's a deterministic and not an optimization problem. And when $N=4$, e.g. R-G-B-W LEDs, there is only one parameter to optimize, which makes the problem as simple as we don't need to use sophisticated LP solver.
% Mathematically, it is dependent to $R = rank(\boldsymbol{A})$, where $\boldsymbol{A}$ is a matrix of LEDs, in Eq.~\eqref{E_X=AY}. We first derive a general description of the problem and solve it for $R=3$, $R=4$ and $R > 4$ cases.
We first derive a general description of the problem and solve it for $N=3$, $N=4$ and $N > 4$ cases.

\section{General solution}
We use XYZ color space because a composite of color source in XYZ color space can be obtained as a simple sum of each term.  In XYZ color space, our problem is to determine $\boldsymbol{\alpha} = [\alpha_1 \cdots \alpha_N]$ which gives an equation between input color $[X, Y, Z]^T$ and color source $[X_{i}, Y_{i}, Z_{i}]^T$, $i=1 \ldots N$;

\begin{equation}
  \label{E_XYZcomposite}
  \left[
    \begin{array}{c}
      X \\
      Y \\
      Z
    \end{array}
  \right]
   = \alpha_1
  \left[
    \begin{array}{c}
        X_1 \\
        Y_1 \\
        Z_1
    \end{array}
  \right]
   + \cdots + \alpha_N
  \left[
    \begin{array}{c}
        X_N \\
        Y_N \\
        Z_N
    \end{array}
  \right]
\end{equation}

Color space $[X, Y, Z]^T$ is expressed by using $(x, y, Y)$:

\begin{eqnarray}
  \label{E_xyY2XYZ}
  X & = & \frac{x}{y}  Y \\
  Y & = & Y \\
  Z & = & \frac{1 - x - y}{y} Y
\end{eqnarray}

Using matrix representation, Eq.~\eqref{E_XYZcomposite} is written as

\begin{equation}
  \label{E_X=AY}
  \left[ \boldsymbol{X} \right] =
  \left[ \boldsymbol{A} \right]
  \left[ \boldsymbol{\alpha} \right]
\end{equation}

\noindent
where

\begin{eqnarray}
  \left[ \boldsymbol{X} \right] &=&
  \left[ X \, Y \, Z \right]^T \label{E_XYZ^T} \\
%
  \left[ \boldsymbol{A} \right] &=&
  \left[
    \begin{array}{ccc}
      \frac{x_1}{y_1} Y_1 & \cdots & \frac{x_N}{y_N} Y_N \\
      Y_1 & \cdots & Y_N \\
      \frac{1 - x_1 - y_1}{y_1}Y_1 & \cdots & \frac{1 - x_N - y_N}{y_N}Y_N
    \end{array}
  \right] \\
%
  \left[ \boldsymbol{\alpha} \right] &=&
  \left[ \alpha_1\, \cdots\, \alpha_N \right]^T
\end{eqnarray}

Our goal is to solve Eq.~\eqref{E_X=AY} with respect to $ \boldsymbol{\alpha} = [\alpha_1 \cdots \alpha_N]^T $. To solve it, we can use the singular value decomposition (SVD) (Eq.~\eqref{E_SVD})~\cite{SVD_NRC}.

\begin{equation}
  \label{E_SVD}
  \Bigg[ \boldsymbol{A} \Bigg] =
  \Bigg[ \boldsymbol{U} \Bigg]
  \left[
    \begin{array}{cccc}
      \omega_1 & \\
        & \omega_2 &   &  0 \cdots 0 \\
        &  & \omega_3 &
    \end{array}
  \right]
  \Bigg[ \boldsymbol{V}^T \Bigg]
\end{equation}

\noindent
where $ \boldsymbol{A} $ is $ 3 \times N $,
$ \boldsymbol{U} $ is $ 3 \times 3 $,
$ [\omega_1 \ddots \omega_3, 0 \cdots 0] $ is $ 3 \times N $,
$ \boldsymbol{V}^T $ is $ N \times N $ matrixes
\footnote{Many implementations of SVD return 'economy' $\boldsymbol{V}$ in $ N \times 3$ instead of calculating full $N \times N$ size. Matlab, Octave without 'econ' option and \href{https://www.npmjs.com/package/svd-js}{svd-js} javascript package in NPM with 'f' option (This is my contribution!) give full $\boldsymbol{V}$.}
in this specific case, since $ \boldsymbol{A} $ is a $ 3 \times N $ matrix and there are upto 3 $\omega$'s. When $ N \geq 4 $, $ [\omega_1 \ddots \omega_3 ] $ is null-padded in $ 3 \times (N-3) $.
The pseudo-inverse matrix $ \boldsymbol{A}^{-1} $ is obtained by

\begin{equation}
  \Bigg[ \boldsymbol{A} \Bigg]^{-1} =
  \Bigg[ \boldsymbol{V}_{1-3} \Bigg]
  \left[
    \begin{array}{ccc}
      1/\omega_1 & & \\
      & 1/\omega_2 & \\
      & & 1/\omega_3
    \end{array}
  \right]
  \Bigg[ \boldsymbol{U}^T \Bigg]
\end{equation}

\noindent
where $ \boldsymbol{V}_{1-3} $ is the first 3 columns of $ \boldsymbol{V} $, those correspond to $ \omega_1, \omega_2, \omega_3 $
\footnote{Many implementations of SVD do not sort $ \boldsymbol{U}, \boldsymbol{V}$ by $\omega$s. Matlab and Octave do sort. Algorithm in 'Numerical Recipes in C' and \href{https://www.npmjs.com/package/svd-js}{svd-js} in NPM do not.}.
Using $ \boldsymbol{A}^{-1} $, we obtain

\begin{equation}
  \label{E_Y=A-1X}
  \left[ \boldsymbol{\alpha} \right] =
  \left[ \boldsymbol{A} \right]^{-1}
  \left[ \boldsymbol{X} \right]
\end{equation}

By the way, what about the rest of columns in $ \boldsymbol{V} $? They are null vectors of $ \boldsymbol{A} $. A null vector $\boldsymbol{n}$ of $ \boldsymbol{A}$ is such vector that satisfies $ \boldsymbol{A} \boldsymbol{n} = [0]$. By denoting these columns as $ \boldsymbol{n}_4 \ldots \boldsymbol{n}_N $, Eq.~\eqref{E_Y=A-1X} can be extended as

\begin{equation}
  \label{E_Y=A-1X+n}
  \left[ \boldsymbol{\alpha} \right] =
  \left[ \boldsymbol{A} \right]^{-1}
  \left[ \boldsymbol{X} \right]
  + \beta_4 \boldsymbol{n}_4 + \cdots + \beta_N \boldsymbol{n}_N
\end{equation}
\noindent
where $ \beta_4 \ldots \beta_N $ are arbitrary numbers. By choosing these using other constraints, we can obtain the optimum solution.

% The actual number of null vectors is determined by the rank of $\boldsymbol{A}$.

\section{Solution of $N=3$ case}

When $N=3$, Eq.~\eqref{E_Y=A-1X} gives a deterministic solution. No optimization. However, the obtained $ \alpha_i $ should be physically meaningful, i.e., $ 0 \leq \alpha_i \leq 1 $. It can be out of range when
\begin{itemize}
  \item Input color $[X]$ is out of the gamut defined by the color sources,
  \item $Y$ of $[X]$ is greater (brighter) than the color sources.
\end{itemize}
\noindent
When $ \alpha_i < 0$, the nearest color in the gamut should be used as the input. We can also truncate such $\alpha_i$ to 0. In this case, the output color has certain error.

When $ \alpha_i > 1 $, all $\alpha$s should be normalized by the largest $\alpha$. This way the color will be correctly obtained, but it will be darker than expected.

\section{Solution of $N=4$ case}

When $N=4$, Eq.~\eqref{E_Y=A-1X+n} is simple.

\begin{equation}
  \label{E_Y=A-1X+1}
  \left[ \boldsymbol{\alpha} \right] =
  \left[ \boldsymbol{A} \right]^{-1}
  \left[ \boldsymbol{X} \right]
  + \beta_4 \boldsymbol{n}_4
\end{equation}

\noindent
We will determine parameter $\beta_4$ using the assumptions in section \ref{s_assumptions}.
Since it is always $ 0 \leq \alpha_i \leq 1$, by solving it for $\beta$ (hereafter omitting '$_4$'), we obtain the following conditions.
\begin{eqnarray}
  \beta & \geq & \begin{cases}
    - \frac{b_i}{n_i} \;\;\;\; \text{ if \(n_i > 0\)} \label{E_betamin} \\
    \frac{1 - b_i}{n_i} \;\;\;\; \text{ if \(n_i < 0\)}
  \end{cases} \\
%
  \beta & \leq & \begin{cases}
    \frac{1 - b_i}{n_i} \;\;\;\; \text{ if \(n_i > 0\)} \\
    - \frac{b_i}{n_i} \;\;\;\; \text{ if \(n_i < 0\)} \label{E_betamax}
  \end{cases} \\
%
    E &=& \sum_{i=1}^4 (\beta n_i + b_i) W_i \to min \label{E_energy_n4}
\end{eqnarray}

\noindent
where $ [b_1,\, \ldots{}\, , b_4]^T = [ \boldsymbol{A} ]^{-1} [\boldsymbol{X}] $, $n_i$ are the elements of $\boldsymbol{n}$. Eq.~\eqref{E_energy_n4} is from Eq.~\eqref{E_min_energy}. Finding the largest and smallest values of the right hand side of Eqs.~\eqref{E_betamin} and \eqref{E_betamax}, denoted as $\beta_{min}$ and $\beta_{max}$, Eqs.~\eqref{E_betamin} and \eqref{E_betamax} are rewritten as

\begin{equation}
  \beta_{min} \leq \beta \leq \beta_{max}
\end{equation}

Since Eq.~\eqref{E_energy_n4} is rewritten as $E = s_1\beta + s_2$, here $s_1$ and $s_2$ are constants determined by calculating the sums in Eq.~\eqref{E_energy_n4}, optimized $\beta$ is determined as

\begin{equation}
    \beta = \begin{cases}
      \beta_{min}  & \text{if \(s_1 = \sum_1^4 n_i W_i > 0\)} \\
      \beta_{max}  & \text{else}
  \end{cases}
\end{equation}

\subsection{When $\beta$ is not determined}

When $\beta_{min} > \beta_{max}$, there is no feasible answer. Again, there are two cases, when the input color $[\boldsymbol{X}]$ is out of the gamut, or when $Y$ in Eq.~\eqref{E_XYZ^T} is greater than the color sources. Since $\alpha_i \geq 0$ cannot compromise, we find $\beta$ that satisfies

\begin{eqnarray}
  \beta & \geq & - \frac{b_i}{n_i} \;\;\;\; \text{ if \(n_i > 0\)} \label{E_beta0min} \\
  \beta & \leq & - \frac{b_i}{n_i} \;\;\;\; \text{ if \(n_i < 0\)} \label{E_beta0miax}
\end{eqnarray}
Then we normalize the largest $\alpha_i$ to be 1.

\subsection{When $\alpha_i$ is small}

To implement the assumption \ref{I_small_alpha} in section \ref{s_assumptions}, we can introduce allowance of small $\alpha$, $\alpha_\varepsilon$, and exchange Eqs.~\eqref{E_betamin} and \eqref{E_betamax} as

\begin{equation}
  \beta \geq \frac{\alpha_\varepsilon - b_i}{n_i}
\end{equation}

But this also needs to assert if $\beta_{min} \leq \beta_{max}$.

\section{Solution of $N > 4$ case}
We can optimize Eq.~\eqref{E_min_energy} under constraints of $0 \leq \alpha_i \leq 1$ for Eq.~\eqref{E_Y=A-1X+n} using a linear programming solution\cite{LP_NRC}.
To use linear programming we need to rewrite our problem into the \textit{normal form}. Normal form of a linear programming problem is

\begin{itemize}
  \item Objective functions are to be minimized,
  \item All constraints are equality formulas,
  \item All variables $ \geq 0$.
\end{itemize}

Since our constraints $0 \leq \alpha_i \leq 1$ are unequal and $\beta_i$ can be negative, we introduce \textit{slack variables} $\gamma_i, \delta_i$ and $\epsilon_i, \zeta_i$ to replace $\beta$.

\begin{itemize}
  \item Introduce $\gamma_i \geq 0$ such that $b_i + \beta_4 n_{4i} + \cdots + \beta_N n_{Ni} - \gamma_i = 0$,

  \item Introduce $\delta_i \geq 0$ such that $b_i + \beta_4 n_{4i} + \cdots + \beta_n n_{Ni} + \delta_i = 1$,

  \item Replace $\beta_i = \epsilon_i - \zeta_i$, such that $\epsilon_i \geq 0 $ and $\zeta_i \geq 0$.
\end{itemize}

After this modification, we have $2N$ equations with $2N$ variables (for $\gamma$ and $\delta$) and $2(N-3)$ variables (for $\epsilon$ and $\zeta$). Using these replacements, the objective function (Eq.~\eqref{E_min_energy}) and Eq.~\eqref{E_Y=A-1X+n} are rewritten as

\begin{eqnarray}
%
  \label{E_min_energy5}
  \sum_{i=1}^N (n_{4i} \epsilon_4 - n_{4i} \zeta_4 + \cdots +  n_{Ni} \epsilon_N - n_{Ni} \zeta_N + b_{i}) W_i &\to& min \\
%
  \label{E_bmin5}
  n_{4i} \epsilon_4  - n_{4i} \zeta_4 + \cdots + n_{Ni} \epsilon_N  - n_{Ni} \zeta_N  - \gamma_i + b_i &=& 0 \\
%
  \label{E_bmax5}
  n_{4i} \epsilon_4  - n_{4i} \zeta_4 + \cdots + n_{Ni} \epsilon_N  - n_{Ni} \zeta_N  + \delta_i + b_i &=& 1
\end{eqnarray}

\noindent
Eq.~\eqref{E_min_energy5} is the objective function. Solvers applicable to Eqs.~\eqref{E_min_energy5} - \eqref{E_bmax5} can be found in many numerical packages. \href{https://www.npmjs.com/package/kch-rgbw-lib}{\texttt{Kch-rgbw-lib}} uses \href{https://www.npmjs.com/package/linear-program-parser}{linear-program-parser} and \href{https://www.npmjs.com/package/linear-program-solver}{linear-program-solver} in npm.

\subsection{When solution infeasible}
Linear programming solver may find it's `infeasible' - no solution to satisfy all constraints in Eqs.~\eqref{E_bmin5} and \eqref{E_bmax5}. Another possibility is that the solution would not converge. Yet again, there are two cases, when the input color $[X]$ is out of the gamut, or when $Y$ in Eq.~\eqref{E_XYZ^T} is greater (brighter) than the color sources.

When the object brightness is too large, we can find a solution by omitting Eq.~\eqref{E_bmax5}. Physically doable solution is to normalize the maximum $Y_i$ to $1.0$.

We may also see infeasible case when one or more value in solution is very close to zero and Eq.~\eqref{E_bmin5} fails due to numerical error. If it is the case, you can set a small negative value to the right side of Eq.~\eqref{E_bmin5} instead of $0$.

\section{More to do}

The following sections discuss items not implemented in \href{https://www.npmjs.com/package/kch-rgbw-lib}{\texttt{kch-rgbw-lib}}. We leave them as `homework' fun.

\subsection{Not to compromise brightness $Y$}
When $Y$ in Eq.~\eqref{E_XYZ^T} is greater (brighter) than the color source's capacity, there is no solution. Here we suggested a (compromised) solution to normalize $Y_i$. But we can also take another strategy to maintain the goal brightness by compromising the goal color.

This strategy requires computation of gradient of $Y$ in $\boldsymbol{\alpha}$ space.

\subsection{LED's lifetime averaging}
In section \ref{s_assumptions} '\nameref{s_assumptions}' we introduced an optional condition \ref{I_lifetime}, 'When possible, average turn-on time of LEDs to equalize LEDs lifetime'. It is equivalent to minimize the variance of $\alpha_1, \, \ldots\, , \alpha_N$. It can be an optimization of a quadratic function.

In $N = 4$ case, we have only one variable $\beta$ therefore we can optimize only one condition. This means we need to chose between the energy minimization and this condition.

\bibliographystyle{unsrt}
\bibliography{rgbw}

\section*{MIT License}

Copyright (c) 2020 Kiyo Chinzei

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

\end{document}


\documentclass[11pt, oneside]{article}
\usepackage[margin=.9in]{geometry}
\usepackage{pgfplots}
\pgfplotsset{compat=default}
\newcommand{\cuckoo}{{\rm cuckoo}}
\newcommand{\hash}{{\rm siphash}}
\usepackage{hyperref}
\usepackage{listings}
\title{Cuckoo Cycle: \protect\\ a memory bound graph-theoretic proof-of-work}
\author{John Tromp}
\begin{document}
\maketitle

\begin{abstract}
We introduce the first graph-theoretic proof-of-work system,
based on finding small cycles or other structures in large random graphs.
Such problems are trivially verifiable and arbitrarily scalable,
and appear to require memory linear in graph size to solve efficiently.
We show that in random bipartite graphs with average degree 1,
length $L$ cycles occur with frequency approximately $1/L$.
On these graphs, algorithm "lean" finds cycles using one bit per edge, and up to one bit per node.
Runtime is linear in graph size and dominated by random access latency.
We exhibit two time-memory trade-off (TMTO) algorithms
decreasing memory usage by a factor $k$ while increasing runtime by a factor $c \cdot k$.
The constant $c$ provides a measure of memory-hardness, which is shown to be dependent
on cycle length, guiding the latter's choice.
Trading in the other direction, algorithm "mean" uses a few dozen bits per edge but is 4x faster
in practice, becoming memory bandwidth bound rather than latency bound.
We present performance figures for optimized CPU and GPU implementations,
and discuss possible ASIC implementations.
% Both algorithms are shown to parallelize well.
\end{abstract}

\section{Introduction}
A {\em proof-of-work} (PoW) system allows a verifier to check with negligible
effort that a prover has expended a large amount of computational effort.
Originally introduced as a spam fighting measure,
where the effort is the price paid by an email sender for demanding the
recipient's attention, they now form one of the cornerstones of crypto currencies.

As proof-of-work for new blocks of transactions,
Bitcoin~\cite{nakamoto2009bitcoin} adopted Adam Back's hashcash~\cite{back2002}.
Hashcash entails finding a nonce value such that application of a cryptographic hash function
to this nonce and the rest of the block header, results in a number below a
target threshold\footnote{or, less accurately, results in many leading zeroes}.
The threshold is dynamically adjusted by the protocol
so as to maintain an average block interval of 10 minutes.

Bitcoin's choice of the simple and purely compute-bound SHA256 hash function
allowed for an easy migration of hash computation from
desktop processors (CPUs) to graphics-card processors (GPUs),
to field-programmable gate arrays (FPGAs), and finally to custom designed
chips (ASICs), with huge improvements in energy-efficiency at every step.

Since Bitcoin, many other crypto-currencies have adopted hashcash, with various
choices of underlying hash function. the most well-known being {\em scrypt} as
introduced by Tenebrix~\cite{tenebrix2011} (since faded into obscurity)
and copied by Litecoin~\cite{litecoin2011}.
Scrypt, designed as a sequential memory-hard key derivation function,
was specifically chosen to resist the migration away from CPUs and be ``GPU-hostile''.
However, to adapt to the efficient verifiability requirement of proof-of-work, its
memory footprint was severely limited, and migration slowed down only slightly.

Primecoin~\cite{king2013} introduced the notion of a number-theoretic proof-of-work,
thereby offering the first alternative to hashcash among crypto-currencies.
Primecoin identifies long chains of nearly doubled prime numbers, constrained
by a certain relation to the block header.
Verification of these chains, while very slow compared to bitcoin's, is much faster
than attempting to find one.
This asymmetry between proof attempt and verification is typical in non-hashcash proofs of work.
Recently, two other prime-number based crypto-currencies were introduced. Riecoin is based
on finding clusters of prime numbers, and Gapcoin on finding large gaps between consecutive prime numbers.

Momentum~\cite{larimer2013} proposes finding birthday collisions of hash outputs,
in what could well be the simplest possible asymetric proof-of-work,
combining scalable memory usage with trivial verifiability.
In section~\ref{cycle_length_choice} we show that Momentum is in essence a special case of Cuckoo Cycle,
one that is particularly susceptible to time-memory trade-offs.

Adam Back~\cite{back2014} has a good overview of proof-of-work papers past and present.

\section{Motivation}
Cuckoo Cycle aims to be an ``egalitarian'' proof-of-work, that is,
to minimize performance-per-dollar differences across hardware architectures.
This is to be achieved by making main memory latency or bandwidth the bottleneck, since
DRAM latency and bandwidth vary much less across hardware architecture and process technology
than compute power.

Our aim of a memory bound PoW translates to the following desirable properties:

\begin{description}
\item[MB1] a target memory footprint that exceeds a single memory chip
\item[MB2] a pattern of necessarily random memory accesses
\item[MB3] minimal computation per random memory access\footnote{Preferably less than
the roughly $50$ nanosecond row activation delay for switching rows on a memory bank.}
\item[MB4] no feasible trade-off of memory for time\footnote{Rather arbitrarily
defined as incurring an order of magnitude increase
in $\mbox{time}\times\mbox{memory}$ used per expected solution.}
\end{description}

A memory bound PoW aims to take advantage of the huge economies of scale of commodity DRAM production
to make DRAM chips the most cost-effective vehicle for mining.
Just as SRAM is one order of magnitude faster but two orders more expensive than DRAM,
so it is conceivable that development and production of custom memory chips for a memory bound PoW
will incur a sufficient cost premium to wipe out any performance gains.

We thus disagree with the premise of \cite{poelstra2014} that PoWs should be compute bound
in order to have ongoing energy costs dominate mining, which results in an expensive ASIC
design arms race to drive up performance per Watt, rapid hardware obsolescence,
and geographical centralization towards cheap electric power.

We will not strive for provable lower bounds on memory usage. Such bounds appear to be
attainable only under the so-called {\em random oracle model}, where memory tends to be used
merely as a store for chains of compute-intensive hash outputs.
Instead, we present an efficient proof-finding algorithm
along with our best attempts at memory-time trade-offs,
and conjecture that these cannot be significantly improved upon.
Lacking precise definitions and proofs of memory bound-ness, this work should be considered
more empirical than formal.

\section{Graph-theoretic proofs-of-work}
We propose to base proofs-of-work on finding certain subgraphs in large pseudo-random graphs.
In the Erd\H{o}s-R\'{e}nyi model, denoted $G(N,M)$, a graph is chosen uniformly at random
from the collection of all graphs with $N$ nodes and $M$ edges. Instead, we choose edges
deterministically from the output of a keyed hash function, whose key could be chosen
uniformly at random. For a well-behaved hash function, these two classes of random graphs
should have nearly identical properties.

Formally, fix a keyed hash function
$h: \{0,1\}^K \times \{0,1\}^{W_i} \rightarrow \{0,1\}^{W_o}$,
and a small graph $H$ as a target subgraph\footnote{hash functions generally have arbitrary length inputs,
but here we fix the input width at $W_i$ bits.}.
Now pick a large number $N \leq 2^{W_o}$ as the number of nodes,
and $M \leq 2^{W_i-1}$ as the number of edges.
Each key $k \in \{0,1\}^K$ generates a graph $G_k = (V,E)$ where $V=\{v_0,\ldots,v_{N-1}\}$, and
\begin{equation}
E=\{(v_{h(k,2i) \bmod N},v_{h(k,2i+1) \bmod N}) | i \in [0,\ldots,M-1]\}
\end{equation}
The inputs $i \in [0,\ldots,M-1]$ are also called {\em nonces}\footnote{These
{\em micro} nonces should be distinguished from the {\em macro} nonce used to generate key $k$.}
The graph has a {\em solution} if $H$ occurs as a subgraph.
Denote the number of edges in $H$ as $L$.
A proof of solution is an ordered list of $L$ nonces that generate the edges
of $H$'s occurrence in $G_k$.
Such a proof is verifiable in time depending only on $H$ (typically linear in $L$), independent of $N$ and $M$.

A simple variation generates random bipartite graphs: $G_k = (V_0 \cup V_1,E)$ where (assuming $N$ is even)
$V_0=\{v_0,v_2,\ldots,v_{N-2}\}$, $V_1=\{v_1,v_3,\ldots,v_{N-1}\}$, and
\begin{equation}
\label{hash_edges}
E=\{(v_{2(h(k,2i) \bmod \frac{N}{2})}, v_{2(h(k,2i+1) \bmod \frac{N}{2})+1}) | i \in [0,\ldots,M-1]\}
\end{equation}

The expected number of occurrences of $H$ as a subgraph of $G$ is a function of both $N$ and $M$,
and in many cases is roughly a function of $\frac{M}{N}$ (half the average node degree).
For fixed $N$, this function is monotonically increasing in $M$.
To make the proof-of-work challenging, one chooses a value of $M$ that yields less than one
expected solution.

The simplest possible choice of subgraph is a fully connected one, or a {\em clique}.
While an interesting choice, akin to the number-theoretic notion of a prime-cluster
as used in Riecoin, we leave its consideration to a future paper.

\section{Cuckoo Cycle}
In this paper we focus on what is perhaps the next-simplest possible choice, the {\em cycle}.
Specifically, we propose the hash function \hash\ with a $K=128$ bit key, $W_i = W_o = 64$ input
and output bits, $N \leq 2^{64}$ a 2-power, $M=N/2$, and $H$ an $L$-cycle.
Using the lightweight \hash\-2-4 with only 6 rounds helps to attain property MB3.
The reason for calling the resulting proof-of-work Cuckoo Cycle is that
inserting items in a Cuckoo hashtable naturally leads to cycle formation
in random bipartite graphs.

\section{Cuckoo hashing}
Introduced by Rasmus Pagh and Flemming Friche
Rodler~\cite{Pagh04cuckoohashing}, a Cuckoo hashtable consists of two
same-sized tables each with its own hash function mapping a key to a table
location, providing two possible locations for each key.
Upon insertion of a new key, if both locations are already occupied by keys,
then one is kicked out and inserted in its alternate location, possibly
displacing yet another key, repeating the process until either a vacant
location is found, or some maximum number of iterations is reached.
The latter is bound to happen once cycles have formed in the {\em Cuckoo graph}.
This is a bipartite graph with a node for each location and an
edge for every inserted key, connecting the two locations it can reside at.
It matches the bipartite graph defined above if the cuckoo hashtable
were based on function $h$.
In fact, the insertion procedure suggests a simple algorithm for detecting cycles.

\section{Cycle detection in Cuckoo Cycle}
We enumerate the $M$ nonces, but instead of storing the nonce itself as a key
in the Cuckoo hashtable, we store the alternate key location,
and forget about the nonce.  We thus maintain the {\em directed}
cuckoo graph, in which the edge for a key is directed from the location where
it resides to its alternate location.  Moving a key to its alternate location
thus corresponds to reversing its edge.  The outdegree of every node in this
graph is either 0 or 1.  When there are no cycles yet, the graph is a {\em
forest}, a disjoint union of trees.  In each tree, all edges are directed,
directly, or indirectly, to its {\em root}, the only node in the tree with
outdegree 0.  Initially there are just $N$ singleton trees consisting of
individual nodes which are all roots.
Addition of a new key causes a cycle if and only if its two endpoints are
nodes in the same tree, which we can test by following the path from each
endpoint to its root.
In case of different roots, we reverse all edges on the shorter of the two
paths, and finally create the edge for the new key itself, thereby joining
the two trees into one. Let us illustrate this process with an actual example.

The left diagram in Figure~\ref{cycleformation} shows the directed cuckoo graph for header ``39'' on
$N=8+8$ nodes after adding edges
$(2,15),(4,9),(8,5),(4,15),(12,11),(10,5)$ and $(4,13)$ (nodes
with no incident edges are omitted for clarity).
In order to add the 8th edge $(10,11)$, we follow the paths $10 \rightarrow 5
\rightarrow 8$ and $11 \rightarrow 12$ to find different roots $8$ and $12$.
Since the latter path is shorter, we reverse it to $12 \rightarrow 11$ so we
can add the new edge as $(11 \rightarrow 10)$, resulting in the middle diagram.
In order to add to 9th edge
$(10,13)$ we now find the path from $10$ to be the shorter one, so we reverse
that and add the new edge as $(10 \rightarrow 13)$, resulting in the right diagram.
\begin{figure}
\begin{center}
\begin{tikzpicture}[>=stealth]
\node  (2) at (1, 2) [shape=circle,draw] {2};
\node  (4) at (2, 2) [shape=circle,draw] {4};
\node  (8) at (3, 2) [shape=circle,draw] {8};
\node (10) at (4, 2) [shape=circle,draw] {10};
\node (12) at (5, 2) [shape=circle,draw] {12};
\node  (5) at (1,-1) [shape=circle,draw] {5};
\node  (9) at (2,-1) [shape=circle,draw] {9};
\node (11) at (3,-1) [shape=circle,draw] {11};
\node (13) at (4,-1) [shape=circle,draw] {13};
\node (15) at (5,-1) [shape=circle,draw] {15};
\draw [<-]  (2) -- (15);
\draw [<-]  (4) -- (9);
\draw [<-]  (8) -- (5);
\draw [->]  (4) -- (15);
\draw [<-] (12) -- (11);
\draw [->] (10) -- (5);
\draw [<-]  (4) -- (13);
\end{tikzpicture}\hspace{1cm}\begin{tikzpicture}[>=stealth]
\node  (2) at (1, 2) [shape=circle,draw] {2};
\node  (4) at (2, 2) [shape=circle,draw] {4};
\node  (8) at (3, 2) [shape=circle,draw] {8};
\node (10) at (4, 2) [shape=circle,draw] {10};
\node (12) at (5, 2) [shape=circle,draw] {12};
\node  (5) at (1,-1) [shape=circle,draw] {5};
\node  (9) at (2,-1) [shape=circle,draw] {9};
\node (11) at (3,-1) [shape=circle,draw] {11};
\node (13) at (4,-1) [shape=circle,draw] {13};
\node (15) at (5,-1) [shape=circle,draw] {15};
\draw [<-]  (2) -- (15);
\draw [<-]  (4) -- (9);
\draw [<-]  (8) -- (5);
\draw [->]  (4) -- (15);
\draw [->] (12) -- (11);
\draw [->] (10) -- (5);
\draw [<-]  (4) -- (13);
\draw [<-] (10) -- (11);
\end{tikzpicture}\hspace{1cm}\begin{tikzpicture}[>=stealth]
\node  (2) at (1, 2) [shape=circle,draw] {2};
\node  (4) at (2, 2) [shape=circle,draw] {4};
\node  (8) at (3, 2) [shape=circle,draw] {8};
\node (10) at (4, 2) [shape=circle,draw] {10};
\node (12) at (5, 2) [shape=circle,draw] {12};
\node  (5) at (1,-1) [shape=circle,draw] {5};
\node  (9) at (2,-1) [shape=circle,draw] {9};
\node (11) at (3,-1) [shape=circle,draw] {11};
\node (13) at (4,-1) [shape=circle,draw] {13};
\node (15) at (5,-1) [shape=circle,draw] {15};
\draw [<-]  (2) -- (15);
\draw [<-]  (4) -- (9);
\draw [->]  (8) -- (5);
\draw [->]  (4) -- (15);
\draw [->] (12) -- (11);
\draw [<-] (10) -- (5);
\draw [<-]  (4) -- (13);
\draw [<-] (10) -- (11);
\draw [->] (10) -- (13);
\end{tikzpicture}
\end{center}
\caption{cycle formation and detection in a Cuckoo graph}
\label{cycleformation}
\end{figure}
When adding the 10th edge $(8,9)$, we find the paths $8 \rightarrow 5
\rightarrow 10 \rightarrow 13 \rightarrow 4 \rightarrow 15 \rightarrow 2$ and
$9 \rightarrow 4 \rightarrow 15 \rightarrow 2$ with equal roots.
In this case, we can compute the length of the resulting cycle as
1 plus the sum of the path-lengths to the node where the two paths join.
In the diagram, the paths join at node $4$, and the cycle length is computed as $1+4+1=6$.

\section{Union-find}
The above representation of the directed cuckoo graph is an example of
a {\em disjoint-set data structure}~\cite{wikidsds2014}, and our algorithm is
closely related to the well-known union-find algorithm, where the find operation
determines which subset an element is in, and the union operation joins two subsets
into a single one. For each edge addition to the cuckoo graph we perform the equivalent
of two find operations and one union operation.
The difference is that the union-find algorithm is free to add
directed edges between arbitrary elements. Thus it can join two subsets by adding an edge
from one root to another, with no need to reverse any edges.
Our algorithm on the other hand solves the union-find problem by maintaining
a direction on all union operations while keeping the maximum outdegree at 1.

\section{Cuckoo Cycle basic algorithm}
The above algorithm for inserting edges and detecting cycles forms the basis
for our basic proof-of-work algorithm.
If a cycle of length $L$ is found, then we solved the problem, and recover the proof
by storing the cycle edges in a set and enumerating nonces once more to see which ones
generate edges in the set.
If a cycle of a different length is found, then we keep the graph acyclic by ignoring the edge.
There is some risk of overlooking other $L$-cycles
through that edge, but when the expected number of cycles is low (which is what we design for),
this ignoring of cycle forming edges hardly affects the rate of solution finding.

This algorithm is available online at \url{https://github.com/tromp/cuckoo}
as either the C-program simple\_miner.cpp or the Java program SimpleMiner.java.
A proof verifier is available as cuckoo.c or Cuckoo.java, while the repository
also has a Makefile, as well as the latest version of this paper.
% `make test' tests everything.
`make example' reproduces the example shown above.
The simple program uses 32 bits per node to represent the directed cuckoo graph,
plus about 64KB per thread for two path-following arrays.
The left plot in Figure~\ref{runtimes} shows both the total runtime in seconds and the runtime of just
the hash computation, as a function of (log)size. The latter is purely
linear, while the former is superlinear due to increasing memory latency
as the nodes no longer fit in cache. The right plot show this more clearly
as the percentage of hashing to total runtime, ending up around 5\%.

\begin{figure}
\begin{center}
\begin{tikzpicture}
\begin{axis}[xlabel={$\mbox{log}_2(N)$}, ymode=log, ylabel={seconds}, legend pos=north west]
\addplot[color=red] coordinates {
% (10,0.0000) (11,0.0000) (12,0.0000) (13,0.0001) (14,0.0001)
(15,0.0002) (16,0.0004) (17,0.0008) (18,0.0017) (19,0.0034)
(20,0.0068) (21,0.0139) (22,0.0271) (23,0.0542) (24,0.1084)
(25,0.2166) (26,0.4336) (27,0.8658) (28,1.7322) (29,3.4719)
(30,7.0389) };
\addlegendentry{hashing runtime}
\addplot[color=green] coordinates {
% (10,0.0000) (11,0.0000) (12,0.0001) (13,0.0001) (14,0.0003)
(15,0.0002) (16,0.0010) (17,0.0022) (18,0.0049) (19,0.0104)
(20,0.0250) (21,0.0986) (22,0.2465) (23,0.5332) (24,1.1922)
(25,2.5505) (26,5.3394) (27,11.0793) (28,23.1984) (29,54.6811)
(30,128.1682) };
\addlegendentry{total runtime}
\end{axis}
\end{tikzpicture}
% \hspace{1cm}
\begin{tikzpicture}
\begin{axis}[xlabel={$\mbox{log}_2(N)$}, ylabel={\% runtime}, legend pos=north east]
\addplot[color=blue] coordinates {
% (10,38.8889) (11,33.3333) (12,45.1613) (13,39.8496) (14,44.6154)
(15,96.5217) (16,45.9119) (17,38.2180) (18,35.0988) (19,32.6724)
(20,27.2076) (21,14.0874) (22,11.0014) (23,10.1635) (24,9.0964)
(25,8.4921) (26,8.1215) (27,7.8144) (28,7.4670) (29,6.3494)
(30,5.4919) };
\addlegendentry{hashing percentage}
\end{axis}
\end{tikzpicture}
\end{center}
\caption{Runtime and compute intensity of the basic algorithm}
\label{runtimes}
\end{figure}

The left plot in Figure~\ref{accesses} shows the probability of finding a 42-cycle as a function
of the percentage edges/nodes, while the right plot shows the average number of
memory reads and writes per edge as a function of the percentage
of processed nonces (progress through main loop).
Both were determined from 10000 runs at size $2^{20}$;
results at size $2^{25}$ look almost identical.
In total the basic algorithm averages 3.3 reads and 1.1 writes per edge.

\begin{figure}
\begin{center}
\begin{tikzpicture}
\begin{axis}[xlabel={$\frac{M}{N}$ in \%}, ylabel={probability}, legend pos=north west]
\addplot[color=blue] coordinates {
(40,0) (41,0.00001) (42,0.00003) (43,0.0001) (44,0.00031) (45,0.00067)
(46,0.00141) (47,0.00385) (48,0.00967) (49,0.02222) (50,0.05076)
(51,0.10117) (52,0.17953) (53,0.27993) (54,0.39581) (55,0.51873)
(56,0.63614) (57,0.73955) (58,0.82352) (59,0.88719) (60,0.93182)
(61,0.9616) (62,0.97949) (63,0.98956) (64,0.99503) (65,0.99799)
(66,0.99907) (67,0.9996) (68,0.99989) (69,0.99997) (70,0.99998) (71,1) };
\addlegendentry{has 42-cycle}
\end{axis}
\end{tikzpicture}
% \hspace{1cm}
\begin{tikzpicture}
\begin{axis}[xlabel={\% nonces processed}, ylabel={\# memory accesses per nonce}, ymin=0, legend pos=north west]
\addplot[color=green] coordinates {
(0,2.01) (1,2.02) (2,2.03) (3,2.04) (4,2.05) (5,2.06) (6,2.07) (7,2.08) (8,2.09) (9,2.10) (10,2.11) (11,2.12) (12,2.13) (13,2.15) (14,2.16) (15,2.17) (16,2.18) (17,2.20) (18,2.21) (19,2.22) (20,2.23) (21,2.25) (22,2.26) (23,2.28) (24,2.29) (25,2.30) (26,2.32) (27,2.33) (28,2.35) (29,2.36) (30,2.38) (31,2.40) (32,2.41) (33,2.43) (34,2.45) (35,2.46) (36,2.48) (37,2.50) (38,2.52) (39,2.54) (40,2.56) (41,2.58) (42,2.60) (43,2.62) (44,2.64) (45,2.66) (46,2.68) (47,2.71) (48,2.73) (49,2.76) (50,2.78) (51,2.81) (52,2.83) (53,2.86) (54,2.89) (55,2.92) (56,2.95) (57,2.98) (58,3.01) (59,3.05) (60,3.08) (61,3.12) (62,3.15) (63,3.19) (64,3.23) (65,3.27) (66,3.32) (67,3.36) (68,3.41) (69,3.45) (70,3.51) (71,3.56) (72,3.61) (73,3.67) (74,3.73) (75,3.80) (76,3.86) (77,3.93) (78,4.01) (79,4.09) (80,4.17) (81,4.26) (82,4.36) (83,4.46) (84,4.57) (85,4.69) (86,4.83) (87,4.97) (88,5.13) (89,5.30) (90,5.49) (91,5.71) (92,5.96) (93,6.25) (94,6.59) (95,6.99) (96,7.51) (97,8.18) (98,9.20) (99,10.93) };
\addlegendentry{reads}
\addplot[color=red] coordinates {
(0,1.00) (1,1.00) (2,1.00) (3,1.00) (4,1.00) (5,1.00) (6,1.00) (7,1.00) (8,1.00) (9,1.00) (10,1.00) (11,1.00) (12,1.00) (13,1.00) (14,1.00) (15,1.00) (16,1.00) (17,1.00) (18,1.00) (19,1.00) (20,1.00) (21,1.00) (22,1.00) (23,1.01) (24,1.01) (25,1.01) (26,1.01) (27,1.01) (28,1.01) (29,1.01) (30,1.01) (31,1.01) (32,1.01) (33,1.02) (34,1.02) (35,1.02) (36,1.02) (37,1.02) (38,1.02) (39,1.02) (40,1.03) (41,1.03) (42,1.03) (43,1.03) (44,1.03) (45,1.04) (46,1.04) (47,1.04) (48,1.04) (49,1.05) (50,1.05) (51,1.05) (52,1.06) (53,1.06) (54,1.06) (55,1.07) (56,1.07) (57,1.07) (58,1.08) (59,1.08) (60,1.08) (61,1.09) (62,1.09) (63,1.10) (64,1.10) (65,1.11) (66,1.11) (67,1.12) (68,1.13) (69,1.13) (70,1.14) (71,1.14) (72,1.15) (73,1.16) (74,1.16) (75,1.17) (76,1.18) (77,1.19) (78,1.20) (79,1.21) (80,1.22) (81,1.23) (82,1.24) (83,1.25) (84,1.26) (85,1.27) (86,1.29) (87,1.30) (88,1.32) (89,1.33) (90,1.35) (91,1.37) (92,1.39) (93,1.41) (94,1.43) (95,1.46) (96,1.48) (97,1.51) (98,1.54) (99,1.58) };
\addlegendentry{writes}
\end{axis}
\end{tikzpicture}
\end{center}
\caption{Threshold nature of solution, and increasing memory usage on threshold approach}
\label{accesses}
\end{figure}

\section{Difficulty control}
The ratio $\frac{M}{N}$ determines a base level of difficulty,
which may suffice for applications where difficulty is to remain fixed.
Ratios $\frac{M}{N} \geq 0.7$ are suitable when a practically guaranteed solution is desired.

For crypto currencies, where difficulty must scale in precisely
controlled manner across a large range, adjusting the number of edges is not suitable.
The implementation default $\frac{M}{N}=\frac{1}{2}$ gives a solution probability of roughly $2.2\%$,
while the average number of cycles found increases slowly with size; from 2 at $2^{20}$
to 3 at $2^{30}$.

For further control, a difficulty target $0 < T < 2^{256}$ is introduced,
and we impose the additional constraint that the sha256 digest of the
cycle nonces in ascending order be less than $T$, thus
reducing the success probability by a factor $\frac{2^{256}}{T}$.

\section{Edge Trimming}
\label{edge_trimming}
David Andersen~\cite{dga2014} suggested drastically reducing the number of edges
our basic algorithm has to process, by repeatedly identifying nodes of degree one
and eliminating their incident edge. Such {\em leaf edges} can never be part of a cycle.
This works well when $\frac{M}{N} \leq \frac{1}{2}$ since the expected degree of a node is then at most 1,
and a significant fraction of edges are expected to be leaf edges.

Trimming is implemented in our main algorithm in cuckoo\_miner and hcuckoo\_miner.cpp.
It maintains a set of {\em alive} edges as a bit vector. Initially all edges are alive.
In each of a given number of trimming rounds, it shrinks this set as follows.
A vector of 2-bit degree counters, one per even node, is initialized to all zeroes.
Next, for all alive edges, compute its even endpoint and increase the corresponding counter,
capping the value at 2.
Next, for all alive edges, compute its even endpoint and if the corresponding counter is less than 2,
set the edge to be not-alive.
These steps, both of which cause the random accesses required in property MB2,
are repeated for all odd endpoints.

Preprocessor symbol PART\_BITS, whose value we'll denote as $B$,
allows for {\em counter partitioning}, which trades off node counter storage for runtime,
by processing nodes in multiple passes depending on the value of their $B$ least significant
bits\footnote{excluding the very least significant bit distinguishing even from odd nodes.}.
The memory usage is $M$ bits for the alive set and $N / 2^{B}$ for the counters.

The diagrams in Figure~\ref{trimming} show two rounds of edge trimming on the earlier example. In round one
even nodes 2 and 12 lose their single incident edge and in round two, odd nodes 11 and 15 lose
their remaining single incident edge. At this point only the 6-cycle is left, so further trimming
would be pointless.

\begin{figure}
\begin{center}
\begin{tikzpicture}[>=stealth]
\node  (2) at (1, 2) [shape=circle,draw] {2};
\node  (4) at (2, 2) [shape=circle,draw] {4};
\node  (8) at (3, 2) [shape=circle,draw] {8};
\node (10) at (4, 2) [shape=circle,draw] {10};
\node (12) at (5, 2) [shape=circle,draw] {12};
\node  (5) at (1,-1) [shape=circle,draw] {5};
\node  (9) at (2,-1) [shape=circle,draw] {9};
\node (11) at (3,-1) [shape=circle,draw] {11};
\node (13) at (4,-1) [shape=circle,draw] {13};
\node (15) at (5,-1) [shape=circle,draw] {15};
\draw [-]  (2) -- (15);
\draw [-]  (4) -- (9);
\draw [-]  (8) -- (5);
\draw [-]  (4) -- (15);
\draw [-] (12) -- (11);
\draw [-] (10) -- (5);
\draw [-]  (4) -- (13);
\draw [-] (10) -- (11);
\draw [-] (10) -- (13);
\draw [-]  (8) -- (9);
\end{tikzpicture}\hspace{1cm}\begin{tikzpicture}[>=stealth]
\node  (2) at (1, 2) [shape=circle,draw] {2};
\node  (4) at (2, 2) [shape=circle,draw] {4};
\node  (8) at (3, 2) [shape=circle,draw] {8};
\node (10) at (4, 2) [shape=circle,draw] {10};
\node (12) at (5, 2) [shape=circle,draw] {12};
\node  (5) at (1,-1) [shape=circle,draw] {5};
\node  (9) at (2,-1) [shape=circle,draw] {9};
\node (11) at (3,-1) [shape=circle,draw] {11};
\node (13) at (4,-1) [shape=circle,draw] {13};
\node (15) at (5,-1) [shape=circle,draw] {15};
\draw [-]  (4) -- (9);
\draw [-]  (8) -- (5);
\draw [-]  (4) -- (15);
\draw [-] (10) -- (5);
\draw [-]  (4) -- (13);
\draw [-] (10) -- (11);
\draw [-] (10) -- (13);
\draw [-]  (8) -- (9);
\end{tikzpicture}\hspace{1cm}\begin{tikzpicture}[>=stealth]
\node  (2) at (1, 2) [shape=circle,draw] {2};
\node  (4) at (2, 2) [shape=circle,draw] {4};
\node  (8) at (3, 2) [shape=circle,draw] {8};
\node (10) at (4, 2) [shape=circle,draw] {10};
\node (12) at (5, 2) [shape=circle,draw] {12};
\node  (5) at (1,-1) [shape=circle,draw] {5};
\node  (9) at (2,-1) [shape=circle,draw] {9};
\node (11) at (3,-1) [shape=circle,draw] {11};
\node (13) at (4,-1) [shape=circle,draw] {13};
\node (15) at (5,-1) [shape=circle,draw] {15};
\draw [-]  (4) -- (9);
\draw [-]  (8) -- (5);
\draw [-] (10) -- (5);
\draw [-]  (4) -- (13);
\draw [-] (10) -- (13);
\draw [-]  (8) -- (9);
\end{tikzpicture}
\end{center}
\caption{Trimming of edges which cannot be part of a cycle}
\label{trimming}
\end{figure}

After all edge trimming rounds, the counter memory is freed, and allocated to a
custom cuckoo\_hashtable (based on \cite{preshing2013}) that presents the same interface as the
simple array in the basic algorithm, but gets by with much fewer locations, as long as its {\em load},
the ratio of remaining edges to number of locations, is bounded away from 1; e.g. under 90 percent.

The number of trimming rounds, which can be set with option {\tt -n}, defaults to
$1+(B+3)*(B+4)/2$, which was determined empirically to achieve a load close to $50\%$.

\section{Time-Memory Trade-Offs (TMTOs)}
David Andersen also suggested an alternative method of trimming that avoids storing a bit per edge.
Expanding on that idea led to the algorithm implemented in tomato\_miner.h,
which, unlike the main algorithm, can trade-off memory directly for runtime.
On the downside, to even achieve memory parity with the main algorithm, it already incurs a big slowdown.
To the extent that this slowdown is unavoidable, it can be called
the {\em memory hardness} of the proof-of-work.

The TMTO algorithm selects a suitably small subset $Z$ of even vertices as a base layer,
and on top of that builds a breadth-first-search
(BFS) forest of depth $L/2$, i.e. half the cycle length.
For each new BFS layer, it enumerates all edges to see which ones are incident
to the previous layer, adding the other endpoint.
It maintains a directed forest on all BFS nodes, like the base algorithm does on all nodes.
For increased efficiency, the base layer $Z$ is filtered for nodes with multiple incident edges.
If the graph has an $L$-cycle one of whose nodes is in $Z$, then the above procedure will find it.
If one choice of $Z$ doesn't yield a solution, then the data structures are cleared and the next
subset is tried.

A variation on the above algorithm omits the filtering of $Z$, and expands
the BFS to a whole $L$ levels. This way, an $L$-cycle will be found as long as the distance from (any node in)
$Z$ to the cycle is at most $L/2$. It thus has a much higher chance of finding a cycle, but requires
more space to store the significantly bigger BFS forest.

For each each value of $L \in \{2,4,6,8,10,12,14,16,20,24,28,32,40,48,56,64\}$ we ran these 2 algorithms
on 200 graphs of size $2^{25}$ that include an $L$-cycle,
choosing subset size as a 2-power that results in a memory usage of 4MB,
and analysed the distribution of number of subsets tried before
finding a solution. Since there is possible overlap between the BFS forests of different initial subsets,
especially with the second algorithm, the distributions are skewed toward lower numbers. To maximize solution
finding rate then, it pays to give up on a graph when the first few subsets tried fail to provide a solution.
For each algorithm and cycle length, we determined the minimum number of tries needed to guarantee solutions
in at least 50 of the 200 graphs. In Figure~\ref{slowdown} we plot the slowdown relative
to the reference algorithm also using 4MB (2MB for edges and 2MB for nodes).

\begin{figure}
\begin{center}
\begin{tikzpicture}
% \begin{axis}[ymin=0, xtick={2,8,16,24,32,40,48,56,64}, xlabel={cycle length $L$}, ylabel={slowdown factor}, legend pos=north west]
\begin{axis}[ymin=0, xlabel={cycle length $L$}, ylabel={slowdown factor}, legend pos=north west]
\addplot [color=red] coordinates {
(2,2.8) (4,6.4) (6,9.7) (8,14.5) (10,13.0) (12,25.1) (14,29.0) (16,28.5)
(20,30.4) (24,46.0) (28,36.0) (32,43.3) (40,51.0) (48,82.2) (56,81.0) (64,72.7)
};
\addlegendentry{BFS($L/2$)}
\addplot [color=green] coordinates {
(4,14.4) (6,11.6) (8,20.7) (10,21.4) (12,13.9) (14,18.1) (16,26.8) (20,21.9)
(24,18.8) (28,23.3) (32,31.8) (40,42.6) (48,35.6) (56,22.2) (64,41.0)
};
\addlegendentry{BFS($L$)}
%\addplot [color=blue, mark=o] coordinates {
%(2, 1.4)
%};
%\addlegendentry{customized}
\addlegendentry{}
\end{axis}
\end{tikzpicture}
\end{center}
\caption{Reduction in solution finding rate for two TMTO algorithms}
\label{slowdown}
\end{figure}

The zigzagging is caused by the current implementation being limited to 2-power sizes of
both subsets and cuckoo tables while the load of the latter is kept between 45\% and 90.
%We plan to lift this restriction in the near future and
%produce smoother plots with constant load cuckoo tables.
The BFS($L$) algorithm exhibits at least one order of magnitude slowdown, that grows very slowly
with cycle length, while the BFS($L/2$) algorithm exhibits roughly linear slowdown.
Assuming that these algorithms cannot be significantly improved upon,
this shows Cuckoo Cycle with larger cycle lengths satisfying property MB4,

\section{Choice of cycle length}
\label{cycle_length_choice}
A cycle of length 2 means that two nonces produce identical edge endpoints---a {\em collision} in edge space.
The Momentum proof-of-work looks for collisions on 50 bits of hash output among $2^{26}$ nonces.
This is in essence Cuckoo Cycle with $N=2^{25}+2^{25}$ nodes and cycle length $L=2$, with
two differences.

First, edges are generated not by equation~(\ref{hash_edges}), but by splitting a SHA512 hash of
$(k,\mbox{nonce} / 8)$ into 8 64-bit words, taking the most significant 50 bits of the
($\mbox{nonce} \bmod 8)th$ one, and viewing that as a pair of two 25-bit edge endpoints, appending
a bit to make them even and odd.

Second, the choice of $M=2^{26}$ gives a ratio $\frac{M}{N}$ of 1 rather than $\frac{1}{2}$ and as such
prohibits the use of edge trimming.

Since the extreme case of $L=2$ is so special, there is likely to be a greater variety of algorithms that are more
efficient than for the general case. While we haven't found (and don't know of) a improved main algorithm,
we did find an improved BFS($L/2$) TMTO algorithm (implemented in momentomatum.cpp)
that cuts the memory usage in half, resulting in a slowdown of only $1.75$---a lack of memory-hardness.

The preceding analysis suggests that cycle length should be at least 20 to guard against the more efficient
BFS($L/2$) algorithm, with an additional safety factor of 2.

In order to keep proof size manageable, the cycle length should not be too large either.
We thus consider 20-64 to be a healthy range, and suggest the use of the average of 42.

The plot below shows the distribution of cycle lengths found for sizes $2^{10},2^{15},2^{20},2^{25}$,
as determined from 100000,100000,10000, and 10000 runs respectively. The tails of the distributions
beyond $L=100$ are not shown. For reference, the longest cycle found was of length 2120.

\begin{figure}
\begin{center}
\begin{tikzpicture}
\begin{axis}[ymin=0, xlabel={cycle length $L$}, ylabel={probability}, legend pos=north east]
\addplot[color=orange] coordinates {
(4,0.24862) (6,0.15673) (8,0.10907) (10,0.07952) (12,0.05783) (14,0.04269) (16,0.0303)
(18,0.02237) (20,0.01653) (22,0.01168) (24,0.00815) (26,0.00511) (28,0.00374) (30,0.00251)
(32,0.00191) (34,0.00098) (36,0.00079) (38,0.00029) (40,0.0003) (42,0.00011) (44,0.00018)
(46,8e-05) (48,2e-05) (50,3e-05) };
\addlegendentry{10}
\addplot[color=green] coordinates {
(4,0.24822) (6,0.16551) (8,0.12317) (10,0.09749) (12,0.08105) (14,0.07036) (16,0.05871) (18,0.05308)
(20,0.04717) (22,0.04189) (24,0.03801) (26,0.03342) (28,0.03205) (30,0.02822) (32,0.02521)
(34,0.02282) (36,0.0212) (38,0.01852) (40,0.01814) (42,0.01668) (44,0.01511) (46,0.01356)
(48,0.01246) (50,0.01145) (52,0.0101) (54,0.0093) (56,0.00861) (58,0.00778) (60,0.00768)
(62,0.00672) (64,0.00589) (66,0.00565) (68,0.00517) (70,0.00455) (72,0.00435) (74,0.00375)
(76,0.00348) (78,0.00286) (80,0.00276) (82,0.0023) (84,0.00224) (86,0.00204) (88,0.00165)
(90,0.00164) (92,0.00134) (94,0.00126) (96,0.00114) (98,0.00103) (100,0.00101) };
\addlegendentry{15}
\addplot[color=red] coordinates {
(4,0.249) (6,0.1666) (8,0.1309) (10,0.0977) (12,0.0821) (14,0.0754) (16,0.0612) (18,0.0569)
(20,0.0504) (22,0.0412) (24,0.0438) (26,0.0385) (28,0.0364) (30,0.0349) (32,0.0328) (34,0.0286)
(36,0.0263) (38,0.0283) (40,0.0244) (42,0.0237) (44,0.0213) (46,0.0197) (48,0.0185) (50,0.0171)
(52,0.0169) (54,0.0204) (56,0.0161) (58,0.0155) (60,0.0153) (62,0.0158) (64,0.0135) (66,0.0135)
(68,0.0118) (70,0.0158) (72,0.0137) (74,0.012) (76,0.0108) (78,0.0119) (80,0.0116) (82,0.0106)
(84,0.0112) (86,0.0102) (88,0.0075) (90,0.0096) (92,0.0091) (94,0.0094) (96,0.0077) (98,0.0089)
(100,0.006) };
\addlegendentry{20}
\addplot[color=blue] coordinates {
(4,0.2439) (6,0.1661) (8,0.1216) (10,0.1031) (12,0.0816) (14,0.0755) (16,0.0635) (18,0.055) (20,0.0511) (22,0.0451) (24,0.0427) (26,0.0369) (28,0.0375) (30,0.0336) (32,0.0302) (34,0.0297) (36,0.0264) (38,0.0268) (40,0.0254) (42,0.0215) (44,0.021) (46,0.0205) (48,0.0206) (50,0.0182) (52,0.017) (54,0.0192) (56,0.0172) (58,0.0169) (60,0.0167) (62,0.0147) (64,0.0169) (66,0.0137) (68,0.0169) (70,0.0125) (72,0.0127) (74,0.0123) (76,0.0139) (78,0.0122) (80,0.0131) (82,0.0129) (84,0.012) (86,0.0119) (88,0.0102) (90,0.0088) (92,0.0102) (94,0.0115) (96,0.0108) (98,0.0089) (100,0.0104) };
\addlegendentry{25}
\end{axis}
\end{tikzpicture}
\end{center}
\caption{Distribution of cycle lengths in random graphs}
\label{cyclelengths}
\end{figure}

\section{Parallelization}
All our implementations allow the number of threads to be set with option {\tt -t}.
For $0\leq t < T$, thread $t$ processes all nonces $t \bmod T$.
Parallelization in the basic algorithm presents some minor algorithmic challenges.
Paths from an edge's two endpoints
are not well-defined when other edge additions and path reversals are still in progress.
One example of such a path conflict is the check for duplicate edges yielding a false negative,
if in between checking the two endpoints, another thread reverses a path through those nodes.
Another is the inadvertent creation of cycles when a reversal in progress hampers another thread's
path following causing it to overlook root equality.
Thus, in a parallel implementation, path following can no longer be assumed to terminate.
Instead of using a cycle detection algorithm such as~\cite{1980-brent-cycles}, our implementation
notices when the path length exceeds MAXPATHLEN (8192 by default),
and reports whether this is due to a path conflict.

In the main algorithm, cycle detection only takes a small fraction of total runtime and
the conflicts above could be avoided altogether by running the cycle detection single threaded.

In edge trimming, parallelization is achieved by partitioning the set of edges. To maintain efficient access
to the bitmap of live edges, each thread handles words (of 32 edge-bits each) spaced $T$ apart.
%Partitioning the bitmap over threads by whole words also avoids the need for atomic access.

Atomic access is used by default for accessing the 2-bit counters. Disabling this results in a small
chance of removing multiple edges incident to a node that access the counter at the same time.

The implementation further benefits from bucketing the addresses of counters to be updated or tested,
based on their most significant bits. Thus, when a bucket becomes full and is emptied by actually
performing those updates/tests, the accesses are limited to a certain address range, which turns
out to reduce memory access latencies.

The plots below show the speedup over single thread performance achieved by multithreading at various
graph sizes and counter-partition levels.

\begin{figure}
\begin{center}
\begin{tikzpicture}
\begin{axis}[ymin=0, xlabel={number of threads}, ylabel={speedup factor}, legend pos=north west]
\addplot [color=green] coordinates {
(1,1.000) (2,1.921) (3,2.988) (4,3.757) (5,4.668)
(6,5.347) (7,6.138) (8,6.792) (9,7.504) (10,8.108)
(11,8.873) (12,9.380) (13,10.061) (14,10.543) (15,11.190)
(16,11.608) (17,12.231) (18,12.535) (19,13.008) (20,13.433)
};
\addlegendentry{speedup30}
\addplot [color=blue] coordinates {
(1,1.336) (2,2.179) (3,3.148) (4,3.984) (5,4.781)
(6,5.462) (7,6.061) (8,6.706) (9,7.354) (10,7.876)
(11,8.333) (12,9.036) (13,9.457) (14,9.838) (15,10.250)
(16,10.713) (17,11.048) (18,11.479) (19,11.736) (20,12.088)
};
\addlegendentry{speedup30.0}
\addplot [color=purple] coordinates {
(1,0.795) (2,1.416) (3,2.082) (4,2.683) (5,3.255)
(6,3.762) (7,4.285) (8,4.759) (9,5.222) (10,5.639)
(11,6.105) (12,6.605) (13,7.033) (14,7.400) (15,7.821)
(16,8.144) (17,8.583) (18,9.014) (19,9.303) (20,9.585)
};
\addlegendentry{speedup30.1}
\addplot [color=red] coordinates {
(1,0.498) (2,0.919) (3,1.373) (4,1.761) (5,2.176)
(6,2.538) (7,2.913) (8,3.234) (9,3.599) (10,3.883)
(11,4.239) (12,4.527) (13,4.903) (14,5.234) (15,5.570)
(16,5.845) (17,6.194) (18,6.511) (19,6.661) (20,7.003)
};
\addlegendentry{speedup30.2}
\end{axis}
\end{tikzpicture}
% \hspace{1cm}
\begin{tikzpicture}
\begin{axis}[ymin=0, xlabel={number of threads}, ylabel={speedup factor}, legend pos=north west]
\addplot [color=green] coordinates {
(1,1.000) (2,1.752) (3,2.813) (4,3.439) (5,5.810)
(6,6.762) (7,7.732) (8,8.669) (9,9.646) (10,10.460)
(11,11.348) (12,12.077) (13,13.107) (14,13.663) (15,14.698)
(16,15.363) (17,16.202) (18,16.623) (19,17.446) (20,18.207)
};
\addlegendentry{speedup32}
\addplot [color=blue] coordinates {
(1,2.337) (2,3.767) (3,5.445) (4,6.949) (5,8.319)
(6,9.432) (7,10.462) (8,11.632) (9,12.648) (10,13.658)
(11,14.717) (12,15.652) (13,16.461) (14,17.286) (15,18.063)
(16,18.393) (17,19.149) (18,19.647) (19,20.169) (20,20.761)
};
\addlegendentry{speedup32.0}
\addplot [color=purple] coordinates {
(1,1.343) (2,2.404) (3,3.534) (4,4.526) (5,5.570)
(6,6.410) (7,7.367) (8,8.208) (9,9.085) (10,9.932)
(11,10.707) (12,11.590) (13,12.297) (14,12.954) (15,13.647)
(16,14.294) (17,15.060) (18,15.718) (19,16.371) (20,16.804)
};
\addlegendentry{speedup32.1}

\end{axis}
\end{tikzpicture}
\end{center}
\caption{Multi-threading speedup}
\label{speedup}
\end{figure}

\section{Choice of graph size}
For cryptocurrency purposes, the choice of Cuckoo graph size should be in accordance to its
block interval time.
To illustrate, suppose an average desktop machine needs 1 minute for a single proof attempt,
and the block interval time is only 2 minutes. Then it will waste a large fraction (almost half)
of its attempts, as about half the time, someone else finds a proof in under 2 minutes. To reduce such waste
to a small percentage, the time for a single proof attempt should be a similarly small fraction of the block
interval time. This desirable property is known as {\em progress-freeness}, and in our case
is achieved more easily with a small graph (and hence memory) size.

Larger memory sizes have two advantages. Beyond satisfying property MB1,
they also make it harder for botnets to mine without causing excessive swapping.
Sending a computer into swap-hell will likely alert its owner and trigger a cleanup,
so botnet operators can be expected to eschew memory bound PoWs in favor of low-memory ones.

We expect these opposing goals to lead to graph sizes from $2^{28}$ to $2^{32}$, with the larger ones geared
more toward longer block interval times and faster mining hardware.

\section{Dynamic Sizing}
Ideally, graph size should grow with evolving memory chip capacities, so as to preserve property MB1.
Although these have shown remarkable adherence to Moore's Law in the past,
this cannot be relied on for the more distant future.
We therefore propose to re-evaluate the graph size every so-many difficulty adjustments.
If the difficulty target is sufficiently low, then the
graph size is deemed to have become "too easy" for existing hardware, and gets doubled.

In order to make this transition smoother and avoid severe loss of proof-of-work power,
we propose having a range of sizes allowed at any time,
namely $k$ consecutive 2-powers for some small number $k\geq 2$.
As with Myriad-coin, separate difficulty controls are maintained for each size,
adjusted so that each size accounts for roughly $\frac{1}{k}$ of all blocks.

Doubling graph sizes is then equivalent to disabling the smallest 2-power,
and enabling a new largest one, whose initial difficulty target is twice that of the previous largest.
Even if none of the hardware that was working on the smallest 2-power is repurposed for a larger size,
since this hardware only accounted for a fraction $\frac{1}{k}$ of the rewards, the loss of
proof-of-work power should be acceptable.

It remains to decide what exact form the ``difficulties too low'' condition should take.

\section{Conclusion}
Cuckoo Cycle is a novel graph-theoretic proof-of-work design that combines
scalable memory requirements with instant verifiability,
and the first where memory latency dominates the runtime.

Barring any unforeseen memory-time trade-offs, it makes for a near-ideal memory bound proof-of-work
whose cost effectiveness on commodity hardware could greatly benefit decentralization of mining.
% More research is also needed to determine the effectiveness of GPUs and FPGAs
% at running Cuckoo Cycle.

\bibliographystyle{IEEEtran}
\bibliography{cuckoo}

\lstset{language=C,basicstyle=\footnotesize}
\section{Appendix A: cuckoo.h}
\lstinputlisting{../src/cuckoo.h}

%\section{Appendix B: cuckoo\_miner.h}
%\lstinputlisting{cuckoo_miner.h}

%\section{Appendix C: cuckoo\_miner.cpp}
%\lstinputlisting{cuckoo_miner.cpp}

\end{document}