\documentclass[paper=a4,11pt,headsepline]{scrartcl}

\usepackage[margin=2cm]{geometry}
\usepackage[fleqn]{amsmath}
\usepackage{amssymb}
\usepackage{bm}
\usepackage{minted}
\usepackage{booktabs}
\usepackage{url}
\usepackage[
    colorlinks=true,
    linkcolor=black,
    citecolor=black,
    urlcolor=black,
    hyperfootnotes=true,
]{hyperref}
\usepackage{cancel}
\usepackage{xspace}
\usepackage{cleveref}
\usepackage{environ}
\usepackage[
    backend=biber,
    maxbibnames=2,
    giveninits=true,
    url=true,
    isbn=false,
    sorting=none,
    date=year,
]{biblatex}

\addbibresource{lit.bib}

\include{nc}

\newcommand{\ipmpy}[1]{\inputminted[xleftmargin=0.9cm]{python}{#1}}

% https://tex.stackexchange.com/a/5652
\NewEnviron{splitequation}{%
    \begin{equation}
        \begin{split}
            \BODY
        \end{split}
    \end{equation}
}

\begin{document}

\tableofcontents
\newpage

\section{Introduction}

This text is a short introduction to Automatic Differentiation (AD). The main
references are \cite{baydin_2018, johnson_2017, jax_autodiff_cookbook}. We
focus (for now) on basics linear computation graphs to introduce forward and
reverse mode, as well as differences between \jax and \pytorch (and a bit of
the older \autograd, the predecessor to \jax and one of the bases for
\pytorch's AD system \cite{paszke_2017}).

\section{Methods to evaluate derivatives}

This overview is inspired mostly by \cite{baydin_2018}.

\begin{itemize}
    \item Work out analytic derivatives by hand (or really Mathematica, Maple, Maxima, ...)
        and code them. Can be an advantage when the expression you want to
        differentiate never changes, e.g. derivatives of classical force
        fields in molecular simulations. Code of derivatives can be
        hand-optimized for speed.
    \item Call symbolic engines (e.g. \soft{sympy}) in your code to get
        analytic derivatives.
    \item Numerical derivatives by finite differences (FD). Use at least
        the central differences method. Good for checking AD or manually coded
        derivatives. Scales as $\mathcal O(n)$ for $\nabla f(\ve x), \ve
        x\in\mathbb R^n$.
    \item AD
        \begin{itemize}
            \item Directly provides numerical values for derivatives at some point
                $\ve x$ \emph{with machine precision}, \emph{not} symbolic expressions of
                derivatives
            \item Uses operator overloading (or other methods) to carry out
                derivatives (\jax, \pytorch: define JVPs/VJPs, see below)
            \item Can be applied to almost any code using arbitrary control flows
            \item In reverse mode: uses code tracing ("taping") by one forward eval
                to construct computation graph
            \item No "code swell": complex analytic expressions that grow which each
                application of $\partial/\partial x_i$ in symbolic engines and that
                need an additional simplification step
        \end{itemize}
\end{itemize}

\section{Forward and reverse AD}

\subsection{Setting the stage}

First consider a scalar function of scalar inputs $f:\mathbb R\ra\mathbb R$
\begin{equation}
    f(x) = c(b(a(x)))
\end{equation}
which implies the computation graph $x\ra a\ra b\ra c = f$. Forward = $x \ra c$ (inputs
to outputs). Reverse = $x \la c$ (outputs to inputs).
The derivative using the chain rule is given by
\begin{splitequation}
    \td{f}{x}
        &= \td{c}{b}\,\td{b}{a}\,\td{a}{x}\\
        &= \td{c}{b}\,\left(\td{b}{a}\,\td{a}{x}\right)&&\quad\text{forward}\\
        &= \left(\td{c}{b}\,\td{b}{a}\right)\,\td{a}{x}&&\quad\text{reverse}
\end{splitequation}

Now we consider the general case of a multivariate vector-valued function $\ve
f: \mathbb R^n \ra \mathbb R^m$. The Jacobian is the matrix of all first
partial derivatives and is defined as
%
\begin{equation}
    \ve f: \mathbb R^n \ra \mathbb R^m,\quad \ma J
    = \pd{\ve f}{\ve x} =
    \begin{bmatrix}
        \pd{f_1}{x_1} & \cdots & \pd{f_1}{x_n}  \\
        \vdots        & \ddots & \vdots         \\
        \pd{f_m}{x_1} & \cdots & \pd{f_m}{x_n}
    \end{bmatrix}
    \in\mathbb R^{m\times n}
    \eqdot
\end{equation}
One edge case is
\begin{equation}
    \ve f: \mathbb R^1 \ra \mathbb R^m\quad \ma J
    = \pd{\ve f}{x} =
    \begin{bmatrix}
        \pd{f_1}{x_1}  \\
        \vdots         \\
        \pd{f_m}{x_1}
    \end{bmatrix}
    = \ma J[:,1]\in\mathbb R^{m\times 1}
\end{equation}
where we need only the first column $\ma J[:,1]$. In the other edge case
\begin{equation}
    f: \mathbb R^n \ra \mathbb R^1\quad \ma J
    = \pd{f}{\ve x} =
    \begin{bmatrix}
        \pd{f_1}{x_1} & \cdots & \pd{f_1}{x_n}
    \end{bmatrix} \equiv \nabla f
    = \ma J[1,:] \in\mathbb R^{1\times n}
\end{equation}
we need the first row $\ma J[1,:]$ only. This is also the definition of the
\emph{gradient} $\nabla f(\ve x)\in\mathbb R^n,\: f: \mathbb R^n\ra\mathbb R$.

Note that in the ML literature all partial derivatives including those in
Jacobians and Hessians are often called "gradients", which might confuse you if
you have a physics background :)

\subsection{Vectorized functions}

Vectorized functions (e.g. \verb|sin()| in \numpy, \jax, \pytorch) are a
bit of a special case since, depending on input, they are either $f(x):\mathbb
R\ra\mathbb R$ when given a scalar or $\ve f(\ve x):\mathbb R^n\ra\mathbb R^n$
when given a vector, but never $f(\ve x): \mathbb R^n \ra \mathbb R$ (i.e. the
gradient $\nabla f(\ve x)$ is not defined for them). Importantly we have
$f_i\equiv f$: each $f_i$ is a function of only the $x_i$ it is applied to.
Therefore, the Jacobian is always diagonal, which is a very neat property that
we'll use later.

\subsection{Forward}

Again we have
\begin{equation}
    \ve f(\ve x) = \ve c(\ve b(\ve a(\ve x)))
\end{equation}
and can use the chain rule
\begin{equation}
    \ma J=\pd{\ve f}{\ve x} = \pd{\ve c}{\ve b}\,\pd{\ve b}{\ve a}\,\pd{\ve a}{\ve x}
\end{equation}
which implies a series of matrix multiplications of individual Jacobians $\pdi{\ve
a}{\ve x}$, $\pdi{\ve b}{\ve a}$, $\pdi{\ve c}{\ve b}$.
We can now right-multiply $\ma J$ with the identity
matrix $\pdi{\ve x}{\ve x}$
\begin{equation}
    \pd{\ve f}{\ve x}\,\pd{\ve x}{\ve x} =
    \pd{\ve c}{\ve b}\,\pd{\ve b}{\ve a}\,\pd{\ve a}{\ve x}\,\pd{\ve x}{\ve x}
\end{equation}
which doesn't change anything. We can also think of this as extracting the
$j$-th column $\ma J[:,j]$ by multiplying from the right with one column of the
identity $\partial\ve x/\partial x_j = \ve e_j = \tp{[0,0,\cdots,1,\cdots, 0]}$.
This will thus select the $x_j$ w.r.t. to which we want to calculate the
derivative. Analytically this means for an example $2\times 2$ system and choosing
$x_j = x_1$
\begin{equation}
    \pd{\ve f}{\ve x}\,\pd{\ve x}{x_1}=
    \begin{bmatrix}
        \pd{f_1}{x_1} & \pd{f_1}{x_2} \\
        \pd{f_2}{x_1} & \pd{f_2}{x_2} \\
    \end{bmatrix}
    \begin{bmatrix}
        \pd{x_1}{x_1} \\
        \pd{x_2}{x_1} \\
    \end{bmatrix}
    =
    \begin{bmatrix}
        \pd{f_1}{x_1}\,\pd{x_1}{x_1} + \cancelto{0}{\pd{f_1}{x_2}\,\pd{x_2}{x_1}} \\
        \pd{f_2}{x_1}\,\pd{x_1}{x_1} + \cancelto{0}{\pd{f_2}{x_2}\,\pd{x_2}{x_1}} \\
    \end{bmatrix}
    =
    \begin{bmatrix}
        \pd{f_1}{x_1} \\
        \pd{f_2}{x_1} \\
    \end{bmatrix}
\end{equation}
%
if we note that $\pdi{x_2}{x_1}=0$ and that formally by the chain rule
%
\begin{gather}
    \pd{f_1}{x_1}\,\pd{x_1}{x_1} = \pd{f_1}{x_1} \\
    \pd{f_2}{x_1}\,\pd{x_1}{x_1} = \pd{f_2}{x_1}
    \eqdot
\end{gather}
%
Now, of course we don't want to build up Jacobians. The trick is to evaluate
the expression by using pre-defined derivatives of \emph{primitive}
functions (here $\ve a(\cdot)$, $\ve b(\cdot)$, $\ve c(\cdot)$)\footnote{Any
basic (\numpy) function like \co{sin}, \co{sum} or \co{sqrt} that we can't or
won't represent in terms of even more basic functions.} and by repeated
application of a \emph{\red{Jacobian} \blue{vector} product (JVP)}. We
initialize with $\ve e_j$ and apply JVPs as we go.
%
\begin{splitequation}
    \pd{\ve f}{\ve x}\,\blue{\pd{\ve x}{x_j}} = \pd{\ve f}{\ve x}\,\blue{\ve e_j}
            &= \pd{\ve c}{\ve b}\,\pd{\ve b}{\ve a}\,\red{\pd{\ve a}{\ve x}}\,\blue{\ve e_j} \\
            &= \pd{\ve c}{\ve b}\,\red{\pd{\ve b}{\ve a}}\,\blue{\ve v_j} \\
            &= \red{\pd{\ve c}{\ve b}}\,\blue{\ve v_j'} \\
            &= \ma J[:,j]
\end{splitequation}
%
Now what is a JVP? We see that in order to evaluate the chain rule, each
primitive function $\ve z(\cdot) = \ve a(\cdot), \ve b(\cdot), \ve c(\cdot)$
needs to know ($i$) how it would evaluate its own derivative (Jacobian
$\pdi{\ve z}{\ve{\tau}}$, e.g. $\pdi{\ve b}{\ve a}$) w.r.t. its inputs $\ve{\tau}$ and ($ii$)
how to right-multiply that with a given vector $\ve v$. By doing ($ii$), we can
always initialize the process by $\ve e_j$ and then multiply forward (recall
that forward means $x\ra c$, i.e. from inputs to outputs). Now how do we
do $(i)$? The answer is that we don't, in the sense that we don't need to
instantiate Jacobians. Instead, we \emph{augment} each primitive function $\ve
z(\cdot)$ with a JVP such that we map the so-called
\emph{primal}-\emph{tangent} pair $(\ve x, \ve v)$ to the function at $\ve x$
and its JVP with $\ve v$.
%
\begin{equation}
    (\ve x, \ve v) \mapsto \left(\ve z(\ve x), \red{\pd{\ve z}{\ve\tau}}\,\blue{\ve v}\right)
\end{equation}
%
Each primitive function has an associated JVP function defined (\jax: by using
\co{jax.defjvp}\footnote{The name of this and details of its usage may vary
across \jax versions.}) which gets called when evaluating the chain rule. At
each step through the chain rule along the comp graph, we evaluate the
function's value $\ve z(\ve x)$ \emph{and} its JVP $\red{\pdi{\ve
z}{\ve{\tau}}}\,\blue{\ve v}$ together in lock step. Now, the most
important trick is that the intermediate Jacobians are never explicitly build.
The JVP function only has to return the \emph{result} of $\pdi{\ve
z}{\ve{\tau}}\,\ve v$. Especially, for \numpy's vectorized functions, all
Jacobians are diagonal, which makes implementing $\pdi{\ve z}{\ve{\tau}}\,\ve
v$ simple and efficient. In most cases, we get away with element-wise
operations on \ve v.

Side note: in the AD literature, applying JVPs is also called
"push-forward" of the vector (here $\ve e_j$) from inputs to outputs ($\ve x\ra\ve c$).

When we repeat the process and apply all possible $\ve e_j$ (i.e. the whole
identity matrix), we can build up the full $\ma J$ if we need to, one column at
a time. For the edge case $\ve f(x): \mathbb R^1 \ra \mathbb R^m$ ($n=1$, first column)
we are finished in one forward pass. In general forward mode is efficient for
"tall" Jacobians where $m\gg n$ and inefficient for "wide" ones where $m\ll n$.
The other edge case $f(\ve x): \mathbb R^n \ra \mathbb R^1$ ($m=1$, first row a.k.a.
$\nabla f(\ve x)$) is inefficient in forward mode since we need $n$ passes to
calculate each $\pdi{f}{x_j}$. This has thus similar complexity as finite
differences, where we also repeat $n$ times something like $(f(\ve x +\ve e_j\,h) - f(\ve
x-\ve e_j h))/2\,h$.

\subsection{Reverse}

First, we do a forward pass to trace the execution done in $\ve f$ to build up
the graph $\ve x\ra \ve a\ra \ve b\ra \ve c = \ve f$. Then we can extract the
$i$-th row $\ma J[i,:]$ by multiplying from the left with $\pdi{\ve f}{f_i} =
\ve e_i$. Analytically, we have
\begin{splitequation}
    \left(\pd{\ve f}{f_1}\right)^\top\,\pd{\ve f}{\ve x}
    &=
    \begin{bmatrix}
        \pd{f_1}{f_1} & \pd{f_2}{f_1} \\
    \end{bmatrix}
    \begin{bmatrix}
        \pd{f_1}{x_1} & \pd{f_1}{x_2} \\
        \pd{f_2}{x_1} & \pd{f_2}{x_2} \\
    \end{bmatrix}
    \\
    &=
    \begin{bmatrix}
        \pd{f_1}{f_1}\,\pd{f_1}{x_1} + \cancelto{0}{\pd{f_2}{f_1}\,\pd{f_2}{x_1}} &
        \pd{f_1}{f_1}\,\pd{f_1}{x_2} + \cancelto{0}{\pd{f_2}{f_1}\,\pd{f_2}{x_2}}
    \end{bmatrix}
    \\
    &=
    \begin{bmatrix}
        \pd{f_1}{x_1} & \pd{f_1}{x_2}
    \end{bmatrix}
\end{splitequation}
with $\pdi{f_2}{f_1}=0$.
In the code, we initialize with $\ve e_i$ and this time apply
\emph{\blue{vector} \red{Jacobian} products (VJPs)} as we go.
\begin{splitequation}
    \blue{\left(\pd{\ve f}{f_i}\right)^\top}\,\pd{\ve f}{\ve x} = \blue{\ve e_i^\top}\,\pd{\ve f}{\ve x}
        &= \blue{\ve e_i^\top}\,\red{\pd{\ve c}{\ve b}}\,\pd{\ve b}{\ve a}\,\pd{\ve a}{\ve x}\\
        &= \blue{\ve v_i^\top}\,\red{\pd{\ve b}{\ve a}}\,\pd{\ve a}{\ve x}\\
        &= \blue{\ve v_i'^\top}\,\red{\pd{\ve a}{\ve x}}\\
        &= \ma J[i,:]
\end{splitequation}
Again, we can apply all possible $\ve e_i$ to build up the full $\ma J$, this
time one row at a time. For the edge case $f(\ve x): \mathbb R^n \ra \mathbb
R^1$ ($m=1$, first row) we are done in one backward pass.

Side note: in the AD literature, applying VJPs is also called "pull-back" of
the vector (here $\ve e_i$) from outputs to inputs ($\ve x\la\ve c$).

\subsection{Reverse mode in neural network training a.k.a. backprop}

NN training loss function: a multivariate function $f(\ve x): \mathbb R^n\ra \mathbb R$
\begin{equation}
    f(\ve x) = c(\ve b(\ve a(\ve x)))
\end{equation}
for instance
\begin{minted}{python}
    f = lambda x: c(b(a(x)))
    f = lambda x: sum(power(sin(x),2))
\end{minted}
i.e. the composition of a number of vector-valued functions\footnote{ The NN
training loss' computation graph is of course not short and linear as in our
example.} $\ve a(\cdot), \ve b(\cdot)$ and a final reduction $c(\cdot): \mathbb
R^n\ra \mathbb R$ and where $n$ is "large" (as in $10^6$) and $\ve x$ are the
network's parameters. This is exactly the second edge case from above. When
using reverse mode, we get the gradient $\pdi{f}{\ve x} = \ma J[1,:]$ in a
single reverse pass (i.e. backprop).

\section{Comparison of implementations}

\subsection{\jax, \autograd}

Both are designed to be functional, like \numpy itself. \co{grad()} returns a
function object that evaluates $\nabla f(\ve x)$.
%
\ipmpy{../talk/code/jax_ad_teaser_grad_usage.py}
%
\jax returns \co{DeviceArray} objects because it uses \tf's XLA compiler.
\autograd returns plain \numpy arrays.

\subsection{\pytorch}
%
\pytorch is not functional\footnote{However, there is the experimental
\co{torch.autograd.functional} (checked: v1.8.1).}, it thinks in terms of
\co{torch.Tensor} objects, so when using our little example from above, now
written in \pytorch syntax
%
\ipmpy{../talk/code/pytorch_fwd_rev_1.py}
%
we use the "loss tensor" \co{c} of shape \co{(1,)} instead of the loss function
\co{f}. With knowledge of reverse mode, we can make sense of \pytorch's API
design. Below, we unpack the calculation step by step. Observe how each tensor
has a \verb|grad_fn| attribute which corresponds to defined VJPs. In \pytorch
the tracing of forward ops is implemented such tensors record
operations applied to them.
%
\ipmpy{../talk/code/pytorch_fwd_rev_2.py}
%
Then, we call the \co{backward()} method of the final output tensor, here
\co{c}.
%
\ipmpy{../talk/code/pytorch_fwd_rev_3.py}
%
This "pulls back" the derivatives (starting with $\pdi{f}{f}=1$) from the
output \co{c} to the input and the derivatives are stored in $\pdi{c}{\ve x} =
\co{x.grad}$.\footnote{For a simple linear graph that feels super weird,
pull-back or not. \co{c.grad} would be much more intuitive. For a multi-leaf
DAG, where leafs = input tensors, it makes a bit more sense.}

We can also perform VJPs by calling \co{backward()} of an intermediate
vector-valued variable by giving it a vector argument ($\ve
e$ or $\ve v$ above). In particular, we can build up the intermediate
Jacobians. Here, we extract the first row of $\pdi{\ve b}{\ve a}$.
%
\ipmpy{../talk/code/pytorch_rev_detail_2.py}
%
And finally, the default for "seeding" the backward pass starting at \co{c}
is indeed \co{1.0} as in $\pdi{f}{f}=1$.
%
\ipmpy{../talk/code/pytorch_rev_detail_1.py}

\subsection{Implementations of JVPs (forward) and VJPs (reverse)}

\subsubsection{\autograd}

They define a VJP for "each" numpy function in
\url{https://github.com/HIPS/autograd/blob/master/autograd/numpy/numpy_vjps.py}
using \co{defvjp}, also some JVPs in
\url{https://github.com/HIPS/autograd/blob/master/autograd/numpy/numpy_jvps.py}
but \autograd is mostly only reverse mode. \numpy API definitions in
\url{https://github.com/HIPS/autograd/blob/master/autograd/numpy/numpy_wrapper.py}

\subsubsection{\jax}

\numpy primitives are defined in
\url{https://github.com/google/jax/blob/master/jax/_src/lax/lax.py} with a lot
of \co{defjvp}, one for each primitive, i.e. only forward mode.

\ipmpy{../talk/code/jax_lax_sin.py}

They don't define explicit VJPs (for reverse mode), instead they use the
forward trace, which has to be done anyway, and then run that backwards,
transposing the JVP operations (note that $\tp{\ve e_i}\,\ma J =
\tp{\left(\tp{\ma J}\,\ve e_i\right)}$). From the docs: "\emph{... when
computing reverse differentiation JAX obtains a trace of primitives that
compute the tangent using forward differentiation. Then, JAX interprets this
trace abstractly backwards and for each primitive it applies a transposition
rule.}".

The \numpy API def is in
\url{https://github.com/google/jax/blob/master/jax/_src/numpy}.

\subsubsection{\pytorch}

\pytorch's AD system is designed with focus on the use case $f: \mathbb
R^n\ra\mathbb R$, i.e. the loss function during NN training, where $n$ is
large, which is why is uses VJPs (as in \autograd). VJP definitions are not
done at the Python level as in \jax, using a \co{defvjp} machinery, but instead
in a \co{yaml} file
\url{https://github.com/pytorch/pytorch/blob/master/tools/autograd/derivatives.yaml}
with Python-ish pseudo code, which defines the VJP for each \co{torch}
primitive function. Then scripts are used to generate C++ code for each
function's VJP and Python bindings (e.g. in \co{libtorch.so}).

\subsection{Tracing and compilation}

\subsubsection{\jax}

\jax uses an intermediate representation dubbed \co{jaxpr} which is the result
of tracing a function. Also every other function, e.g. \co{grad(f)} is
represented in \co{jaxpr}.

\begin{minted}{python}
    >>> import jax; from jax import numpy as jnp
    >>> f=lambda x: jnp.sum(jnp.power(jnp.sin(x),2.0))
    >>> jax.make_jaxpr(f)(1.0)
    { lambda  ; a.
      let b = sin a
          c = pow b 2.0
          d = reduce_sum[ axes=() ] c
      in (d,) }

    >>> jax.make_jaxpr(jax.grad(f))(1.0)
    { lambda  ; a.
      let b = sin a
          c = pow b 1.0
          d = mul 2.0 c
          e = mul 1.0 d
          f = cos a
          g = mul e f
      in (g,) }
\end{minted}

It uses \tf's XLA compiler, which uses LLVM, to compile for CPU and GPU targets.

\subsubsection{\pytorch}

\pytorch's \co{jit} creates TorchScript, which is a serialized version of
the graph. That can be exported to disk, loaded into C++ using the libtorch C++
API and executed as a C++ program.

\pytorch can also run on XLA devices like TPUs using
\url{https://github.com/pytorch/xla}.

\section{No Free Lunch: Limitations of AD}
\begin{itemize}
    \item \tf \co{1.x}: Manually construct computation graph by framework
        mini-language (e.g. \co{tf.while}, \co{tf.cond}). \pytorch, \jax,
        \tf\co{2.x}: eager execution / build graph dynamically
    \item In-place ops such as \co{A *= 3} instead of
        \co{B = A*3} are hard to support and can slow things down because large
        parts of the comp graph must be rewritten instead of just adding a new
        variable. In \autograd, \jax and \pytorch, usage of in-place mods is
        discouraged and will often just raise an exception. \pytorch has an
        elaborate tensor versioning system that will cause backward grad
        calculations to fail when in-pace ops would break it
        (\url{https://pytorch.org/docs/stable/notes/autograd.html#in-place-operations-with-autograd}).
        \jax and \pytorch have a \verb|jit|, which could optimize out-of-place
        modifications and copies away if possible, not sure if they do.
    \item Watch out when ADing through fast but approximate
        implementations: "Approximate the derivative, not differentiate the
        approximation." (see \verb|examples/text_jax.py|)
    \item For end-to-end AD, all parts of a pipeline must be implemented using
        the same AD-aware library. Else one needs to cut the chain rule open
        and hand over derivatives at the interface between codes.
\end{itemize}

\newpage
\nocite{*}
\printbibliography

\end{document}


\section{Introduction}

Phenology, the timing of seasonal biological phenomena, is a key aspect of plant and animal life.
It defines the timing and duration of growth and reproduction and thereby determines the ability to capture seasonally variable resources \citep{chuine2017process}.
Phenological analyses often focus on the timing of particular events, such as the dates of peak caterpillar abundance \citep{shutt2019spatial}.
However, for many biological phenomena exact dates of particular events are more difficult to observe than the state of the system itself.
For example, repeated but sparse survey visits may record whether a plant is in bud, flowering, or setting fruit, but not the exact dates when each of those stages was reached.
Such observations can be used to categorize an organism's state into discrete classes which usually follow natural ordering, e.g.\ from least to most developed.
The resulting data can be described using ordinal regression models \cite{mccullagh1980regression,agresti2010analysis} which then allow inferences about phenological progression.

I here replicate a number of ordinal regression models that were employed by \citet{dennis1986stochastic} and \citet{candy1991modeling} to describe insect phenology.

\section{Data}
\label{sec:data}
The models replicated in this study are fitted to a data set on the phenology of the western spruce budworm \emph{Choristoneura freemani} (Lepidoptera: Tortricidae), a defoliating moth that is widespread in western North America \citep{brookes1987western}.
This data set was originally published in \citep{dennis1986stochastic} and is a subset of a larger budworm survey data set analysed in \citep{kemp1986stochastic}.
The data consist of 12 sampling occasions at which counts of individual budworms in each of seven development stages (five larval instars, pupae, and adults) were recorded.
The only available covariate is a measure of seasonal progression, the accumulated degree days calculated using a threshold of 5.5°C.
\citet{candy1991modeling} noted an inconsistency in these data, namely that the reported total number of individuals did not correspond to the sum across the seven development stages for two of the sampling occasions.
I therefore use the data set as it was republished in \citep{candy1990biology}, where numbers in each stage have been assumed correct and the totals for each sampling occasion were adjusted accordingly.

\begin{table}[tbp]
  \small
    \centering
    \caption{The data used in this replication are counts of western spruce budworm \emph{Choristoneura freemani} across seven developmental stages on 12 sampling occasions, as published in \citep{candy1990biology}.}
  \input{../outputs/budworm_table}
  \label{tab:tab0}
\end{table}

\section{Methods}
The statistical models replicated here are different types of ordinal regression models~\citep{agresti2010analysis}, all with the aim of predicting the proportion of an insect population in a particular development stage at any given time.
In particular, they represent three different parameterisations of the so-called cumulative model and one version of the so-called sequential model.
A summary of the theory underlying these models and their derivation is provided in \citep{burkner2019ordinal}.

Both model types assume that the development of an insect follows an unobservable stochastic process $S(t)$ made up of accumulated increments of development over time~$t$.
As $S(t)$ increases, the insect passes through successive stages $j=1,\dots,r$, delimited by $r-1$ moults, with the $j$th moult occurring when the development threshold $a_j$ is reached:

\begin{alignat*}{3}
  \mathrm{stage}\,1&:\qquad {}&   S(t) & \leq a_1 \\
  \mathrm{stage}\,2&:\qquad  a_1&< S(t) & \leq a_2 \\
  \vdots & &\vdots \\
  \mathrm{stage}\,r-1&:\qquad  a_{r-2}&< S(t) & \leq a_{r-1} \\
  \mathrm{stage}\,r&:\qquad  a_{r-1}&< S(t)
\end{alignat*}

The $a_j$ values are typically unknown and their estimation from observed data was the goal of the orginal studies~\citep{dennis1986stochastic,candy1991modeling}.

\subsection{Cumulative model with constant variance }
\label{sec:const_var_cm}
The ordinal regression model of~\citep{candy1991modeling} is specified in terms of the cumulative number of individuals  $m_{ij}=\sum_{k=1}^jn_{ik}$ observed in stages 1 to $j$ on a sampling occasion $i$.
\begin{alignat}{1}
\mathbf{E}(m_{ij})&=N_iPr(S(t) < \alpha_j), \qquad j = 1,\dots ,r\\
&=N_iG(\alpha_j + \beta z_i)
\end{alignat}
where $G$ is the cumulative probability density function of $S(t)$, $\alpha_j$ are ordered thresholds or cut-point parameters, $\beta$ is a vector of regression parameters and $z_i$ is a vector of predictor variables.
If the probability of an individual being in stage $j$ or earlier at time $t_i$ is

$$\mu_{ij} = \mathbf{E}(m_{ij})/N_i$$

 one can interpret $G^{-1}$ as the link function of a generalised linear model (GLM) with the linear predictor

$$\eta_{ij}=\alpha+\beta z_i$$

This ordinal regression model is commonly known as the cumulative model~\citep{burkner2019ordinal}, and is applied to the budworm data in \citep{candy1991modeling} using the logit and complementary log-log (cloglog) link functions.
In both cases the parameterisation results in a constant variance for $S(t)$.
For the purpose of parameter estimation \citet{candy1991modeling} re-expressed the model in terms of stage-specific counts $n_{ij}$
\begin{equation}
\mathbf{E}(n_{ij})=N_i\{G(\alpha_j + \beta z_i) - G(\alpha_{j-1} + \beta z_i)\}
\label{eq:candy_cm_count_form}
\end{equation}
and fits it using a Poisson likelihood \citep{thompson1981composite}.
No code or initial values for the likelihood optimisation are provided for this estimation procedure in the original paper.
I therefore created an R version of the estimation procedure which directly optimizes a Poisson log-likelihood for Equation~\ref{eq:candy_cm_count_form} using the BFGS method in the \verb+optim+ function and a parameter scaling value of 0.01 for $\beta$ relative to the cut-point parameters..
Initial values for the optimisation were determined using a random search across plausible start values (see Appendix~\ref{sec:appendix}).
 The cumulative model is implemented in various R packages, including in the \verb+vglm+ function in \verb+VGAM+ \citep{VGAM} and the \verb+clm+ function in \verb+ordinal+ \cite{ordinal} and for comparison I also attempted to fit the models using these functions with their default settings.

\subsection{Cumulative model with proportional variance}
\citet{dennis1986stochastic} used a different parameterisation of the ordinal model with a logit link, i.e. assuming a logistic distribution for $S(t)$, such that the probability that an insect's development at time $t$ has not exceeded $s$ amounts to
\begin{equation}
Pr(S(t) \leq s) = \left\{ 1 + \exp\left[-\left(\frac{s-t}{\sqrt{b^2t}}\right)\right]\right\}^{-1}
\label{eqn:cumpropcdf}
\end{equation}
where $b^2$ is a positive constant.
The cumulative distribution function in Eqn.~\ref{eqn:cumpropcdf} corresponds to a logistic distribution with a mean of $t$ and a variance which increases proportional to the mean as $(\pi^2/3)b^2t$.
At any fixed time $t$ the thresholds $a_j$ segment the probability distribution function into $r$ parts and the area under the curve between $a_{j-1}$ and $a_j$ gives the probability that the insect will be in stage $j$ at time $t$.

This modelling approach is applied to data consisting of samples~$i$ that record the number of insects $x_{ij}$ in stage $j$ at times $t_1, t_2, \dots, t_q$ and the $x_{ij}$ are assumed to be random samples from a multinomial distribution with corresponding multinomial probabilities~$p_{ij}$

\begin{align}
p_{ij} & = Pr(a_{j-1} < S(t_i) \leq a_{j})\\
& =  \left\{ 1 + \exp\left[-\left(\frac{a_j-t_i}{\sqrt{b^2t_i}}\right)\right]\right\}^{-1} - \left\{ 1 + \exp\left[-\left(\frac{a_{j-1}-t_i}{\sqrt{b^2t_i}}\right)\right]\right\}^{-1}\label{eq:dennis_cm}
\end{align}

To fulfill the constraint that $\sum_{j=1}^r p_{ij}= 1$, it is further assumed that $a_0 = -\infty$ and $a_r = +\infty$.
The model has $r$ unknown parameters $a_1, \dots, a_{r-1}$ and $b^2$ which can be found by maximising the corresponding log-likelihood function
\begin{equation}
\mathcal{\ell} = \log C + \sum_{j=1}^r \sum_{i=1}^q x_{ij} \log p_{ij}
\label{eq:dennis_loglik}
\end{equation}
where $C$ is a combinatorial constant that is independent of the parameter values.

\citet{dennis1986stochastic} provided SAS code and initial values to estimate the parameters under this likelihood using an iteratively reweighted non-linear least squares approach based on \verb+PROC NLIN+.
This was updated to run in a contemporary version of SAS (SAS 9.4) and is provided in the article code repository.
However, since SAS is a proprietary software package, I implemented two R versions of the estimation procedure which both directly optimize the log-likelihood (\ref{eq:dennis_loglik}) using the L-BFGS-B optimisation routine \citep{byrd1995limited} in the R \verb+optim+ function. The first implementation is a direct translation of the SAS code which uses a literal implementation of the logistic cumulative distribution function and employs a lower parameter bound of 0 and initial values provided in \citep{dennis1986stochastic} for the estimation. The second implementation makes use of the R function \verb+stats::plogis+ to implement the logistic CDF and employs a lower parameter bound of the machine precision (i.e.\ \verb+.Machine$double.xmin+) and the same initial values as above. Both routines used a parameter scaling value of 0.01 for $b^2$ relative to the cut-point parameters

\citet{candy1991modeling} re-expressed the proportional variance model (Eqn.~\ref{eq:dennis_cm}) to match the form of Eqn.~\ref{eq:candy_cm_count_form}, which results in the following re\-para\-meter\-isation $\alpha_j = a_j/b$, $\beta = -1/b$, and $z_i = \sqrt{t_i}$, and uses the Poisson likelihood approach described in section~\ref{sec:const_var_cm} for parameter estimation.
A set of example macros for the software package \verb+GLIM+ \citep{aitkin1989statistical} is provided in an earlier manuscript by the same author \citep{candy1990biology}. GLIM is no longer actively developed or distributed, but initial values from the GLIM code were used in the estimation with the BFGS method of R \verb+optim+ and a parameter scaling value of 0.01 for $\beta$ relative to the cut-point parameters.

\subsection{Sequential model}
A different class of ordinal regression model can be derived by treating the observations as the result of a strictly ordered counting process, i.e.\ to achieve a stage $j$, all lower stages $1,\dots,j-1$ have to be achieved first.
The general form of this model is known as the sequential model, and rather than assuming a single latent process $S(t)$ as in the cumulative model there is a latent continuous variable $S_j$ for each category $j$~\citep{burkner2019ordinal}.
Analogous to the cumulative model it can be framed as a GLM

\begin{equation}
S_j = \eta + \epsilon_j
\end{equation}

with a linear predictor $\eta$ and an error term $\epsilon_j$ which has mean zero and is distributed following some distribution $G$.
This leads to a model of the form

\begin{equation}
Pr(S = a_j|S \geq a_j, \eta) = G(a_j - \eta)
\end{equation}

When $G$ is the logistic distribution this model is also known as the continuation ratio model~\citep{fienberg1980analysis,burkner2019ordinal}.
Confusingly, there are two common versions of the model in the literature both using this name.
The one outlined above describing the probability of the sequential process \emph{stopping} at stage $j$, and the other describing the probability of the process \emph{continuing} beyond stage $j$, i.e.

$Pr(S > a_j | S \geq a_j, \eta)$ \citep{burkner2019ordinal,VGAM}.

The paper replicated here \citep{candy1991modeling} used the stopping parameterisation.
In their notation the expected value for the stage-specific counts $n_{ij}$ is
\begin{alignat}{3}
\mathbf{E}(n_{ij})&=N_i G(\beta_{01} + \beta_{11}t_i), &j&=1 \label{eq:candy_sm_counts}\\
&=N^*_{ij} G(\beta_{0j} + \beta_{1j}t_i), \qquad &j&=2,\dots,r-1 \nonumber
\end{alignat}
with
\begin{equation}
N^*_{ij}=\left(N_i - \sum_{k=1}^{j-1}n_{ik}\right) \label{eq:n_star}
\end{equation}
and conditional probabilities
\begin{equation}
p^*_{ij} =  G(\beta_{0j} + \beta_{1j}t_i), \qquad j=1,\dots,r-1
\end{equation}

\citet{candy1991modeling} uses GLM estimation routines in \verb+GLIM+ to fit the $r-1$ models defined in Eqn.~\ref{eq:candy_sm_counts} assuming the $n_{ij}$ are binomially distributed conditional on $N_i$ for stage 1 and conditional on $N^*_{ij}$ for stages $2,\dots,r-1$.
No code is provided for this estimation procedure in the original paper, but the model is straightforward to implement using the \verb+glm+ function in R with a model formula of the form
$$\verb!cbind(count,total - N_star) ~ stage + stage:time - 1!$$
where the variable \verb+count+ represents the $n_{ij}$, \verb+N_star+ represents $N_i$ for $j=1$ and $N^*_{ij}$ for all other observations, \verb+stage+ is a factor variable encoding $j$ and \verb+time+ are the $t_i$. The sequential model with stopping parameterisation is also implemented in \verb+VGAM::vglm+ \citep{VGAM} and for comparison I attempted to fit the model using this function with its default settings.

\section{Results}

\begin{table}[tbp]
  \small
    \centering
    \caption{Parameter estimates for the cumulative model with constant variance (Eqn.~\ref{eq:candy_cm_count_form}).
    This table replicates results presented in the first two rows of Table~2 of \citep{candy1991modeling}.
    Note that \texttt{ordinal::clm} uses a parameterisation $\alpha_j - \beta z_i$ for the linear predictor yielding a parameter estimate for $\beta$ with the opposite sign than the other methods.
    The cloglog link model failed to fit using \texttt{VGAM::vglm}.}
  \input{../outputs/cm_const_var_table}
  \label{tab:tab1}
\end{table}

\begin{table}[tbp]
  \small
    \centering
    \caption{Parameter estimates for the cumulative logit model with proportional variance.
    This table replicates results presented in the first row of Table~1 of  \citep{kemp1986stochastic} and the last row of Table~2 of \citep{candy1991modeling}.}
  \input{../outputs/dennis_model_table}
  \label{tab:tab2}
\end{table}

\subsection{Cumulative model with constant variance}
Parameters were estimated using a direct optimisation of the Poisson likelihood for Eqn.~\ref{eq:candy_cm_count_form}, as well as with the R functions \verb+VGAM::vglm+ and \verb+ordinal::clm+.
The cloglog link model failed due to numerical errors when using the \verb+vglm+ function.
Parameter estimates were close to those of the original study for all three methods employed (Table~\ref{tab:tab1}). Parameter estimates were generally insensitive to the choice of starting values once the optimisation function was provided with appropriate parameter scaling values for the optimisation routine (see Appendix).

\subsection{Cumulative model with proportional variance}
The original SAS code provided in \citep{dennis1986stochastic} required minimal updates to run in a contemporary version of SAS (SAS 9.4).
Translating the model code to R was straightforward once I took the decision to implement a direct minimisation of the negative log likelihood with \verb+optim+.

Parameter estimates from SAS \verb+NLIN+ and both R \verb+optim+ implementations (Table~\ref{tab:tab2}) were virtually identical, but differed slightly from the parameter estimates presented in \citep{kemp1986stochastic}, which was assumed to be the original source for the parameter estimates, as no parameter estimates were presented in \citep{dennis1986stochastic}.
The observed differences in estimates were $<1$\% for the cut-point parameters $\alpha_i$, but c. 9\% for $\beta$.

Based on these three sets of parameter estimates it was also possible to redraw two figures from \citep{dennis1986stochastic}.
Figure~\ref{fig:fig1} and~\ref{fig:fig2}, respectively, show that despite the observed parameter differences  there is an overall good agreement between the original results and the replication.

\begin{figure}[p]
  \centering
  \includegraphics[width=\textwidth]{../figures/fig1_dennis_fig2.pdf}
  \caption{Logistic PDF of the cumulative model with proportional variance (Equation~\ref{eq:dennis_cm}) plotted for fixed values of~$t$.
  Area under the PDF between $a_{j-1}$ and $a_j$ gives the expected proportion of insects in stage $j$ at time $t$.
  The graph is based on the estimates in Table 1 of \citep{kemp1986stochastic} (black lines) and the estimates from the replication using the R \texttt{optim} implementation (red lines).
  This figure replicates Figure 2 in \citep{dennis1986stochastic}.}
  \label{fig:fig1}
\end{figure}

\begin{figure}[p]
  \centering
  \includegraphics[width=\textwidth]{../figures/fig2_dennis_fig3.pdf}
  \caption{Proportion of insects expected in stages 1-7 under the cumulative logit model with proportional variance (Equation~\ref{eq:dennis_cm}) plotted as functions of time $t$.
   Values of $a_j$ and $b^2$ used in the graph are the estimates given in Table 1 of \citep{kemp1986stochastic} (black lines) and the estimates from the replication using the R \texttt{optim} implementation (red lines).
   This figure replicates Figure 3 in \citep{dennis1986stochastic}.}
  \label{fig:fig2}
\end{figure}

\begin{table}[htb]
  \small
    \centering
    \caption{Parameter estimates for the sequential model with stopping ratios (Equation~\ref{eq:candy_sm_counts}).
    This table replicates results presented in Table~3 of \citep{candy1991modeling}.
    The cloglog link model failed to fit using \texttt{VGAM::vglm}.}
  \input{../outputs/sm_table}
  \label{tab:tab3}
\end{table}

\subsection{Sequential model}
\label{sec:sm-results}
Parameters were estimated using the R \verb+glm+ function and \verb+VGAM::vglm+.
The GLM formulation of the model fitted with R \verb+glm+ produced a warning that fitted probabilities numerically 0 or 1 occurred.
Likely due to related reasons, the cloglog link model failed due to numerical errors when using the \verb+vglm+ function.
Parameter estimates, where obtained, were identical to the original study (Table~\ref{tab:tab3}) within the precision reported in \citep{candy1991modeling}.

\section{Discussion}
Overall the results from both \citep{dennis1986stochastic} and \citep{candy1991modeling} could be replicated closely.
The SAS code provided in \citep{dennis1986stochastic} required only minimal updates to run in a contemporary version of SAS (SAS 9.4) and produced virtually identical estimates to the R re-implementation.
These estimates, however, differed slightly from the parameter estimates reported in \citep{kemp1986stochastic}.
Given that the same initial values were used in all implementations, I believe that this disagreement is most likely caused by the inconsistencies in the published data set described in Section~\ref{sec:data}.
The corrections applied to the data by \citep{candy1991modeling} result in a data set that is internally consistent but likely different to that on which the estimates in \citep{kemp1986stochastic} are based.

No code was provided in \citep{candy1991modeling}.
However, the mathematical and verbal descriptions of the models were detailed enough to re-implement the estimation procedures in R.
GLIM code of the cumulative model with proportional variance was available from an earlier manuscript~\citep{candy1990biology}.
This allowed me to use the same initial values as the original study for this model.
Initial values for the model with constant variance had to be guessed.
The direct optimisation of the likelihood was reported to be sensitive to the choice of initial values in ~\citep{dennis1986stochastic}.
Additional simulations (Appendix~\ref{sec:appendix}) showed that convergence failures did occur for some initial values, particularly in the case for the cloglog-link model.
However, the coefficient of variation for estimates derived from a wide range of initial values was very small (<0.01\%) for both the logit and cloglog models, whenenver the model converged succesfully (Table~\ref{tab:tabS2}).

Literal implementations of both the inverse logit and inverse complementary log-log function can suffer from numerical underflow and/or overflow for probabilities close to zero and one, and this may be the key reason for convergence failures observed in the direct optimisation, as well as in the \verb+vglm+ function.
The case study presented here is based on observations where the population variation in development speed (i.e.\ the transition from class to class) is low compared to the overall speed of seasonal progression.
As a result the early and late development stages of the observed species never occur together, and the observed data are sparse in the sense that many cell counts in Table~\ref{tab:tab0} are zero.
As a consequence the model estimates large effects, which although estimable on the link scale, are indistinguishable from one on the probability scale given the limitations of floating point representations.
This is the underlying reason for the warnings produced by the \verb+glm+ function when fitting the sequential model.
The GLIM code for the cumulative model from \citep{candy1990biology} uses multiple thresholding steps during the calculation of the linear predictor to mitigate against this, whereas the R implementation of the corresponding model makes use of a single thresholding step in the inverse link function (\verb+gtools::inv.logit+~\citep{gtools} or \verb+stats::plogis+ and \verb+VGAM::clogloglink+, respectively).
Differences in parameter estimates between a literal implementation of the logit link and  \verb+stats::plogis+ for the cumulative model with proportional variance (Table~\ref{tab:tab3}) were less than 0.01\%, however, in the case of the constant variance model the complementary log-log link model proved to be numerically less stable than the corresponding logit-link model (Figure~\ref{fig:figS1}).
This is perhaps unsurprising as the cloglog function has a steeper slope as it approaches one compared to the logit function, so values numerically close to one are attained earlier.
Given the sparsity of the data set and the resulting large estimated effect sizes this likely contributed to the failure to fit either of the cloglog-link models using the \verb+VGAM::vglm+ function.
The behaviour was reported to the maintainer of the \verb+VGAM+package, and initial troubleshooting of the\verb+VGAM+ code resolved some instabilities for the fitting of the cumulative model.
These updates are now available in the pre-release version of \verb+VGAM+\footnote{https://www.stat.auckland.ac.nz/~yee/VGAM/prerelease/index.html}.
However, other instabilities remain.
The cumulative model using the updated \verb+VGAM+ code converges far from the optimum identified by the other methods and a fix for the error affecting the sequential model are yet to be implemented.

\section*{Acknowledgements}
I am grateful to Juniper Simonis and Andrew MacDonald for constructive reviews of an earlier version of this manuscript, and to Thomas Yee for investigating numerical errors in the \verb+VGAM+ package.

\afterpage{\clearpage}


\input{header.tex}

\graphicspath{
{images/png/}{images/}{images/plots/}
}

\begin{document}
%------------------------------------------------------------------------------------------------
\section{Multidomain}

The multidomain equations generalize the bidomain equation and have multiple compartments at each spatial point.
Each compartment $k$ describes one of the $M_\text{mu}$ motor units.
The electric potential in the extra-cellular space is designated by $\phi_e$ and the intra-cellular potential of motor unit $k$ is desribed by $\phi_i$. The transmembrane voltages are given by $V_m^k = \phi_i^k - \phi_e$.

The first multidomain equation balances current flow between intra and extra-cellular space:
\begin{equation}\label{eq:multidomain1}
  \begin{array}{lll}
    \div\big(\bfsigma_e\,\grad(\phi_e)\big) + \s{k=1}{M_\text{mu}} f_r^k\,\div\big(\bfsigma_i^k\,\grad(\ub{V_m^k + \phi_e}{=\phi_i^k})\big) = 0.
  \end{array}
\end{equation}
It can be reformulated as:
\begin{equation}\label{eq:multidomain1-1}
  \begin{array}{lll}
    \div\big((\bfsigma_e + \ub{\ds\sum\limits_{k}^{M_\text{mu}} f_r^k\bfsigma_i^k}{=:\bfsigma_i}) \,\grad(\phi_e)\big) + \s{k=1}{M_\text{mu}} f_r^k\,\div\big(\bfsigma_i^k\,\grad(V_m^k )\big) = 0.
  \end{array}
\end{equation}
%
The second multidomain equations describe flow over the membrane and hold for each compartment:
\begin{equation}
  \begin{array}{lll}\label{eq:multidomain2}
    \div\big(\bfsigma_i^k\,\grad(\ub{V_m^k + \phi_e}{=\phi_i^k})\big) = A_m^k\,\big(C_m^k\,\p{V_m^k}{t} + I_\text{ion}(V_m^k)\big) \qquad \forall\,k \in 1\dots M_\text{mu}
  \end{array}
\end{equation}
The unknowns are the transmembrane voltages of compartment $k$, $V_m^k$ and the extracellular potential, $\phi_e$. $f_r^k \in [0,1]$ is a spatially varying factor of the presence of the compartment with $\sum_k f_i^k = 1$.
$\bfsigma_i^k$ and $\bfsigma_e$ are the conductivity tensors of the intra- and extracellular spaces.

Solving \eqref{eq:multidomain2} for $∂V_m^k/∂t$ yields:
\begin{equation*}
  \begin{array}{lll}
    \p{V_m^k}{t} = \dfrac{1}{A^k_m\,C_m^k}\div\big(\bfsigma_i^k\,\grad(V_m^k + \phi_e)\big) - \dfrac{1}{C_m^k}\,I_\text{ion}(V_m^k)\\[4mm]
  \end{array}
\end{equation*}
We solve using an operator splitting approach, e.g. Godunov splitting.
The reaction term is solved with an explicit Euler scheme.
\begin{equation*}
  \begin{array}{lll}
    V_m^{k,(*)} = V_m^{k,(i)} - dt\,\dfrac{1}{C_m^k}\,I_\text{ion}(V_m^{k,(i)}).
  \end{array}
\end{equation*}
The subcellular model provided by the CellML description computes $(-1/C_m^k\,I_\text{ion})$.

The diffusion term is solved using an implicit scheme, e.g. backward Euler.
\begin{equation}\label{eq:diffusion_term}
  \begin{array}{lll}
    V_m^{k,(i+1)} = V_m^{k,(*)} + dt\,\dfrac{1}{A^k_m\,C_m^k}\div\big(\bfsigma_i^k\,\grad(V_m^{k,(i+1)} + \phi_e)\big)\\[4mm]
  \end{array}
\end{equation}
\begin{equation*}
  \begin{array}{lll}    \Leftrightarrow\quad
    V_m^{k,(i+1)} -\dfrac{dt}{A^k_m\,C_m^k}\div\big(\bfsigma_i^k\,\grad(V_m^{k,(i+1)})\big) - \dfrac{dt}{A^k_m\,C_m^k}\div\big(\bfsigma_i^k\,\grad(\phi_e)\big) = V_m^{k,(*)}
  \end{array}
\end{equation*}

After discretizing the spatial terms with the Finite Element Method the following matrix equation is obtained:
\begin{equation*}
  \begin{array}{lll}
    \left[\begin{array}{@{}ccc|c@{}}
      \bfA_{V_m,V_m}^1 &  & & \bfB^1_{V_m,\phi_e} \\[2mm]
      & \ddots &   & \vdots \\[2mm]
      &  & \bfA_{V_m,V_m}^{M_\text{mu}} & \bfB^{M_\text{mu}}_{V_m,\phi_e} \\[2mm] \hline
      \bfB_{\phi_e,V_m}^1 & \dots & \bfB_{\phi_e,V_m}^{M_\text{mu}} & \bfB_{\phi_e,\phi_e} \\[2mm]
    \end{array}\right]
    \left[\begin{array}{@{}c@{}}
      V_{m}^{1,(i+1)} \\[2mm] \vdots \\[2mm] V_{m}^{M_\text{mu},(i+1)} \\[2mm]\hline \phi_{e,i}
    \end{array}\right]
    =
    \left[\begin{array}{@{}c@{}}
      \bfb_{V_m}^{1,(i+1)} \\[2mm] \vdots \\[2mm] \bfb_{V_m}^{M_\text{mu},(i+1)} \\[2mm]\hline \bfzero
    \end{array}\right]
  \end{array},
\end{equation*}
where
\begin{equation*}
  \begin{array}{lll}
    \bfA^k_{V_m,V_m} &\dots\quad\text{ discretization of }\quad -\dfrac{dt}{A^k_m\,C_m^k}\div\big(\bfsigma_i^k\,\grad(\cdot)\big) + (\cdot) \\[4mm]
    \bfB^k_{V_m,\phi_e} &\dots\quad\text{ discretization of }\quad -\dfrac{dt}{A^k_m\,C_m^k}\div\big(\bfsigma_i^k\,\grad(\cdot)\big)\\[4mm]
    \bfB^k_{\phi_e,V_m} &\dots\quad\text{ discretization of }\quad f_r^k\,\div\big(\bfsigma_i^k\,\grad(\cdot)\big)\\[4mm]
    \bfB_{\phi_e,\phi_e} &\dots\quad\text{ discretization of }\quad
  \div\big((\bfsigma_e + \bfsigma_i)\,\grad(\cdot)\big)
  \end{array}
\end{equation*}
%
\begin{equation*}
  \begin{array}{lll}
    \bfb_{V_m}^{k,(i+1)} = V_m^{k,(*)} = V_m^{k,(i)} - \dfrac{dt}{C_m^k}\,I_\text{ion}(V_{m}^{k,(i)}) \quad \text{($I_\text{ion}$ solved using splitting scheme)}
  \end{array}
\end{equation*}

The bidomain equation is the special case for $M_\text{mu}=1$. It can also be used for computation of EMG ($\phi_e$) from $V_m$ in the fiber based model.
\begin{equation*}
  \begin{array}{lll}
    \div\big((\bfsigma_i + \bfsigma_e)\,\grad \phi_e\big) = - \div(\bfsigma_i\,\grad V_m)
  \end{array}
\end{equation*}

\subsection{Finite Element formulation}
In this section the finite element formulation for the multidomain equation is derived. We start with an example problem.
\subsubsection{Diffusion problem}
In general, the weak form of a diffusion problem discretized with Crank-Nicolson,
\begin{equation}\label{eq:weak_form0}
  \begin{array}{lll}
    Δu = u_t, \qquad \p{u}{\bfn} = f \quad \text{on }\Gamma_f, \qquad \p{u}{\bfn} = 0 \quad \text{on } ∂Ω\backslash \Gamma_f \\[4mm]
    \Rightarrow\quad \ds\int_Ω \big(\theta\,Δu^{(i+1)} + (1-\theta)\,Δu^{(i)}\big)\,\phi \,\d\bfx = \dfrac{1}{dt} \ds\int_Ω(u^{(i+1)} - u^{(i)})\,\phi\,\d\bfx, \quad \forall \phi \in V_h\\[4mm]
  \end{array}
\end{equation}
Discretize in space with $u = \sum_j u_j\,\varphi_j, V_h = \span\{\varphi_j | j = 1\dots N\}$ and using Divergence theorem
\begin{equation}\label{eq:weak_form1}
  \begin{array}{lll}
    \ds\sum\limits_{j=1}^{N} \big(\theta\,u_j^{(i+1)} + (1-\theta)\,u_j^{(i)}\big)  \left(-\ds\int_Ω ∇\varphi_j\cdot ∇\varphi_k \,\d\bfx + \ds\int_{∂Ω} (∇\varphi_j\cdot \bfn)\varphi_k \,\d\bfx  \right) \\[4mm]
    \quad = \dfrac{1}{dt} \sum\limits_{j=1}^{N} \big(u_j^{(i+1)} - u_j^{(i)}\big) \ds\int_Ω \varphi_j\,\varphi_k\,\d\bfx, \quad \forall k = 1\dots N.\\[4mm]
  \end{array}
\end{equation}
This can be written in matrix notation as
\begin{equation}\label{eq:diffusion_weak_form_matrix}
  \begin{array}{lll}
    \bfA\,\bfu^{(i+1)} = \bfb(\bfu^{(i)}),
  \end{array}
\end{equation}
where
\begin{equation}\label{eq:diffusion_weak_form_matrix2}
  \begin{array}{lll}
    \bfA = \theta\,(\bfK + \bfB) -\dfrac{1}{dt}\bfM, \\[4mm]
    \bfb = \big((\theta-1)\,(\bfK + \bfB) - \dfrac{1}{dt} \bfM \big)\,\bfu^{(i)},
  \end{array}
\end{equation}
with
\begin{equation*}
  \begin{array}{lll}
     \bfK_{kj} = -\ds\int_Ω ∇\varphi_j\cdot ∇\varphi_k \,\d\bfx \qquad \text{(note, the minus sign is correct for $+Δ$)},\\[4mm]
     \bfB_{kj} = \ds\int_{\Gamma_f} (∇\varphi_j\cdot \bfn)\varphi_k \,\d\bfx,\\[4mm]
     \bfM_{kj} = \ds\int_Ω \varphi_j\,\varphi_k\,\d\bfx,
  \end{array}
\end{equation*}
or written in component form:
\begin{equation*}
  \begin{array}{lll}
    \bfA_{kj} = \theta\,\left(-\ds\int_Ω ∇\varphi_j\cdot ∇\varphi_k \,\d\bfx + \ds\int_{∂Ω} (∇\varphi_j\cdot \bfn)\varphi_k \,\d\bfx \right) - \dfrac{1}{dt}\,\ds\int_Ω \varphi_j\,\varphi_k\,\d\bfx,\\[4mm]
    \bfb_k = \ds\sum\limits_{j=1}^{N} -(1-\theta)\,u_j^{(i)}\,\left(-\ds\int_Ω ∇\varphi_j\cdot ∇\varphi_k \,\d\bfx + \ds\int_{∂Ω} (∇\varphi_j\cdot \bfn)\varphi_k \,\d\bfx \right)
     + \dfrac{1}{dt} \ds\sum\limits_{j=1}^{N} -u_j^{(i)} \ds\int_Ω \varphi_j\,\varphi_k\,\d\bfx.
  \end{array}
\end{equation*}
So far we did not plug in the boundary conditions. For $f=0$ we get $\bfB = \bfzero$. The case $f \neq 0$ is handled in the next subsection.

\subsubsection{Boundary conditions}
The boundary condition $∇u\cdot\bfn = f$ can be written as
\begin{equation*}
  \begin{array}{lll}
    ∇u\cdot\bfn = \s{j=1}{N}u_j\,(∇\varphi_j\cdot \bfn) = f,
  \end{array}
\end{equation*}
We discretize the flow over the boundary, $f$, by different ansatz functions, $\psi_j$, with coefficients $f_j$:
\begin{equation*}
  \begin{array}{lll}
    f = \s{j=1}{N}f_j\,\psi_j
  \end{array}
\end{equation*}
We get from \eqref{eq:weak_form1}
\begin{equation*}
  \begin{array}{lll}
    \ds\sum\limits_{j=1}^{N} \big(\theta\,u_j^{(i+1)} + (1-\theta)\,u_j^{(i)}\big)
     \left(-\ds\int_Ω ∇\varphi_j\cdot ∇\varphi_k \,\d\bfx \right)
      + \ds\int_{\Gamma_f} \big(\theta\,f^{(i+1)} + (1-\theta)\,f^{(i)}\big)\,\varphi_k \,\d\bfx \\[4mm]
    \quad = \dfrac{1}{dt} \sum\limits_{j=1}^{N} \big(u_j^{(i+1)} - u_j^{(i)}\big) \ds\int_Ω \varphi_j\,\varphi_k\,\d\bfx, \quad \forall k = 1\dots N,\\[4mm]
    \Leftrightarrow \quad
    \ds\sum\limits_{j=1}^{N} \big(\theta\,u_j^{(i+1)} + (1-\theta)\,u_j^{(i)}\big)
     \left(-\ds\int_Ω ∇\varphi_j\cdot ∇\varphi_k \,\d\bfx \right)
      + \ds\sum\limits_{j=1}^{N} \big(\theta\,f_j^{(i+1)} + (1-\theta)\,f_j^{(i)}\big)
      \ds\int_{\Gamma_f} \psi_j\,\varphi_k \,\d\bfx \\[4mm]
    \quad = \dfrac{1}{dt} \sum\limits_{j=1}^{N} \big(u_j^{(i+1)} - u_j^{(i)}\big) \ds\int_Ω \varphi_j\,\varphi_k\,\d\bfx, \quad \forall k = 1\dots N,\\[4mm]
  \end{array}
\end{equation*}
In matrix notation,
\begin{equation}\label{eq:diffusion_weak_form_matrix}
  \begin{array}{lll}
    \bfA\,\bfu^{(i+1)} = \bfb(\bfu^{(i)}),
  \end{array}
\end{equation}
we have
\begin{equation}\label{eq:diffusion_weak_form_matrix2}
  \begin{array}{lll}
    \bfA = \theta\,\bfK -\dfrac{1}{dt}\bfM, \\[4mm]
    \bfb = \big((\theta-1)\,\bfK - \dfrac{1}{dt} \bfM \big)\,\bfu^{(i)} - \bfB_{\Gamma_f}\,\big(\theta\,\bff^{(i+1)} + (1-\theta)\,\bff^{(i)}\big),
  \end{array}
\end{equation}
with
\begin{equation*}
  \begin{array}{lll}
     \bfK_{kj} = -\ds\int_Ω ∇\varphi_j\cdot ∇\varphi_k \,\d\bfx \qquad \text{(note, the minus sign is correct for $+Δ$)},\\[4mm]
     \bfM_{kj} = \ds\int_Ω \varphi_j\,\varphi_k\,\d\bfx,\\[4mm]
     \bfB_{\Gamma_f,kj} = \ds\int_{\Gamma_f} \psi_j\,\varphi_k \,\d\bfx,
  \end{array}
\end{equation*}

\subsubsection{Laplace problem}
We consider $Δu = 0, \partial u/\partial \bfn = f$.
This leads to
\begin{equation*}
  \begin{array}{lll}
    (\bfK + \bfB)\,\bfu = \bfzero \qquad \text{or} \qquad \bfK\,\bfu + \bfB_{\Gamma_f}\,\bff = 0.
  \end{array}
\end{equation*}

\subsubsection{First multidomain equation}
Back to the first multidomain equation \eqref{eq:multidomain1-1}:
\begin{equation*}
  \begin{array}{lll}
    \div\big((\bfsigma_e + \ub{\ds\sum\limits_{k}^{M_\text{mu}} f_r^k\bfsigma_i^k}{=:\bfsigma_i}) \,\grad(\phi_e)\big) + \s{k=1}{M_\text{mu}} f_r^k\,\div\big(\bfsigma_i^k\,\grad(V_m^k )\big) = 0,
  \end{array}
\end{equation*}
The weak form can be written as
\begin{equation*}
  \begin{array}{lll}
    \ds\sum\limits_{j=1}^{N} \phi_{e,j} \left(-\ds\int_Ω (\bfsigma_e + \bfsigma_i) ∇\varphi_j\cdot ∇\varphi_\ell \,\d\bfx + \ds\int_{∂Ω} ((\bfsigma_e + \bfsigma_i) ∇\varphi_j\cdot \bfn)\varphi_\ell \,\d\bfx  \right) \\[4mm]
    \quad +  \s{k=1}{M_\text{mu}} f_r^k\,\left(\ds\sum\limits_{j=1}^{N} V^k_{m,j} \left(-\ds\int_Ω \bfsigma_i^k ∇\varphi_j\cdot ∇\varphi_\ell \,\d\bfx + \ds\int_{∂Ω} (\bfsigma_i^k ∇\varphi_j\cdot \bfn)\varphi_\ell \,\d\bfx  \right)\right) = 0 \quad \forall \ell=1,\dots,N,
  \end{array}
\end{equation*}
which is in matrix notation,
\begin{equation}\label{eq:multidomain1_matrix1}
  \begin{array}{lll}
    \big(\bfK_{\bfsigma_e + \bfsigma_i} + \bfB_{\bfsigma_e + \bfsigma_i}\big)\bfphi_{e} +  \s{k=1}{M_\text{mu}} f_r^k \big(\bfK_{\bfsigma_i^k} + \bfB_{\bfsigma_i^k}\big)\bfV_m^k = 0
  \end{array}
\end{equation}

\subsubsection{Second multidomain equation}
The diffusion part of the second multidomain equation is given by
\begin{equation*}
  \begin{array}{lll}
    \dfrac{V_m^{k,(i+1)}-V_m^{k,(*)}}{dt} = \dfrac{1}{A^k_m\,C_m^k}\div\big(\bfsigma_i^k\,\grad(V_m^{k,(i+1)})\big) + \dfrac{1}{A^k_m\,C_m^k}\div\big(\bfsigma_i^k\,\grad(\phi_e)\big).
  \end{array}
\end{equation*}
The weak form is given by
\begin{equation*}
  \begin{array}{lll}
    \dfrac{1}{A^k_m\,C_m^k}\ds\sum\limits_{j=1}^{N} \big(\theta\,V_{m,j}^{(i+1)} + (1-\theta)\,V_{m,j}^{(i)}\big) \left(-\ds\int_Ω \bfsigma_i^{k}\, ∇\varphi_j\cdot ∇\varphi_\ell \,\d\bfx + \ds\int_{∂Ω} (\bfsigma_i^k\,∇\varphi_j\cdot \bfn)\varphi_\ell \,\d\bfx  \right) \\[4mm]
    + \dfrac{1}{A^k_m\,C_m^k} \ds\sum\limits_{j=1}^{N} \big(\theta\,\phi_{e,j}^{(i+1)} + (1-\theta)\,\phi_{e,j}^{(i)}\big) \left(-\ds\int_Ω \bfsigma_i^k\,∇\varphi_j\cdot ∇\varphi_\ell \,\d\bfx + \ds\int_{∂Ω} (\bfsigma_i^k\,∇\varphi_j\cdot \bfn)\varphi_\ell \,\d\bfx  \right) \\[4mm]
    \quad = \dfrac{1}{dt} \sum\limits_{j=1}^{N} \big(V_{m,j}^{(i+1)} - V_{m,j}^{(i)}\big) \ds\int_Ω \varphi_j\,\varphi_\ell\,\d\bfx, \quad \forall \ell = 1\dots N\\[4mm]
  \end{array}
\end{equation*}
Analogous to \eqref{eq:diffusion_weak_form_matrix} we get
\begin{equation}\label{eq:multidomain2_matrix1}
  \begin{array}{lll}
    \bfA\,\mat{\bfV_m^{(i+1)}\\ \bfphi_{e}^{(i+1)}} = \bfb,
  \end{array}
\end{equation}
where
\begin{equation}\label{eq:multidomain2_matrix2}
  \begin{array}{lll}
    \bfA = \mat{
      \dfrac{1}{A_m^k\,C_m^k}\theta\,(\bfK_{\bfsigma_i^k} + \bfB_{\bfsigma_i^k}) -\dfrac{1}{dt}\bfM & \quad
      \dfrac{1}{A_m^k\,C_m^k}\theta\,(\bfK_{\bfsigma_i^k} + \bfB_{\bfsigma_i^k})
    } \\[4mm]
    \bfb = \Big( \dfrac{1}{A_m^k\,C_m^k}(\theta-1)\,(\bfK_{\bfsigma_i^k} + \bfB_{\bfsigma_i^k}) - \dfrac{1}{dt}\bfM\Big) \bfV_m^{(i)}
      + \dfrac{1}{A_m^k\,C_m^k}(\theta - 1)\,(\bfK_{\bfsigma_i^k} + \bfB_{\bfsigma_i^k})\,\bfphi_e^{(i)}
  \end{array}
\end{equation}

Together, \eqref{eq:multidomain1_matrix1} and \eqref{eq:multidomain2_matrix1},\eqref{eq:multidomain2_matrix2} form the following system
\begin{equation}\label{eq:matrix_equation_1}
  \begin{array}{lll}
    \matt{
      \dfrac{1}{A_m^k\,C_m^k}\theta\,(\bfK_{\bfsigma_i^k} + \bfB_{\bfsigma_i^k}) -\dfrac{1}{dt}\bfM &
      \dfrac{1}{A_m^k\,C_m^k}\theta\,(\bfK_{\bfsigma_i^k} + \bfB_{\bfsigma_i^k}) \\[4mm]
      f_r^k \big(\bfK_{\bfsigma_i^k} + \bfB_{\bfsigma_i^k}\big) &
      \big(\bfK_{\bfsigma_e + \bfsigma_i} + \bfB_{\bfsigma_e + \bfsigma_i}\big)
    }
    \matt{
      \bfV_m^{(i+1)}\\[4mm]
       \bfphi_{e}^{(i+1)}
    }\\[4mm]
    =
    \matt{
      \big((\theta-1)\, \dfrac{1}{A_m^k\,C_m^k}(\bfK_{\bfsigma_i^k} + \bfB_{\bfsigma_i^k}) - \dfrac{1}{dt}\bfM\big) \bfV_m^{(i)}
      + (\theta - 1)\,(\bfK_{\bfsigma_i^k} + \bfB_{\bfsigma_i^k})\,\bfphi_e^{(i)}\\[4mm]
      \bfzero
    }
  \end{array}
\end{equation}
By multiplying the first row with $-dt\,\bfM^{-1}$ we get
\begin{equation}\label{eq:matrix_equation_2}
  \begin{array}{lll}
    \matt{
      \dfrac{-dt\,\theta}{A_m^k\,C_m^k}\bfM^{-1}(\bfK_{\bfsigma_i^k} + \bfB_{\bfsigma_i^k}) + \bfI &
      \dfrac{-dt\,\theta}{A_m^k\,C_m^k}\bfM^{-1}(\bfK_{\bfsigma_i^k} + \bfB_{\bfsigma_i^k}) \\[4mm]
      f_r^k \big(\bfK_{\bfsigma_i^k} + \bfB_{\bfsigma_i^k}\big) &
      \big(\bfK_{\bfsigma_e + \bfsigma_i} + \bfB_{\bfsigma_e + \bfsigma_i}\big)
    }
    \matt{
      \bfV_m^{(i+1)}\\[4mm]
       \bfphi_{e}^{(i+1)}
    }\\[12mm]
    =
    \matt{
      \left(\dfrac{(1-\theta)\,dt}{A_m^k\,C_m^k}\bfM^{-1}(\bfK_{\bfsigma_i^k} + \bfB_{\bfsigma_i^k}) + \bfI\right) \bfV_m^{(i)}
      + (1 - \theta)\,dt\,\bfM^{-1}\,(\bfK_{\bfsigma_i^k} + \bfB_{\bfsigma_i^k})\,\bfphi_e^{(i)} \\[4mm]
      \bfzero
    }
  \end{array}
\end{equation}

For a forward Euler scheme ($\theta = 1$) and homogeneous Dirichlet boundary conditions ($\bfB = \bfzero$) the equation simplifies to
\begin{equation*}
  \begin{array}{lll}
   \matt{
      \dfrac{1}{A_m^k\,C_m^k}\bfK_{\bfsigma_i^k} -\dfrac{1}{dt}\bfM\ & \quad
      \dfrac{1}{A_m^k\,C_m^k}\bfK_{\bfsigma_i^k} \\[4mm]
      f_r^k \bfK_{\bfsigma_i^k} &
      \bfK_{\bfsigma_e + \bfsigma_i}
    }
    \matt{
      \bfV_m^{(i+1)}\\[4mm]
       \bfphi_{e}^{(i+1)}
    }
    =
    \matt{
       -\dfrac{1}{dt}\bfM\,\bfV_m^{(i)} \\[4mm]
      \bfzero
    }
  \end{array}
\end{equation*}
or equivalently,
\begin{equation*}
  \begin{array}{lll}
   \matt{
      \dfrac{-dt}{A_m^k\,C_m^k}\bfM^{-1}\bfK_{\bfsigma_i^k} +\bfI & \quad
      \dfrac{-dt}{A_m^k\,C_m^k}\bfM^{-1}\bfK_{\bfsigma_i^k} \\[4mm]
      f_r^k \bfK_{\bfsigma_i^k} &
      \bfK_{\bfsigma_e + \bfsigma_i}
    }
    \matt{
      \bfV_m^{(i+1)}\\[4mm]
       \bfphi_{e}^{(i+1)}
    }
    =
    \matt{
       \bfV_m^{(i)} \\[4mm]
      \bfzero
    }
  \end{array}
\end{equation*}

\subsection{Boundary conditions}
The boundary conditions to the multidomain equations are given by
\begin{equation*}
  \begin{array}{lll}
    (\bfsigma_i^{k}\,∇\phi_i^{k})\cdot \bfn_m = 0  \qquad \text{on } \Gamma_M
  \end{array}
\end{equation*}
With $\phi_i = V_m + \phi_e$ this translates to
\begin{equation}\label{eq:flux_bc}
  \begin{array}{lll}
    (\bfsigma_i^{k}\,∇V_m^{k})\cdot \bfn_m = -(\bfsigma_i^{k}\,∇\phi_e)\cdot \bfn_m =: p^k  \qquad \text{on } \Gamma_M
  \end{array}
\end{equation}
For now, we assume $\partial\phi_e/\partial \bfn = 0$ on $\Gamma_M$.

%%

%\subsubsection{Diffusion example}
%How to handle the inhomogeneous Neumann-type boundary conditions will be derived in the following subsection.
%Consider the example problem \eqref{eq:weak_form0}:
%\begin{equation*}
  %\begin{array}{lll}
    %∇\cdot(\bfsigma\,∇ u) = u_t, \qquad (\bfsigma \,∇u)\cdot\bfn = f \quad \text{on }\Gamma_f, \qquad (\bfsigma\,∇u)\cdot\bfn = 0\quad \text{on }∂Ω\backslash \Gamma_f.
  %\end{array}
%\end{equation*}
%Analogous to \eqref{eq:weak_form1} we have
%\begin{equation*}
  %\begin{array}{lll}
    %\ds\sum\limits_{j=1}^{N} \big(\theta\,u_j^{(i+1)} + (1-\theta)\,u_j^{(i)}\big)  \left(-\ds\int_Ω \bfsigma\,∇\varphi_j\cdot ∇\varphi_k \,\d\bfx\right)
    %+ \ds\sum\limits_{j=1}^{N}\big(\theta\,u_j^{(i+1)} + (1-\theta)\,u_j^{(i)}\big)\left(\ds\int_{\Gamma_f} (\bfsigma\,∇\varphi_j\cdot \bfn)\varphi_k \,\d\bfx  \right) \\[4mm]
    %\quad = \dfrac{1}{dt} \sum\limits_{j=1}^{N} \big(u_j^{(i+1)} - u_j^{(i)}\big) \ds\int_Ω \varphi_j\,\varphi_k\,\d\bfx, \quad \forall k = 1\dots N\\[4mm]
  %\end{array}
%\end{equation*}
%The boundary condition $(\bfsigma \,∇u)\cdot\bfn = f$ can be written as
%\begin{equation*}
  %\begin{array}{lll}
    %(\bfsigma \,∇u)\cdot\bfn = \s{j=1}{N}u_j\,(\bfsigma\,∇\varphi_j\cdot \bfn) = f
  %\end{array}
%\end{equation*}
%and we get
%\begin{equation*}
  %\begin{array}{lll}
    %\ds\sum\limits_{j=1}^{N} \big(\theta\,u_j^{(i+1)} + (1-\theta)\,u_j^{(i)}\big)
     %\left(-\ds\int_Ω \bfsigma\,∇\varphi_j\cdot ∇\varphi_k \,\d\bfx + \ds\int_{\Gamma_f} f\,\varphi_k \,\d\bfx  \right)\\[4mm]
    %\quad = \dfrac{1}{dt} \sum\limits_{j=1}^{N} \big(u_j^{(i+1)} - u_j^{(i)}\big) \ds\int_Ω \varphi_j\,\varphi_k\,\d\bfx, \quad \forall k = 1\dots N,\\[4mm]
  %\end{array}
%\end{equation*}
%which is the same as
%\begin{equation*}
  %\begin{array}{lll}
    %\ds\sum\limits_{j=1}^{N} \big(\theta\,u_j^{(i+1)} + (1-\theta)\,u_j^{(i)}\big)  \left(-\ds\int_Ω \bfsigma\,∇\varphi_j\cdot ∇\varphi_k \,\d\bfx\right)
    %+ \ds\sum\limits_{j=1}^{N}\big(\theta\,f_j^{(i+1)} + (1-\theta)\,f_j^{(i)}\big) \left(\ds\int_{\Gamma_f}  \varphi_j\,\varphi_k  \,\d\bfx  \right) \\[4mm]
    %\quad = \dfrac{1}{dt} \sum\limits_{j=1}^{N} \big(u_j^{(i+1)} - u_j^{(i)}\big) \ds\int_Ω \varphi_j\,\varphi_k\,\d\bfx, \quad \forall k = 1\dots N.\\[4mm]
  %\end{array}
%\end{equation*}
%This translates to the matrix equation
%\begin{equation*}
  %\begin{array}{lll}
   %\matt{
      %\theta\,\bfK_{\bfsigma} -\dfrac{1}{dt}\bfM & \quad
      %(1-\theta)\,\bfM_\Gamma \quad &
      %\theta\,\bfM_\Gamma
    %}
    %\matt{
      %\bfu^{(i+1)}\\
      %\bff^{(i)}\\
      %\bff^{(i+1)}
    %}
    %=
    %\matt{
       %\big((\theta-1)\,\bfK_{\bfsigma} - \dfrac{1}{dt} \bfM \big)\,\bfu^{(i)}
    %},
  %\end{array}
%\end{equation*}
%where
%\begin{equation*}
  %\begin{array}{lll}
     %\bfK_{\bfsigma} = -\ds\int_Ω \bfsigma\,∇\varphi_j\cdot ∇\varphi_k \,\d\bfx, \quad \bfK = \bfK_\bfI \qquad \text{(note, the minus sign is correct for $+Δ$)},\\[4mm]
     %\bfM_\Gamma = \ds\int_{\Gamma_f} \varphi_j\,\varphi_k \,\d\bfx\\[4mm]
     %\bfM = \ds\int_Ω \varphi_j\,\varphi_k\,\d\bfx,
  %\end{array}
%\end{equation*}
%\subsubsection{Laplace example}
%Another example is
%\begin{equation*}
  %\begin{array}{lll}
    %Δu = 0, \qquad \p{u}{\bfn} = f \quad \text{on }\Gamma_f.
  %\end{array}
%\end{equation*}
%We get
%\begin{equation*}
  %\begin{array}{lll}
    %\ds\sum\limits_{j=1}^{N} u_j \left(-\ds\int_Ω ∇\varphi_j\cdot ∇\varphi_k \,\d\bfx\right)
    %+ \ds\sum\limits_{j=1}^{N} f_j\ds\int_{\Gamma_f} \varphi_j\,\varphi_k \,\d\bfx = 0 \quad \forall k = 1\dots N,\\[4mm]
  %\end{array}
%\end{equation*}
%which is in matrix form
%\begin{equation*}
  %\begin{array}{lll}
    %\matt{
     %\bfK &
      %\bfM_\Gamma
    %}
    %\matt{
      %\bfu\\
      %\bff\\
    %}
    %=
    %\bfzero,
  %\end{array}
%\end{equation*}

\subsubsection{Multidomain example}
Starting from \eqref{eq:matrix_equation_1} with $\bfB= \bfzero$ we have
\begin{equation}\label{eq:matrix_equation_3}
  \begin{array}{lll}
  \matt{
      \dfrac{1}{A_m^k\,C_m^k}\theta\,\bfK_{\bfsigma_i^k} -\dfrac{1}{dt}\bfM &
      \dfrac{1}{A_m^k\,C_m^k}\theta\,\bfK_{\bfsigma_i^k} \\[4mm]
      f_r^k \,\bfK_{\bfsigma_i^k}  &
      \bfK_{\bfsigma_e + \bfsigma_i}
    }
    \matt{
      \bfV_m^{(i+1)}\\[4mm]
       \bfphi_{e}^{(i+1)}
    }\\[8mm]
    =
    \matt{
      \big((\theta-1)\, \dfrac{1}{A_m^k\,C_m^k}\bfK_{\bfsigma_i^k} - \dfrac{1}{dt}\bfM\big) \bfV_m^{(i)}
      + (\theta - 1)\,\dfrac{1}{A_m^k\,C_m^k}\bfK_{\bfsigma_i^k}\,\bfphi_e^{(i)}\\[4mm]
      \bfzero
    }.
  \end{array}
\end{equation}
For boundary integrals and a Neumann boundary condition $(\bfsigma ∇u \cdot \bfn) = f$ on $∂\Omega=\Gamma$, we have:
\begin{equation*}
  \begin{array}{lll}
    \bfsigma ∇u\cdot\bfn = \s{j=1}{N}u_j\,(\bfsigma ∇\varphi_j\cdot \bfn) = \s{j=1}{N}f_j\,\psi_j\\[6mm]
    \Leftrightarrow\quad \s{j=1}{N}u_j\,\ds\int_{∂\Omega} (\bfsigma ∇\varphi_j \cdot \bfn)\,\varphi_\ell\,\d \bfx
    = \s{j=1}{N}f_j\,\ds\int_{∂\Omega} \psi_j\,\varphi_\ell\,\d \bfx\\[8mm]
    \Leftrightarrow\quad \bfB_{\bfsigma}\bfu = \bfB_{\Gamma}\bff
  \end{array}
\end{equation*}

Now, we know how to incorporate the boundary condition \eqref{eq:flux_bc} by replacing $\bfB_{\bfsigma}\bfu$ by $\bfB_{\Gamma}\bff$
and put the terms on the right hand side. We get \cref{eq:matrix_equation_3} with a different right hand side $\bfb$:
%
\begin{equation}
  \begin{array}{ll|lll}
    \bfb = \Big( \dfrac{1}{A_m^k\,C_m^k}(\theta-1)\,\bfK_{\bfsigma_i^k} - \dfrac{1}{dt}\bfM\Big) \bfV_m^{(i)}
      + \dfrac{1}{A_m^k\,C_m^k}(\theta - 1)\,\bfK_{\bfsigma_i^k}\,\bfphi_e^{(i)} \\[4mm]
      \quad \ub{+ \dfrac{1}{A_m^k\,C_m^k}(\theta-1)\,\bfB_{\Gamma_M} \bfp^{k,(i)} - \dfrac{1}{A_m^k\,C_m^k}(\theta-1)\,\bfB_{\Gamma_M} \bfp^{k,(i)}}{=\bfzero}\\[4mm]
      \quad \ub{- \dfrac{1}{A_m^k\,C_m^k}\theta\,\bfB_{\Gamma_M} \bfp^{k,(i+1)} + \dfrac{1}{A_m^k\,C_m^k}\theta\,\bfB_{\Gamma_M} \bfp^{k,(i+1)}}{=\bfzero}
  \end{array}
\end{equation}

Analogously for the first monodomain equation in matrix notation, \cref{eq:multidomain1_matrix1},
 with $\bfB_{\bfsigma}\bfu = \bfB_{\Gamma}\bff$ and $q := (\bfsigma_e ∇ \phi_e)\cdot \bfn_m$:
\begin{equation}\label{eq:multidomain1_matrix2}
  \begin{array}{lll}
    &\big(\bfK_{\bfsigma_e + \bfsigma_i} + \bfB_{\bfsigma_e + \bfsigma_i}\big)\bfphi_{e} +  \s{k=1}{M_\text{mu}} f_r^k \big(\bfK_{\bfsigma_i^k} + \bfB_{\bfsigma_i^k}\big)\bfV_m^k = 0\\[4mm]
    \Leftrightarrow \quad &\bfK_{\bfsigma_e + \bfsigma_i}\bfphi_{e} + \bfB_{\bfsigma_e}\bfphi_{e} + \ub{\bfB_{\bfsigma_i}\bfphi_{e} }{=\s{k=1}{M_\text{mu}} f_r^k\, \bfB_{\bfsigma_i^k}\,\bfphi_e}
    +  \s{k=1}{M_\text{mu}} f_r^k \big(\bfK_{\bfsigma_i^k}\bfV_m^k + \bfB_{\bfsigma_i^k} \bfV_m^k \big) = 0\\[4mm]
    \Leftrightarrow \quad &\bfK_{\bfsigma_e + \bfsigma_i}\bfphi_{e} + \bfB_{\bfsigma_e}\bfphi_{e} -\bfB_{\Gamma_M} \s{k=1}{M_\text{mu}} f_r^k \bfp^k
    +  \s{k=1}{M_\text{mu}} f_r^k \big(\bfK_{\bfsigma_i^k}\bfV_m^k + \bfB_{\Gamma_M} \bfp^k \big) = 0\\[4mm]
    \Leftrightarrow \quad &\bfK_{\bfsigma_e + \bfsigma_i}\bfphi_{e} + \bfB_{\Gamma_M}\bfq
    +  \s{k=1}{M_\text{mu}} f_r^k \bfK_{\bfsigma_i^k}\bfV_m^k = 0
  \end{array}
\end{equation}

The same operations can also be done by adding the flux terms to the vector of unknowns:
\begin{equation}\label{eq:multidomain_fe_flux}
  \begin{array}{ll|lll}
    \matt{
      \dfrac{\theta}{A_m^k\,C_m^k}\bfK_{\bfsigma_i^k} -\dfrac{1}{dt}\bfM &
      \dfrac{\theta}{A_m^k\,C_m^k}\bfK_{\bfsigma_i^k} &
       \ub{\dfrac{(1-\theta)}{A_m^k\,C_m^k}\,\bfB_{\Gamma_M}- \dfrac{(1-\theta)}{A_m^k\,C_m^k}\,\bfB_{\Gamma_M}}{=\bfzero} \quad &
      \ub{\dfrac{\theta}{A_m^k\,C_m^k}\,\bfB_{\Gamma_M} - \dfrac{\theta}{A_m^k\,C_m^k}\,\bfB_{\Gamma_M}}{=\bfzero}\\[8mm]
      f_r^k \,\bfK_{\bfsigma_i^k}  &
      \bfK_{\bfsigma_e + \bfsigma_i} &
      & 0 &
      \bfB_{\Gamma_M}
    }\\[2mm]
    \matt{
      \bfV_m^{(i+1)}\\[2mm]
       \bfphi_{e}^{(i+1)}\\[2mm]
       \bfp^{k,(i)}\\[2mm]
      \bfp^{k,(i+1)}\\[4mm]
        \bfq^{(i+1)}
    }
    =
    \matt{
      \big((\theta-1)\, \dfrac{1}{A_m^k\,C_m^k}\bfK_{\bfsigma_i^k} - \dfrac{1}{dt}\bfM\big) \bfV_m^{(i)}
      + (\theta - 1)\dfrac{1}{A_m^k\,C_m^k}\,\bfK_{\bfsigma_i^k}\,\bfphi_e^{(i)}\\[4mm]
      \bfzero
    },
  \end{array}
\end{equation}
where
\begin{equation*}
  \begin{array}{lll}
    p^{k,(i)} &= (\bfsigma_i^k \,∇V_m^{k,(i)})\cdot \bfn_m &= -(\bfsigma_i^k\,∇\phi_e^{(i)})\cdot \bfn_m
  \end{array}
\end{equation*}

So far we haven't specified a boundary condition for the second row.

%%

\subsection{Additional body region}
To simulate surface-electromyography we add a domain $\Omega_B$ which represents fat tissue. The setting is visualized by Fig.~\ref{fig:body_domain2}.

\bild{body_domain2}{0.3\textwidth}{Computational domains}

On the muscle domain $\Omega_M$, we have the 1st and 2nd Multidomain equation,
\begin{equation*}
  \begin{array}{lll}
    %\div\big(\bfsigma_e\,\grad(\phi_e)\big) + \s{k=1}{M_\text{mu}} f_r^k\,\div\big(\bfsigma_i^k\,\grad(\phi_i^k)\big) = 0.\\[4mm]
    \div\big((\bfsigma_e + \bfsigma_i) \,\grad(\phi_e)\big) + \s{k=1}{M_\text{mu}} f_r^k\,\div\big(\bfsigma_i^k\,\grad(V_m^k )\big) = 0,\\[4mm]
    \div\big(\bfsigma_i^k\,\grad(\phi_i^k)\big) = A_m^k\,\big(C_m^k\,\p{V_m^k}{t} + I_\text{ion}(V_m^k)\big), \qquad \forall\,k \in 1\dots M_\text{mu}.
  \end{array}
\end{equation*}
The 2nd Multidomain equation is solved using an operator splitting approach, which yields the following diffusion equation to be solved as one part of the splitting \eqref{eq:diffusion_term}:
\begin{equation*}
  \begin{array}{lll}
    \p{V_m^k}{t} = \dfrac{1}{A^k_m\,C_m^k}\div\big(\bfsigma_i^k\,\grad(V_m^k + \phi_e)\big)
  \end{array}
\end{equation*}

We assume a harmonic electric potential on $\Omega_B$:
\begin{equation*}
  \begin{array}{lll}
    \div \big(\bfsigma_b\,\grad (\phi_b)\big) = 0 \qquad \text{on } \Omega_B.
  \end{array}
\end{equation*}

The boundary conditions on $\Gamma_M$ are given by \eqref{eq:flux_bc}:
\begin{equation}\label{eq:bc1}
  \begin{array}{lll}
    &(\bfsigma_i^{k}\,∇\phi_i^{k})\cdot \bfn_m = 0   \qquad &\text{on } \Gamma_M \\[4mm]
    \quad \Rightarrow \quad
    &(\bfsigma_i^{k}\,∇V_m^{k})\cdot \bfn_m = -(\bfsigma_i^{k}\,∇\phi_e)\cdot \bfn_m =: p^k  \qquad &\text{on } \Gamma_M.
  \end{array}
\end{equation}
For the diffusion part of the 2nd Multidomain equation, boundary condition \eqref{eq:bc1} is satisfied automatically when all flux terms are neglected (cf. \eqref{eq:multidomain_fe_flux}).

The connection between muscle and body domain is given by the following conditions:
\begin{equation*}
  \begin{array}{lll}
    \phi_e = \phi_b  \qquad &\text{on } \Gamma_M,\\[4mm]
    (\bfsigma_e ∇ \phi_e)\cdot \bfn_m = -(\bfsigma_b ∇ \phi_b)\cdot \bfn_m =: q \qquad &\text{on } \Gamma_M.
  \end{array}
\end{equation*}
Furthermore we have with $\phi_e = \phi^k_i - V_m^k$:
\begin{equation*}
  \begin{array}{lll}
    \big((\bfsigma_e + \bfsigma_i)\,∇\phi_e\big) \cdot \bfn_m\\[4mm]
    = (\bfsigma_e\,∇\phi_e)\cdot \bfn_m + (\bfsigma_i\,∇\phi_e)\cdot \bfn_m\\[4mm]
    = q + \s{k=1}{M_\text{mu}}f_r^k\big( -\ub{( \bfsigma_i^k\,∇V_m^k)\cdot \bfn_m}{=p^k}
    + \ub{(\bfsigma_i^k \,∇\phi^k_i)\cdot \bfn_m}{=0, \,\eqref{eq:bc1}}\big)\\[4mm]
    = q - \s{k=1}{M_\text{mu}} f_r^k\,p^k
  \end{array}
\end{equation*}

The boundary conditions on the outer boundary of $∂\Omega_B$ are given by
\begin{equation*}
  \begin{array}{lll}
   (\bfsigma_b ∇\phi_b)\cdot \bfn_b = 0 \qquad &\text{on } \Gamma^\text{out}_B \cup \Gamma_M^\text{out}.
  \end{array}
\end{equation*}

\subsection{System of linear equations}
With the body potential, $\bfphi_b$, and for $M_\text{mu}=1$ motor unit, we get the following system:
\begin{equation*}
  \begin{array}{lll}
    \left[\begin{array}{@{}c|c|c|ccc@{}}
      \bfA_{V_m,V_m} & \bfB_{V_m,\phi_e} & &&\\[2mm]
      \bfB_{\phi_e,V_m} & \bfB_{\phi_e,\phi_e} & &f_r^k \,\bfB_{\Gamma_M}-f_r^k \,\bfB_{\Gamma_M}  & \bfB_{\Gamma_M}& \\[2mm] \hline
      &&\bfC_{\phi_b,\phi_b} & & -\bfB_{\Gamma_M}&\\[2mm]\hline
      & \bfI_{\Gamma_M} & -\bfI_{\Gamma_M} && &\\[2mm]
    \end{array}\right]
    \left[\begin{array}{@{}c@{}}
      V_{m}^{(i+1)}  \\[2mm]\hline
      \bfphi_{e}^{(i+1)} \\[2mm]\hline
      \bfphi_{b}^{(i+1)} \\[2mm]\hline
      \bfp^{k,(i+1)} \\[2mm]
      \bfq^{(i+1)}
    \end{array}\right]
    =
    \left[\begin{array}{@{}c@{}}
      \bfb_{V_m}^{(i+1)} \\
      \bfzero \\\hline
      \bfzero\\\hline
      \bfzero
    \end{array}\right]\\[4mm]
    \Leftrightarrow
    \quad
    \left[\begin{array}{@{}c|c|c|c@{}}
      \bfA_{V_m,V_m} & \bfB_{V_m,\phi_e} & &\\[2mm]
      \bfB_{\phi_e,V_m} & \bfB_{\phi_e,\phi_e} & &\bfB_{\Gamma_M} \\[2mm] \hline
      &&\bfC_{\phi_b,\phi_b} & -\bfB_{\Gamma_M}\\[2mm]\hline
      & \bfI_{\Gamma_M} & -\bfI_{\Gamma_M} &\\[2mm]
    \end{array}\right]
    \left[\begin{array}{@{}c@{}}
      V_{m}^{(i+1)}  \\[2mm]\hline
      \bfphi_{e}^{(i+1)} \\[2mm]\hline
      \bfphi_{b}^{(i+1)}  \\[2mm]\hline
      \bfq^{(i+1)}
    \end{array}\right]
    =
    \left[\begin{array}{@{}c@{}}
      \bfb_{V_m}^{(i+1)} \\[2mm]
      \bfzero\\\hline
      \bfzero\\\hline
      \bfzero
    \end{array}\right]
  \end{array},
\end{equation*}
where
\begin{equation*}
  \begin{array}{lll}
    \bfA_{V_m,V_m} = \dfrac{1}{A_m^k\,C_m^k}\theta\,\bfK_{\bfsigma_i^k} -\dfrac{1}{dt}\bfM,\\[4mm]
    \bfB_{V_m,\phi_e} = \dfrac{1}{A_m^k\,C_m^k}\theta\,\bfK_{\bfsigma_i^k},\\[4mm]
    \bfB_{\phi_e,V_m} = f_r^k \,\bfK_{\bfsigma_i^k},\\[4mm]
    \bfB_{\phi_e,\phi_e} = \bfK_{\bfsigma_e + \bfsigma_i},\\[4mm]
    \bfB_{\Gamma_B,kj} = \ds\int_{\Gamma_M} \psi_j\,\varphi_k \,\d\bfx,\\[4mm]
    \bfC_{\phi_b,\phi_b} = \bfK_{\bfsigma_b},\\[4mm]
    \bfI_{\Gamma_M} \text{ containing 1 entries for boundary dofs},\\[4mm]
    \bfb_{V_m}^{(i+1)} = \big((\theta-1)\, \dfrac{1}{A_m^k\,C_m^k}\bfK_{\bfsigma_i^k} - \dfrac{1}{dt}\bfM\big) \bfV_m^{(i)}
      + (\theta - 1)\dfrac{1}{A_m^k\,C_m^k}\,\bfK_{\bfsigma_i^k}\,\bfphi_e^{(i)}\\[4mm]
  \end{array}
\end{equation*}

This matrix can be condensed and takes the form
\begin{equation*}
  \begin{array}{lll}
    \Leftrightarrow
    \quad
    \left[\begin{array}{@{}c|c|c@{}}
      \bfA_{V_m,V_m} & \bfB_{V_m,\phi_e} & \\[2mm]
      \bfB_{\phi_e,V_m} & \bfB_{\phi_e,\phi_e} & \bfD \\[2mm] \hline
      &\bfE &\bfC_{\phi_b,\phi_b}\\[2mm]
    \end{array}\right]
    \left[\begin{array}{@{}c@{}}
      V_{m}^{(i+1)}  \\[2mm]\hline
      \bfphi_{e}^{(i+1)} \\[2mm]\hline
      \hat{\bfphi}_{b}^{(i+1)}
    \end{array}\right]
    =
    \left[\begin{array}{@{}c@{}}
      \bfb_{V_m}^{(i+1)} \\[2mm]
      \bfzero\\\hline
      \bfzero
    \end{array}\right]
  \end{array}.
\end{equation*}
Here, $\bfD$ and $\bfE$ contain entries for the dofs in the elements that are adajacent to the border dofs. The size of the last row and column of the system matrix is the number of dofs in the fat domain, without the border dofs, as they are already included in the second column and row.

$\hat{\bfphi}_{b}^{(i+1)}$ is the vector of body potential without dofs on the border.

\subsection{Summary}
\begin{equation*}
  \begin{array}{lll}
    \left[\begin{array}{@{}ccc|c|c@{}}
      \bfA^1_{V_m,V_m} & & &\bfB^1_{V_m,\phi_e} & \\[2mm]
      &\bfA^2_{V_m,V_m} &  &\bfB^2_{V_m,\phi_e} & \\[2mm]
      &&\bfA^k_{V_m,V_m}  &\bfB^k_{V_m,\phi_e} & \\[2mm]
      \bfB^1_{\phi_e,V_m} & \bfB^2_{\phi_e,V_m} & \bfB^k_{\phi_e,V_m} & \bfB_{\phi_e,\phi_e} & \bfD \\[2mm] \hline
      &&&\bfE &\bfC_{\phi_b,\phi_b}\\[2mm]
    \end{array}\right]
    \left[\begin{array}{@{}c@{}}
      V_{m}^{1,(i+1)}  \\[2mm]
      V_{m}^{2,(i+1)}  \\[2mm]
      V_{m}^{k,(i+1)}  \\[2mm]\hline
      \bfphi_{e}^{(i+1)} \\[2mm]\hline
      \hat{\bfphi}_{b}^{(i+1)}
    \end{array}\right]
    =
    \left[\begin{array}{@{}c@{}}
      \bfb_{V_m}^{1,(i+1)} \\[2mm]
      \bfb_{V_m}^{2,(i+1)} \\[2mm]
      \bfb_{V_m}^{k,(i+1)} \\[2mm]
      \bfzero\\\hline
      \bfzero
    \end{array}\right]
  \end{array}.
\end{equation*}

%\subsubsection{Flux boundary conditions}

%\begin{equation*}
  %\begin{array}{lll}
    %(\bfsigma_i^{k}\,∇V_m^{k})\cdot \bfn_m = -(\bfsigma_i^{k}\,∇\phi_e)\cdot \bfn_m &=: f  \qquad &\text{on } \Gamma_M\\[4mm]
    %(\bfsigma_e ∇ \phi_e)\cdot \bfn_m = -(\bfsigma_b ∇ \phi_b)\cdot \bfn_m &=: g \qquad &\text{on } \Gamma_M\\[4mm]
    %\big((\bfsigma_e + \bfsigma_i)∇\phi_e\big)\cdot \bfn_m &=: h
  %\end{array}
%\end{equation*}

% -------------- Literaturseite --------------------
\newpage
\nocite{*}
\bibliography{literatur}{}
\bibliographystyle{abbrv}

% -------------- Anhang ------------
%\appendix
%\input{8_anhang.tex}

\end{document}


\section{Preliminaries}

An undirected labeled graph \db is represented as a tuple $ \db =
(\vg,\eg,L) $ where $\vg$ is the set of vertices, $\eg$ is the set of
edges and $L\!\!: \vg \rightarrow \Sigma $ is a function that maps
vertices to their labels.  The neighbors of a vertex $v$ are given as $
N(v) = \{ u | (u,v) \in \eg \} $.  A
{\em path} in a graph $\db$ is a sequence of vertices $v_0,\ldots,v_k$
such that $v_i \in \vg$, $(v_i,v_{i+1}) \in \eg$ and $v_i \neq v_j$ for
$i \neq j$.
We use $\kpath{u}{v}{k}$ if there is a $k$ edge path
between $u$ and $v$.
%It covers the vertices $\cup_{i=0}^{k} \{v_i\}$ and the edges $\cup_{i=0}^{k-1}
%\{(v_i,v_{i+1})\}$.
A path is called a walk if the vertices
are allowed to repeat. For example in graph \ref{subfig:ex_db}, the sequence
$50, 20, 10, 40, 60, 30$ is a path and the sequence $10, 40, 60, 30, 10$ is
a walk.
[ can we define this when required ?]

\smallskip\noindent{\bf Cost matrix:}
We assume that there is a cost matrix
$C\!\!:\Sigma^{2} \rightarrow \mathbb{R}_{\geq 0} $.
The entry $\matij{C}{l_i}{l_j}$
denotes the cost of matching the labels $l_i$ and $l_j$. Although it is
not required by the algorithm, $C$ is usually symmetric and the diagonal
entries are $0$

\smallskip\noindent{\bf Approximate subgraph isomorphism:}
A graph $S = (V_S,E_S,L)$ is a subgraph of \db, denoted $S \subseteq
\db$, iff $V_S \subseteq \vg$, and $E_S \subseteq \eg$.  $S$ is an
induced subgraph if $E_S = \eg \cap (V_S \times V_S)$.  Given a database
graph $G$ and a pattern $P = (V_P,E_P,L)$, a function $\phi\!\!: V_P \to
V_G$ is called an {\em unlabeled subgraph isomorphism} provided $\phi$
is an injective (or one-to-one) mapping such that $\forall (u,v) \in
E_P$, we have $(\phi(u),\phi(v)) \in \eg$. That is, $\phi$ preserves the
topology of $P$ in $G$. Define the cost of the isomorphism as follows:
$C(\phi) = \sum_{u \in \vp} \matij{C}{L(u)}{L(\phi(u))}$, that is, the
sum of the costs of matching the node labels in $P$ to the corresponding
node labels in $G$.  We say that $\phi$ is an {\em approximate subgraph
isomorphism} from $P$ to $G$ provided its cost $C(\phi) \le \alpha$,
where $\alpha$ is a user-specified threshold on the total cost. In this
case we also call $P$ an approximate pattern in $G$. Note
that if $\alpha = 0$, then $\phi$ is an unlabeled subgraph isomorphism
between $P$ and $G$. From now on, \textit{isomorphism}
refers to \textit{approximate subgraph isomorphism} unless specified
otherwise.

%%% Example graphs to illustrate the notation used in the paper
\begin{figure}[!h]
\vspace{-0.25in}
\captionsetup[subfloat]{captionskip=15pt}
  \subfloat[Database Graph $\db$] {
    \label{subfig:ex_db}
  \scalebox{0.9}{
    \begin{pspicture}(-1,0)(3,3)
      \putNode{1}{2}{n1}{A}{90}{10}
      \putNode{0}{1}{n2}{A}{180}{20}
      \putNode{1}{1}{n3}{B}{225}{30}
      \putNode{2}{1}{n4}{A}{0}{40}
      \putNode{0}{0}{n5}{C}{270}{50}
      \putNode{1.5}{0}{n6}{C}{270}{60}

      \ncline{-}{n1}{n2}
      \ncline{-}{n1}{n3}
      \ncline{-}{n1}{n4}
      \ncline{-}{n2}{n3}
      \ncline{-}{n3}{n4}
      \ncline{-}{n3}{n6}
      \ncline{-}{n4}{n6}
      \ncline{-}{n2}{n5}
    \end{pspicture}
	}}
  % Graph subgraph isomorphic to the database
  \subfloat[Pattern $P$] {
    \label{subfig:ex_sub}
  \scalebox{0.9}{
    \begin{pspicture}(0.5,1)(3,3)
      \putNode{2}{3}{n1}{A}{90}{1}
      \putNode{1}{2}{n2}{B}{180}{2}
      \putNode{3}{2}{n3}{C}{0}{3}
      \putNode{2}{1}{n4}{A}{0}{4}
      \ncline{-}{n1}{n2}
      \ncline{-}{n1}{n3}
      \ncline{-}{n2}{n4}
      \ncline{-}{n3}{n4}
    \end{pspicture}
	}}
  \newline
\captionsetup[subfloat]{captionskip=5pt}
  \subfloat[Cost Matrix] {
    \label{subfig:ex_match}
    \begin{tabular}{|c|c|c|c|c|}
      \hline
      \M{C} & A &  B & C & D \\
      \hline
      A & $0$ & $0.2$ & $0.6$ & $0.1$ \\
      \hline
      B & $0.2$ & $0$ & $0.4$ & $0.5$ \\
      \hline
      C & $0.6$ & $0.4$ & $0$ & $0.2$ \\
      \hline
      D & $0.1$ & $0.5$ & $0.2$ & $0$ \\
      \hline
    \end{tabular}
  }
  % Approximately isomorphic
  \subfloat[Approximate Embeddings] {
      \label{subfig:ex_occur}
      \begin{tabular}{|l|c|c|c|c|c|}
		\hline
		 & \multicolumn{5}{|c|}{$\phi$}\\
        \hline
		$P$ & $1$ & $2$ & $3$ & $4$ & cost \\
        \hline
        $\phi_1$ & $30$ & $10$ & $60$ & $40$ & $0.4$ \\
        $\phi_2$ & $40$ & $10$ & $60$ & $30$ & $0.4$\\
        \hline
      \end{tabular}
  }
  % occurrences of the approx pattern
  \caption{ \protect\subref{subfig:ex_db}: sample database graph $G$,
    \protect\subref{subfig:ex_sub}: approximate pattern $P$.
	\protect\subref{subfig:ex_match}: cost matrix.
	\protect\subref{subfig:ex_occur}: approximate embeddings
	of $P$ in $G$.
  }
  \label{fig:ex1}
\end{figure}

\smallskip\noindent{\bf Representative set and pattern support:}
Given a node $u \in \vp$, its {\em representative set} in the database
graph $G$ is the set
$$R(u) = \{ v \in \vg |\; \exists \phi, \text{ such
that } C(\phi) \le \alpha \text{ and } \phi(u) = v \}$$
That is, the representative set of $u$ comprises all nodes in $G$ that
$u$ is mapped to in some approximate isomorphism.
Figure
\ref{fig:ex1} shows an example database, a cost matrix, an approximate
pattern, and its approximate subgraph isomorphism for $\alpha=0.5$.
There are only two possible approximate isomorphisms from $P$ to $G$, as
specified by $\phi_1$ and $\phi_2$. For example, for $\phi_1$, we have
$\phi_1(1) \to 30$, $\phi_1(2) \to 10$, $\phi_1(3) \to 60$, and
$\phi_1(4) \to 40$, as seen in Table~\ref{subfig:ex_occur}.
The cost of the isomorphism is
$C(\phi_1) = 0.4$, since
$C(L(1),L(30)) + C(L(2),L(10)) + C(L(3),L(60)) + C(L(4),L(40))
= C(A,B) + C(B,A) + C(C,C)+ C(A,A) = 0.2+0.2+0+0 = 0.4$.
The representative
set for node $1 \in \vp$ is $R(1) = \{30, 40\}$. However, the
support of $P$ is $sup(P) = 1$, since node $2 \in \vp$ has only one
mapping in $G$, namely $R(2) = \{10\}$.

%%%% Define a frequent pattern

\subsection{Outline} The two main steps in approximate graph mining are
candidate generation and support computation. With candidate generation the
search space of the frequent patterns is explored. For each candidate that is
generated, we can check whether it is frequent by computing its support.

Given a pattern with $k$ vertices, the maximum number of possible isomorphisms
are $k \times {|\vg| \choose k} $.  It is therefore infeasible to either
enumerate or store the complete set of isomorphisms. Computing and storing the
representative sets is a compromise that will enable us to decide efficiently if
a candidate is frequent.

The rest of the paper is structured as follows. In section
\ref{sec:representative} we propose methods for computing the representative
sets. In section, \ref{sec:mining} we describe how the idea of representative
sets can be combined with different candidate generation and support computation
mechanisms to yield mining algorithms with different properties. In section
\ref{sec:results}, we present detailed experimental results to show that the
proposed methods can be used to mine interesting and useful frequent patterns
from three real world datasets.  We discuss the related work in section
\ref{sec:relatedwork} and conclude in section \ref{sec:conclusions}

%%%%%%%%% the definition of support is moved to a later section %%%%%%
\if0
Define the {\em
support} of pattern $P$ in a database graph $G$ as
$$sup(P) = \min_{u \in
\vp} \{ |R(u)| \}$$
That is, the minimum cardinality over all
representative set of nodes in $P$.  A pattern $P$ is called {\em
frequent} if $sup(P) \geq minsup$, where $minsup$ is a user defined
support threshold.  $P$ is {\em maximal} iff $P$ is frequent and there
does not exist any supergraph of $P$ that is frequent in $G$.

\smallskip
\noindent{\bf Problem Statement:} Given a database graph \db, minimum
support $minsup$, maximum allowed cost $\alpha$, and an integer $k$, our
goal is to mine $k$ maximal frequent approximate patterns.  Figure
\ref{fig:ex1} shows an example database, a cost matrix, an approximate
pattern, and its isomorphisms for $\alpha=0.5$.
There are only two possible isomorphisms from $P$ to $G$, as
specified by $\phi_1$ and $\phi_2$. For example, for $\phi_1$, we have
$\phi_1(10) \to 3$, $\phi_1(20) \to 1$, $\phi_1(30) \to 6$, and
$\phi_1(40) \to 4$, as seen in Table~\ref{subfig:ex_occur}.
The cost of the isomorphism is
$C(\phi_1) = 0.4$, since
$C(L(10),L(3)) + C(L(20),L(1)) + C(L(30),L(6)) + C(L(40),L(4))
= C(A,B) + C(B,A) + C(C,C)+ C(A,A) = 0.2+0.2+0+0 = 0.4$.
The representative
set for node $10 \in \vp$ is $R(10) = \{3, 4\}$. However, the
support of $P$ is $sup(P) = 1$, since node $20 \in \vp$ has only one
mapping in $G$, namely $R(20) = \{1\}$.
\fi


\documentclass[11pt]{article}
\usepackage[
a4paper,
margin=1in,
headsep=4pt, % separation between header rule and text
]{geometry}
\usepackage{xcolor}
\usepackage{fancyhdr}
\usepackage{tgschola}
\usepackage{lastpage}
\usepackage[natbibapa]{apacite}
\usepackage{listings}
\usepackage{subfigure}
\usepackage{color}
\usepackage{dsfont}
\usepackage{footmisc}
\usepackage{verbatim}
\usepackage{smartdiagram}
\setlength{\marginparwidth}{0cm}
\setlength{\topmargin}{0cm}
\setlength{\voffset}{0cm}
\setlength{\headsep}{0cm}
\definecolor{dkgreen}{rgb}{0,0.6,0}
\definecolor{gray}{rgb}{0.5,0.5,0.5}
\definecolor{mauve}{rgb}{0.58,0,0.82}
\usepackage[utf8]{inputenc}
\graphicspath{{/Users/auddya/uw-me/2018/mechanicalBidomainModel/}}
\lstset{frame=tb,
	language=Java,
	aboveskip=3mm,
	belowskip=3mm,
	showstringspaces=false,
	columns=flexible,
	basicstyle={\small\ttfamily},
	numbers=none,
	numberstyle=\tiny\color{gray},
	keywordstyle=\color{blue},
	commentstyle=\color{dkgreen},
	stringstyle=\color{mauve},
	breaklines=true,
	breakatwhitespace=true,
	tabsize=3
}
\pagestyle{fancy}
\fancyhf{}
\fancyhead[C]{%
	\footnotesize\sffamily
	\yourname\quad
	web: \textcolor{blue}{\itshape\yourweb}\quad
	\textcolor{blue}{\youremail}}
\fancyfoot[C]{Page \thepage\ of \pageref{LastPage}}

\newcommand{\soptitle}{A computational study of mechanical bidomain model in durotaxis}

\newcommand{\yourname}{Debabrata Auddya}
\newcommand{\youremail}{auddya@wisc.edu}
\newcommand{\yourweb}{https://github.com/auddya}

\newcommand{\statement}[1]{\par\medskip
	\textcolor{blue}{\textbf{#1:}}\space
}

\usepackage[
breaklinks,
pdftitle={\yourname - \soptitle},
pdfauthor={\yourname},
unicode
]{hyperref}

\begin{document}

	\begin{center}
		\Large\soptitle
	\end{center}

\section*{Parameters}
N = 101 (No of nodes) \\
L = 0.005 m (Length of domain) \\
nu = 1000 Pa (Intracellular modulus) \\
mu\_zero = 1000 Pa (Extracellular modulus) \\
K = 50000000000 Pa/$m^{2}$ (Stiffness) \\
T =  200 Pa (Tension) \\
\section*{Code and Results}
\begin{lstlisting}
N = 101;
L = 0.005; %0.005m
g = 0; %100000; %100000 Pa/m
mu_zero = 1000; %1000 Pa
nu = 1000; %1000 Pa
K = 50000000000; %50GPa/m2
T = 200; %200Pa
w = zeros(N,1); %Extracellular displacement
u = zeros(N,1); %Intracellular displacement
x = zeros(N,1); %x position, useful when plotting
delta = (2*L)/(N-1); %Spacing along x direction
iterations = 100;
for i = 1:N
x(i) = L*(2*(i-1)/(N-1)-1);
mu(i) = mu_zero + g*x(i);
end
for k = 1:iterations
for i = 2:(N-1)
a(i) = 4*mu(i)*(w(i+1)+w(i-1))+(mu(i+1)-mu(i-1))*(w(i+1)-w(i-1));
b(i) = 4*nu*(u(i+1)+u(i-1));
A(i) = 8*mu(i) + K*delta*delta;
C = 8*nu + K*delta*delta;
B = K*delta*delta;
u(i) = (a(i)*B + A(i)*b(i))/(A(i)*C - B*B);
w(i) = (a(i)/A(i)) + (B/A(i))*((a(i)*B + A(i)*b(i))/(A(i)*C - B*B));
end
%Apply Boundary Conditions
u(1) = u(2) + (T*delta/(4*nu));
w(1) = w(2);
u(N) = u(N-1) - (T*delta/(4*nu));
w(N) = w(N-1);
end
for i = 1:N
h(i) = u(i)-w(i);
end
plot(x,h)  %if you want plot with x in mm, use plot(x*1000,h)
xlabel('x');
ylabel('u-w');
title('Difference between extracellular and intracellular displacement');
\end{lstlisting}
\begin{figure}
	\begin{center}
		%
		\subfigure[Difference in displacements for g=0]{%
			\label{fig:uw0}
			\includegraphics[width=0.4\textwidth]{/testResultsNew/u-w2(g_0).jpg}
		}%
		\subfigure[Difference in displacements for g=$10^5$]{%
			\label{fig:uwvar}
			\includegraphics[width=0.4\textwidth]{/testResultsNew/u-w2(g_var).jpg}
		}\\ %  ------- End of the first row ----------------------%
		\subfigure[Intracellular displacement for g=0]{%
			\label{fig:u0}
			\includegraphics[width=0.4\textwidth]{/testResultsNew/u2(g_0).jpg}
		}%
		\subfigure[Intracellular displacement for g=$10^5$]{%
			\label{fig:uvar}
			\includegraphics[width=0.4\textwidth]{/testResultsNew/u2(g_var).jpg}
		}\\
			\subfigure[Extracellular displacement for g=0]{%
		\label{fig:w0}
		\includegraphics[width=0.4\textwidth]{/testResultsNew/w2(g_0).jpg}
	  }%
	\subfigure[Extracellular displacement for g=$10^5$]{%
		\label{fig:wvar}
		\includegraphics[width=0.4\textwidth]{/testResultsNew/w2(g_var).jpg}
	 }%
	\end{center}
	\caption{%
Comparison of results for g=0 and g=$10^5$ Pa/m (Iteration: 100). Elapsed time is 0.320051 seconds.
	}%
	\label{fig:subfigures2}
\end{figure}
\begin{figure}
	\begin{center}
		%
		\subfigure[Difference in displacements for g=0]{%
			\label{fig:uw02}
			\includegraphics[width=0.4\textwidth]{/testResultsNew/u-w3(g_0).jpg}
		}%
		\subfigure[Difference in displacements for g=$10^5$]{%
			\label{fig:uwvar2}
			\includegraphics[width=0.4\textwidth]{/testResultsNew/u-w3(g_var).jpg}
		}\\ %  ------- End of the first row ----------------------%
		\subfigure[Intracellular displacement for g=0]{%
			\label{fig:u02}
			\includegraphics[width=0.4\textwidth]{/testResultsNew/u3(g_0).jpg}
		}%
		\subfigure[Intracellular displacement for g=$10^5$]{%
			\label{fig:uvar3}
			\includegraphics[width=0.4\textwidth]{/testResultsNew/u3(g_var).jpg}
		}\\
		\subfigure[Extracellular displacement for g=0]{%
			\label{fig:w03}
			\includegraphics[width=0.4\textwidth]{/testResultsNew/w3(g_0).jpg}
		}%
		\subfigure[Extracellular displacement for g=$10^5$]{%
			\label{fig:wvar3}
			\includegraphics[width=0.4\textwidth]{/testResultsNew/w3(g_var).jpg}
		}%
	\end{center}
	\caption{%
		Comparison of results for g=0 and g=$10^5$ Pa/m (Iteration: 1000). Elapsed time is 0.366209 seconds.
	}%
	\label{fig:subfigures3}
\end{figure}
\begin{figure}
	\begin{center}
		%
		\subfigure[Difference in displacements for g=0]{%
			\label{fig:uw04}
			\includegraphics[width=0.4\textwidth]{/testResultsNew/u-w4(g_0).jpg}
		}%
		\subfigure[Difference in displacements for g=$10^5$]{%
			\label{fig:uwvar4}
			\includegraphics[width=0.4\textwidth]{/testResultsNew/u-w4(g_var).jpg}
		}\\ %  ------- End of the first row ----------------------%
		\subfigure[Intracellular displacement for g=0]{%
			\label{fig:u04}
			\includegraphics[width=0.4\textwidth]{/testResultsNew/u4(g_0).jpg}
		}%
		\subfigure[Intracellular displacement for g=$10^5$]{%
			\label{fig:uvar4}
			\includegraphics[width=0.4\textwidth]{/testResultsNew/u4(g_var).jpg}
		}\\
		\subfigure[Extracellular displacement for g=0]{%
			\label{fig:w04}
			\includegraphics[width=0.4\textwidth]{/testResultsNew/w4(g_0).jpg}
		}%
		\subfigure[Extracellular displacement for g=$10^5$]{%
			\label{fig:wvar4}
			\includegraphics[width=0.4\textwidth]{/testResultsNew/w4(g_var).jpg}
		}%
	\end{center}
	\caption{%
		Comparison of results for g=0 and g=$10^5$ Pa/m (Iteration: 10000). Elapsed time is 0.414921 seconds.
	}%
	\label{fig:subfigures4}
\end{figure}
\begin{figure}
	\begin{center}
		%
		\subfigure[Difference in displacements for g=0]{%
			\label{fig:uw05}
			\includegraphics[width=0.4\textwidth]{/testResultsNew/u-w5(g_0).jpg}
		}%
		\subfigure[Difference in displacements for g=$10^5$]{%
			\label{fig:uwvar5}
			\includegraphics[width=0.4\textwidth]{/testResultsNew/u-w5(g_var).jpg}
		}\\ %  ------- End of the first row ----------------------%
		\subfigure[Intracellular displacement for g=0]{%
			\label{fig:u05}
			\includegraphics[width=0.4\textwidth]{/testResultsNew/u5(g_0).jpg}
		}%
		\subfigure[Intracellular displacement for g=$10^5$]{%
			\label{fig:uvar5}
			\includegraphics[width=0.4\textwidth]{/testResultsNew/u5(g_var).jpg}
		}\\
		\subfigure[Extracellular displacement for g=0]{%
			\label{fig:w05}
			\includegraphics[width=0.4\textwidth]{/testResultsNew/w5(g_0).jpg}
		}%
		\subfigure[Extracellular displacement for g=$10^5$]{%
			\label{fig:wvar5}
			\includegraphics[width=0.4\textwidth]{/testResultsNew/w5(g_var).jpg}
		}%
	\end{center}
	\caption{%
		Comparison of results for g=0 and g=$10^5$ Pa/m (Iteration: 100000). Elapsed time is 0.772543 seconds.
	}%
	\label{fig:subfigures5}
\end{figure}
\begin{figure}
	\begin{center}
		%
		\subfigure[Difference in displacements for g=0]{%
			\label{fig:uw06}
			\includegraphics[width=0.4\textwidth]{/testResultsNew/u-w6(g_0).jpg}
		}%
		\subfigure[Difference in displacements for g=$10^5$]{%
			\label{fig:uwvar6}
			\includegraphics[width=0.4\textwidth]{/testResultsNew/u-w6(g_var).jpg}
		}\\ %  ------- End of the first row ----------------------%
		\subfigure[Intracellular displacement for g=0]{%
			\label{fig:u06}
			\includegraphics[width=0.4\textwidth]{/testResultsNew/u6(g_0).jpg}
		}%
		\subfigure[Intracellular displacement for g=$10^5$]{%
			\label{fig:uvar6}
			\includegraphics[width=0.4\textwidth]{/testResultsNew/u6(g_var).jpg}
		}\\
		\subfigure[Extracellular displacement for g=0]{%
			\label{fig:w06}
			\includegraphics[width=0.4\textwidth]{/testResultsNew/w6(g_0).jpg}
		}%
		\subfigure[Extracellular displacement for g=$10^5$]{%
			\label{fig:wvar6}
			\includegraphics[width=0.4\textwidth]{/testResultsNew/w6(g_var).jpg}
		}%
	\end{center}
	\caption{%
		Comparison of results for g=0 and g=$10^5$ Pa/m (Iteration: 1000000). Elapsed time is 6.259795 seconds.
	}%
	\label{fig:subfigures6}
\end{figure}
\section*{Difference of displacements as a function of stiffness gradient}
\begin{figure}[htb]
  \begin{center}
 	 \includegraphics[scale=0.3]{/testResultsNew/variationG.jpg}
	\caption{Difference in intracellular and extracellular displacements about x = 0 as a function of \textbf{g}}
	\label{fig:uwG}
 \end{center}
\end{figure}
\newpage
\section*{Over Relaxation}
Variation of computation time with linearly increasing over relaxation parameter. The \textbf{stars} indicate the minimum value in each iteration limit. The figures below illustrate with iteration ranges from $10^2$ to $10^4$
\begin{figure}[htb]
  \begin{center}
	 \includegraphics[scale = 0.85]{/testResultsNew/ite2.jpg}
	 \caption{Iteration range: 100 - 1000}
	 \label{fig:ite2}
  \end{center}
\end{figure}
\begin{figure}[htb]
  \begin{center}
	 \includegraphics[scale = 0.85]{/testResultsNew/ite3.jpg}
	 \caption{Iteration range: 1000 - 10000}
	 \label{fig:ite3}
  \end{center}
\end{figure}
\begin{figure}[htb]
  \begin{center}
	 \includegraphics[scale = 0.85]{/testResultsNew/ite4.jpg}
	 \caption{Iteration range: 30000 - 90000}
	 \label{fig:ite4}
  \end{center}
\end{figure}
%\newpage
%\section*{SOR Iterations against time}
%\begin{table}[htb]
%	\centering
%	\resizebox{\textwidth}{!}{%
%		\begin{tabular}{lll}
%			Iterations & Time (seconds) & Relaxation Value \\
%			100        & 0.000535       & 1.94             \\
%			1000       & 0.0055         & 1.87             \\
%			10000      & 0.0541         & 1.95             \\
%			100000     & 0.5556         & 1.92             \\
%			1000000    & 5.4486         & 1.91
%		\end{tabular}%
%	}
%\end{table}
\end{document}