\section{1D example}
Consider the 1D case of Theorem \ref{lem:stratifiedapprox2}
\begin{theorem}
Suppose $x\in [-T, T]$ and $f\in \mathcal{B}^{m+1, 1}([-T, T])$.
%$$
% \int_{\mathbb{R}^{d}} |\hat{f}(\omega)|\|\omega\|_{\ell_q}^{m+1} d\omega<\infty.
%$$
There exist $\beta_j\in \{-1, 1\}$, $\bar \omega_j\in\{1, -1\}$, $t\in [0,T]$ such that
\begin{equation}\label{1drepresentation}
f_n(x)= \sum_{k\le m}{1\over k!}f^{(k)}(0) x^k + {\nu\over m!n}\sum_{j=1}^{n}\beta_j (\bar \omega_j x - t_j)_+^m
\end{equation}
with $\nu=\int_{\{-1,1\}\times [0,T]\times \mathbb{R}^{d}} \rho(\theta)d\theta$ and $\rho(\theta)$  defined in \eqref{eq:straglam}
satisfies the following estimate
\begin{equation}
\|f - f_n \|_{H^k(\Omega)} \leq C(m,k,\Omega) n^{-{1\over 2}-{1\over d+2}}\|f\|_{\mathcal B^{m+1, q}(\Omega)},\qquad k\le m.
\end{equation}
Especially,
\begin{equation}
\|f - f_n \|_{L^2(\Omega)} \leq {(2T)^m|\Omega|^{1\over 2}\over (m-1)!} n^{-{1\over 2}-{1\over d+2}}\|f\|_{\mathcal B^{m+1, q}(\Omega)}.
\end{equation}
%\begin{equation}
%\|D^\beta (f(x)- f_n(x))\|_{L^2(\Omega)}\le \sqrt{2^{m-k-2}(2m-k)\over k!(m-k)!}|\Omega|^{1/2} n^{-{1\over 2}-{1\over d}},\quad |\beta|=k\le m.
%\end{equation}
\end{theorem}

If $\bar \omega_j=-1$,
\begin{equation}
\beta_j (\bar \omega_j  x - t_j)_+^m = \beta_j (- (x - (-t_j)))_+^m.
\end{equation}
If $m$ is odd,
\begin{equation}
\beta_j (\bar \omega_j  x - t_j)_+^m = - \beta_j (x - (-t_j))_-^m = \tilde \beta_j(x - \tilde t_j)_-^m
\end{equation}
with $\tilde \beta_j=-\beta_j\in \{-1, 1\}$ and $\tilde t_j\in[-T, 0]$.
If $m$ is even,
\begin{equation}
\beta_j (\bar \omega_j  x - t_j)_+^m = \tilde \beta_j (x - \tilde t_j)_-^m
\end{equation}
with $\tilde \beta_j=\beta_j\in \{-1, 1\}$ and $\tilde t_j\in[-T, 0]$.

\begin{equation}
\begin{split}
&f(x) - \sum_{k\le m}{1\over k!}f^{(k)}(0) x^k
\\
=&{\rm Re} \bigg ({i^{m+1}\over m!}\int_{\mathbb{R}^d} \int_{0}^T\left[(\bar \omega  x - t)_+^me^{i|\omega|t}
+(-1)^{m-1}(-\bar \omega x - t)_+^me^{-i|\omega|t} \right]\hat{f}(\omega)|\omega|^{m+1}dt d\omega\bigg )
\end{split}
\end{equation}
If $m$ is odd,
$$
(\bar \omega  x - t)_+^me^{i|\omega|t}
+(-1)^{m-1}(-\bar \omega x - t)_+^me^{-i|\omega|t}
=
(x - t)_+^me^{i\omega t}
+(- x - t)_+^me^{-i\omega t}.
$$
Thus,
\begin{equation}
\begin{split}
&f(x) - \sum_{k\le m}{1\over k!}f^{(k)}(0) x^k
\\
=&{\rm Re} \bigg ({1\over m!}\int_{\mathbb{R}^d} \int_{0}^T\left[(x - t)_+^me^{i \omega t}
+ (- x - t)_+^me^{-i \omega t} \right]\hat{f}(\omega) (i\omega)^{m+1}dt d\omega\bigg )
\end{split}
\end{equation}
Note that
\begin{equation}
f^{(m)}(t)=\int (i\omega)^m\hat{f}(\omega)e^{i\omega t}d\omega
\end{equation}
It holds that
\begin{equation}
\begin{split}
&f(x) - \sum_{k\le m}{1\over k!}f^{(k)}(0) x^k
\\
=&{\rm Re} \bigg ({1\over m!}\int_{\mathbb{R}^d} \int_{0}^T\left[(x - t)_+^me^{i \omega t}
+ (- x - t)_+^me^{-i \omega t} \right]\hat{f}(\omega) (i\omega)^{m+1}dt d\omega\bigg )
\\
=& {1\over m!} \int_{0}^T\left[(x - t)_+^m f^{(m+1)}(t)
+ (- x - t)_+^mf^{(m+1)}(-t) \right] dt
\end{split}
\end{equation}

\noindent\textbf{1D case from Taylor expansion}

Consider the case that $\Omega=[0,1]$, the integral form of Taylor remainder reads
\begin{equation}
\begin{aligned}
f(x) - \sum_{k\le m}{1\over k!}f^{(k)}(0) x^k &={1\over m!}\int_0^x f^{(m+1)}(t)(x-t)^mdt
\\
&={1\over m!}\int_0^1 f^{(m+1)}(t)(x-t)_+^mdt.
\end{aligned}
\end{equation}
Let the probability density be
\begin{equation}
\lambda(t)= {|f^{(m+1)}(t)|\over \|f^{(m+1)}\|_{L^1}}.
\end{equation}
Thus,
\begin{equation}
\begin{aligned}
f(x) - \sum_{k\le m}{1\over k!}f^{(k)}(0) x^k &={ \|f^{(m+1)}\|_{L^1}\over m!}\int_0^1 sgn(f^{(m+1)}(t))(x-t)_+^m\lambda(t)dt.
\end{aligned}
\end{equation}
\begin{lemma}
	 There exists
	 \begin{equation}
\begin{aligned}
f_n(x) = \sum_{k\le m}{1\over k!}f^{(k)}(0) x^k + { \|f^{(m+1)}\|_{L^1}\over m!n}\sum_{i=1}^n\beta_i  (x-t)_+^m.
\end{aligned}
\end{equation}
with $\beta_i\in [-2,2]$
 such that
	\begin{equation}
	\|f-f_n\|_{H^k(\Omega)} \leq n^{-3/2}|\Omega|^{1/2}.
	\end{equation}
	\end{lemma}

\begin{proof}
Note that $\displaystyle f(x)-f_n(x)={ \|f^{(m+1)}\|_{L^1}\over m!}\left(r(x) - r_n(x)\right)$ with
\begin{equation}
r(x) = \int_0^1 sgn(f^{(m+1)}(t))(x-t)_+^m\lambda(t)dt,\quad r_n(x)= {1\over n}\sum_{i=1}^n\beta_i  (x-t)_+^m.
\end{equation}
Consider a $\epsilon$-covering decomposition $G=\cup_{i=1}^M G_i$ of $\Omega$ such that
\begin{equation}
sgn(f^{(m+1)}(t))= sgn(f^{(m+1)}(t')), \quad |t-t'|<\epsilon, \quad \forall t,\ t'\in G_i.
\end{equation}
Let $n_j=\lceil \lambda(G_j)n\rceil$ and $t_{i,j} \in G_j(1\leq i\leq n_j)$ and
\begin{equation}
r(x) = \int_0^1 g(x, t)\lambda(t)dt,\quad r_n(x)= \sum_{i=1}^M \lambda(G_i) g_{n_i}^i,\quad \mbox{ with }\ g(x, t)=(x-t)_+^m,\ g_{n_i}^i ={1\over n_i}  \sum_{j=1}^{n_i}(x-t_{ij})_+^m.
\end{equation}
Define
\begin{equation}
\begin{aligned}
f_n(x) = \sum_{k\le m}{1\over k!}f^{(k)}(0) x^k + { \|f^{(m+1)}\|_{L^1}\over m!}r_n(x).
\end{aligned}
\end{equation}
Thus, $\displaystyle f(x)-f_n(x)={ \|f^{(m+1)}\|_{L^1}\over m!}\left(r(x) - r_n(x)\right)$. Note that
\begin{equation}
\begin{aligned}
r(x) = \mathbb{E}_G g =  \sum_{i=1}^{M}\lambda(G_i) \mathbb{E}_{G_i} g.
\end{aligned}
\end{equation}
By Lemma \ref{MC},
\begin{equation}
\begin{split}
\mathbb{E}_n\| r^{(k)} - r_n^{(k)} \|_{L^2(\Omega)}^2=&
 \sum_{j=1}^{M}{\lambda^2(G_i) \over n_i}\mathbb{E}_{G_i}\|\mathbb{E}_{G_i} \partial_x g -  \partial_x g^{(k)}\|^2_{L^2(\Omega)}
\\
\le & \sum_{i=1}^{M} {\lambda^2(G_i)\over n_i}\sup_{t,t'\in G_i} \|\partial_x  g(x, t) - \partial_x g(x,t')\|^2_{L^2(\Omega)}.
\end{split}
\end{equation}
Since ${\lambda(G_i)\over n_i}\le {1\over n}$ and $\displaystyle \sum_{i=1}^M \lambda(G_i)=1$,
\begin{equation}
\mathbb{E}_n\| r^{(k)} - r_n^{(k)} \|_{L^2(\Omega)}^2\leq n^{-1}\max_{1\le i\le M}\sup_{t,t'\in G_i} \| \partial_x g(x,t) - \partial_x g(x,t')\|^2_{L^2(\Omega)}.
\end{equation}
Notice that for any $1\le i\le M$,
\begin{equation}
\sup_{t,t'\in G_i} \| \partial_x g(x,t) - \partial_x g(x,t')\|^2_{L^2(\Omega)}\lesssim |t-t'|^2|\Omega| \le | \Omega| \epsilon^2.
\end{equation}
Since $\epsilon \sim M^{-1}$,
there exist $\{t_{i,j}^\ast\}$ such that $t_{i,j}^\ast\in G_i$ and
\begin{equation}
\| f^{(k)} -  f_n^{(k)} \|_{L^2(\Omega)}^2\leq (M^2n)^{-1}| \Omega|.
\end{equation}
Suppose $\displaystyle N=\sum_{j=1}^M n_j$, $n\le N\le n+M$,
$$
r_n(x) =  {1\over N}\sum_{i=1}^{M}\frac{N\lambda(G_i)}{n_i}\sum_{j=1}^{n_i} (x - t_{i,j}^\ast)_+^m
 =  {1\over N}\sum_{i=1}^{M}\beta_{i,j}\sum_{j=1}^{n_i} (x - t_{i,j}^\ast)_+^m
$$
with
\begin{equation}
\beta_{i,j}= \frac{N\lambda(G_j)}{n_j}\le \frac{\lambda(G_j)(M+n)}{\lambda(G_j)n}\le {M+n\over n}.
\end{equation}
Let $M=n$. There exist $\{t_{i,j}^\ast\}$ such that $t_{i,j}^\ast\in G_i$ and
\begin{equation}
\| f -  f_n \|_{H^k(\Omega)}^2\leq N^{-3}| \Omega|,
\end{equation}
which completes the proof.
\end{proof}

\begin{theorem}
	 There exists
	 \begin{equation}
\begin{aligned}
f_n(x) = \sum_{k\le m}{1\over k!}f^{(k)}(0) x^k + { \|f^{(m+1)}\|_{L^1}\over m!n}\sum_{i=1}^n (x-t)_+^m.
\end{aligned}
\end{equation}
 such that
	\begin{equation}
	\|f-f_n\|_{H^k(\Omega)} \leq n^{-{3\over 4}}|\Omega|^{1/2}.
	\end{equation}
\end{theorem}

\begin{proof}
Consider the same decomposition $G=G_1\cup \cdots \cup G_M$ of $\Omega$ such that
$$
|t -t'| \leq \epsilon \le M^{-1},\quad t, t'\in G_i.
$$
Let  $t_{i,j} \in G_i(1\leq j\leq n_i)$,  $n_i$ equal $\lceil \lambda(G_i)n\rceil$ and $\lfloor \lambda(G_i)n\rfloor$ with probabilities chosen to make its mean equal to $\lambda(G_i)n$ and $m_i=n_i + \mathbb{I}(n_i=0)$. Then
\begin{align}
\sum_{i=1}^M m_i&=\sum_{i=1}^M n_i\mathbb{I}(n_i>0) + \sum_{i=1}^M n_i\mathbb{I}(n_i=0)
\\
&\le \sum_{i=1}^M (n\lambda(G_i) + 1)\mathbb{I}(n_i>0) + \sum_{i=1}^M \mathbb{I}(n_i=0)
\\
&\le  n\sum_{i=1}^M \lambda(G_i)\mathbb{I}(n_i>0) + M
\le n+M.
\end{align}
Define $\displaystyle N=\sum_{i=1}^Mn_i$  and
$$
r_{n}(x)= {1\over N}\sum_{i=1}^M {n_i\over m_i} \sum_{j=1}^{m_i} g(x, t_{i,j}).
$$
By the definition of $m_i$, $\displaystyle {n_i\over m_i}=0$ or $1$.  This means that $r_{n}(x) $ is in the form of  $\displaystyle {1\over N}\sum_{i=1}^Ng(x,\theta_i)$.  Define
$$
\bar{r}_{n}(x)= \sum_{i=1}^M {n_i\over N}\mathbb{E}_{G_i}g.
$$
Since
$
\displaystyle r(x)=\mathbb{E}_G g= \sum_{i=1}^M \lambda(G_i) \mathbb{E}_{G_i}g,
$
\begin{align}
r_{n} - r  &= r_{n} - \bar{r}_{n} + \bar{r}_{n} - r
\\
&= {1\over N}\sum_{i=1}^M {n_i\over m_i} \sum_{j=1}^{m_i} \big (g(x,t_{i,j}) - \mathbb{E}_{G_i}g \big ) + {1\over N}\sum_{i=1}^M (n_i - \lambda(G_i)N)  \mathbb{E}_{G_i}g.
\end{align}
It follows that
\begin{align}
\|r_{n} - r \|_{L^2(\Omega)}^2 &
\le {1\over N^2}\sum_{i=1}^M {n_i\over m_i} \sum_{j=1}^{m_i} \|g(x,t_{i,j}) - \mathbb{E}_{G_i}g \|_{L^2(\Omega)}^2
+  {1\over N^2}\sum_{i=1}^M (n_i - \lambda(G_i)N)^2  \|\mathbb{E}_{G_i}g\|_{L^2(\Omega)}^2.
\end{align}
For the first term on the right-hand side of the above equation,
\begin{align}
{1\over N^2}\sum_{i=1}^M {n_i\over m_i} \sum_{j=1}^{m_i} \|g(x,t_{i,j}) - \mathbb{E}_{G_i}g \|_{L^2(\Omega)}^2
\le {|\Omega|\epsilon^2\over N^2}\sum_{i=1}^M n_i ={|\Omega|\epsilon^2\over N}.
\end{align}
Recall
$
g(x, t)= (x - t)_+^m {\rm sgn} s(zt,\omega),
$
which is bounded, say $|g(x, t)|\le C$. Note that $|n-N|\le M$. Thus,
\begin{align}
 {1\over N^2}\sum_{i=1}^M (n_i - \lambda(G_i)N)^2  \|\mathbb{E}_{G_i}g\|_{L^2(\Omega)}^2& \le {1 \over N^2}\sum_{i=1}^M  (M^2 + {1\over \lambda^2(G_i)}) \int_\Omega \int_{G_i} g^2(x, t)\lambda^2(t)dt d\mu(x)
\\
&\le  {C^2|\Omega|\over N^2}(M^2 +M)\le {\tilde C\over N^2}M^2.
\end{align}
It follows that
\begin{align}
\mathbb{E}_n \|r_{n} - r \|_{L^2(\Omega)}^2
\le {\epsilon^2 \over N} + {\tilde C\over N^2}M^2\label{stratify2t}.
\end{align}
Choose $\displaystyle {\epsilon^2 \over N} = {\tilde C\over N^2}M^2$, then $M^2\sim N\epsilon^2$ and
$$
\mathbb{E}_n \|r_{n} - r \|_{L^2(\Omega)}^2 \le {2\epsilon^2 \over N} \lesssim N^{-{3\over 2}}.
$$
There exist $\{t_{i,j}^\ast\}$ such that $t_{i,j}^\ast\in G_i$ and
\begin{equation}
\| f -  f_n \|_{L^2(\Omega)}\le {\nu\over m!}\|r_{n} - r\|_{L^2(\Omega)}\lesssim N^{-{3\over 4}}.
\end{equation}
which completes the proof.

\end{proof}

\hrule

\vspace{1cm}
If $x>0$,
\begin{equation}
\begin{aligned}
f(x) - \sum_{k\le m}{1\over k!}f^{(k)}(0) x^k &={1\over m!}\int_0^T f^{(m+1)}(t)(x-t)_+^mdt;
\end{aligned}
\end{equation}
If $x<0$, since $u_-=-(-u)_+$ ,
\begin{equation}
\begin{aligned}
f(x) - \sum_{k\le m}{1\over k!}f^{(k)}(0) x^k &=-{1\over m!}\int_0^{-x} f^{(m+1)}(-t)(x+t)^mdt
\\
&=-{1\over m!}\int_0^T f^{(m+1)}(-t)(x+t)_-^mdt
\\
&={(-1)^{m+1}\over m!}\int_0^T f^{(m+1)}(-t)(-x-t)_+^mdt
\end{aligned}
\end{equation}
This implies that
\begin{equation}
\begin{aligned}
f(x) - \sum_{k\le m}{1\over k!}f^{(k)}(0) x^k
&={1\over m!}\int_0^T f^{(m+1)}(t)(x-t)_+^m + (-1)^{m+1}f^{(m+1)}(-t)(-x-t)_+^mdt
\\
&={1\over m!}\int_{\{-1,1\}}\int_0^T z^{m+1}f^{(m+1)}(zt)(zx-t)_+^m dtdz
\\
&={1\over m!}\int_{\{-1,1\}}\int_0^T |f^{(m+1)}(zt)| s(z, t)(zx-t)_+^m dtdz
%\\
%&={1\over m!}\int_0^T |f^{(m+1)}(t)|s_1(t)(x-t)_+^m + |f^{(m+1)}(-t)|s_2(t)(-x-t)_+^mdt
\end{aligned}
\end{equation}
with $s(z, t)= z^{m+1}sgn (f^{(m+1)}(zt))$.
%with $s_1(t)=sgn (f^{(m+1)}(t))$ and $s_2(t)=sgn ((-1)^{m+1}f^{(m+1)}(-t))$.
It can be written as
\begin{equation}
\begin{aligned}
f(x) - \sum_{k\le m}{1\over k!}f^{(k)}(0) x^k &={\|f^{(m+1)}\|_{L^1}\over m!}\int_{[0,T]\times \{-1, 1\}}s(z,t)(zx-t)_+^m \lambda(z,t)dtdz
\end{aligned}
\end{equation}
where
\begin{equation}
\begin{aligned}
\lambda(z,t)={|f^{(m+1)}(zt)|\over \int_{[0,T]\times \{-1, 1\}} |f^{(m+1)}(zt)| dt dz}
\end{aligned}
\end{equation}
By Monte Carlo, there exist $t_j\in [0, T]$ and $\beta_j\in \{-1, 1\}$ such that
\begin{equation}
\begin{aligned}
\|f(x) - f_n(x)\|_{L^2} \le {1\over n^{1/2}}
\end{aligned}
\end{equation}
with
\begin{equation}
\begin{aligned}
f_n(x) = \sum_{k\le m}{1\over k!}f^{(k)}(0) x^k + {\|f^{(m+1)}\|_{L^1}\over m!n}\sum_{j=1}^n\beta_j (z_jx-t_j)_+^m
\end{aligned}
\end{equation}

\noindent\textbf{Higher dimension case from Taylor expansion}

The Taylor expansion reads
\begin{equation}
f(x)=f(0)+\sum_{1\le |\alpha| \leqslant k} \partial^\alpha f(0) x^{\alpha}+\sum_{|\alpha|=k+1} \frac{k+1}{\alpha !} x^{\alpha} \int_{0}^{1}(1-t)^{k} \partial^\alpha f(t x) \quad d t
\end{equation}
Let $y=tx$.
\begin{equation}
\begin{aligned}
x^{\alpha}(1-t)^{k} \partial^{\alpha} f(t x) d t &=(1-t)^{k} \partial^{\alpha} f(y) \prod_{i=1}^{N} x^{\alpha_{i}} d t\\
&=\partial^{\alpha} f(y) (1-t)^{k} \frac{y^{\alpha}}{t^{k+1}} d t \\
&=\partial^{\alpha} f(y)  \frac{1}{t} \prod_{i=1}^{N}\left(\frac{1}{t}-1\right)^{\alpha_{i}} y_{i}^{\alpha_{i}} d t \\
&=\partial^{\alpha} f(y)  \frac{1}{t} \prod_{i=1}^{N}\left(x_{i}-y_{i}\right)^{\alpha_{i}} d t \\
&=\partial^{\alpha} f(y)  (x-y)^{\alpha} \frac{1}{t} d t
\end{aligned}
\end{equation}
Thus
\begin{equation}
f(x)=f(0)+\sum_{1\le |\alpha| \leqslant k} \partial^\alpha f(0) x^{\alpha}+\sum_{|\alpha|=k+1} \frac{k+1}{\alpha !}  \int_{0}^{\infty} \partial^\alpha f(y) (x-y)_+^\alpha  d s
\end{equation}
with
\begin{equation}
(x-y)_{+}^{\alpha}=\left\{\begin{array}{ccc}
(x-y)^{\alpha} & \text { if }
y=sx,\ 0\le s \le 1
\\
0 &  \text { othemise }
\end{array}\right.
\end{equation}

\noindent\textbf{Higher dimension case from Taylor expansion 2}


\subsection{Sliding Window Technique} \label{sliding_window_technique}
Given is a continuous time series data stream $Q$. The last subsequence of size $w$ is in the interest of the sliding
window technique. All subsequences or time series data points of $Q$ that are back even further as the window size $w$
are in this moment irrelevant. The sliding window application tries to classify this last subsequence of $Q$ with the
help of a time series classificator. This time series classificator makes its decisions based on a given time series
training set. The application triggers an event in the case of a positive classification of the subsequence and an other
application can react on this event.

The sliding window application remains idle until the time series data stream $Q$
grows. Afterwards, the process is repeated again. However, the sliding window application waits until the time series
data stream $Q$ has grown by a predefined step size $s$. If necessary, this stepwise approach can avoid the execution of
the process continuously after every new data point in $Q$. Figure \ref{fig:swt} illustrates the described process.

\tikzstyle{decision} = [diamond, draw, aspect=2, fill=white!20, text width=8em, text badly centered, node distance=2cm, inner sep=0pt]
\tikzstyle{block} = [rectangle, draw, fill=white!20, text width=5em, text centered, minimum height=4em]
\tikzstyle{line} = [draw, -latex']

\begin{figure}
    \begin{center}
        \resizebox {\textwidth} {!} {
            {\tiny
                \begin{tikzpicture}[node distance = 1.5cm, auto]
                    \node [block] (sod) {sensors or devices};
                    \node [block, right of=sod, node distance=6cm, text width=2cm] (extract) {Extract last subsequence from Q of size $w$, $Q[t-w,t]$};
                    \node [block, right of=extract, node distance=4cm, text width=2cm] (nnc) {Time series classificator};
                    \node [decision, below of=nnc] (decide) {$Q[t-w,t]$ classifiable?};
                    \node [block, left of=decide, node distance=3cm] (sleeps) {Sleep for $s$ time};
                    \node [block, below of=decide, node distance=2cm, text width=2cm] (action) {Trigger event that $Q[t-w,t]$ has been classified and sleep for $w$ time};

                    \path [line,dashed] (sod) -- node (ctss) {Continuous time series stream $Q$} (extract);
                    \path [line] (extract) -- node {$Q[t-w,t]$} (nnc);
                    \path [line] (nnc) -- (decide);
                    \path [line] (decide) -- node {no} (sleeps);
                    \path [line,dashed] (sleeps) -| (ctss);
                    \path [line] (decide) -- node {yes} (action);
                    \path [line,dashed] (action) -| (ctss);
                \end{tikzpicture}
            }
        }
    \end{center}
    \caption{Possible design for a sliding window application. The current time is stored in variable $t$. The constant
    variables $w$ for the window size and $s$ for the step size are predefined.}
    \label{fig:swt}
\end{figure}

The explained sliding window technique uses a generic time series classificator. However, in this bachelor thesis the
generic time series classificator is replaced by 1NN-DTW. A time series window $Q[t-w,t]$ is classified as instance of
class $K_i$ by 1NN-DTW if the DTW distance between $Q[t-w,t]$ and the nearest neighbour passes a predefined
class threshold $\epsilon_i$. The following subsection gives some background of DTW.


% Project Specifications

\chapter{GEMM and $col2im$}

The previous chapter discussed different ways to view the convolution operation and its cousin,
the transposed convolution, both conceptually and implementationally. When it comes down to implementation,
we have seen that both operations can be implemented with a single matrix multiplication. In other words,
matrix multiplication is the main computational burden of these operations. Meanwhile, real world applications
often involve very large matrices. Therefore, as a low-level operation, the implementation of matrix
multiplication is often heavily optimized.

\gls{gemm} is considered as the \textit{de facto} standard operation
contained in the \gls{blas} specification. It has many implementations for
different platforms which exhaustively utilize various optimizations like \gls{simd} instructions,
parallelism, cache-awareness, etc.

\gls{gemm} is defined as

$$C \leftarrow \alpha op(A) op(B) + \beta C,$$

where $\alpha, \beta \in \mathbb{R}$, $op(X)$ is either $X$ or $X^\intercal$. In our particular case for
transposed convolution, $\alpha = 1$, $\beta = 0$, $op(X) = X$, so \gls{gemm} reduces to the basic
matrix multiplication $C \leftarrow A B$.

A subtle detail in the implementation of \gls{gemm} is the order of storage of matrix entries. There are two
different orders to store the same matrix: row-major order or column-major order. In row-major order,
entries of rows are stored contiguously in memory, while in column-major order, entries of columns are
consecutive to each other in memory.

A naïve C implementation of \gls{gemm} is shown in Listing \ref{code:naivegemm}. Here,
\mintinline{c}{lda}, \mintinline{c}{ldb} and \mintinline{c}{ldc} are
the leading dimensions of matrix $A$, $B$ and $C$, respectively.

\begin{code}
\begin{minted}{c}
for (int i = 0; i < m; i++) {
    for (int j = 0; j < n; j++) {
        float sum = 0;
        for (int l = 0; l < k; l++)
          sum += a[l*lda+i] * b[l*ldb+j];
        c[j*ldc+i] = beta * c[j*ldc+i] + alpha * sum;
    }
}
\end{minted}
  \captionof{listing}{Naïve C Implementation of \gls{gemm}}
\label{code:naivegemm}
\end{code}

This implementation is straightforward and not very efficient, but it is a good starting point to guide
us through the rest of the design.

Another operation used by transposed convolution is $col2im$. It cherry picks the elements computed by
\gls{gemm} and places them in the destination image. To describe $col2im$, it is necessary to introduce
the variables used for transposed convolution.

\begin{itemize}
  \item \mintinline{c}{inputHeight} and \mintinline{c}{inputWidth} are the height and width of each input
    channel (sometimes also called input plane)
  \item \mintinline{c}{nInputChannel} is the number of input channels in total, thus the input is a
    $3D$ tensor with dimensions \mintinline{c}{(nInputChannel, inputHeight, inputWidth)}
  \item With \mintinline{c}{m = inputHeight * inputWidth} and \mintinline{c}{k = nInputChannel}, the input
    tensor is stored as a matrix $A \in \mathbb{R}^{m \times k}$
  \item \mintinline{c}{kernelH} and \mintinline{c}{kernelW} are the height and width of each kernel channel
  \item Each kernel is also a $3D$ tensor with dimensions \mintinline{c}{(nInputChannel, kernelH, kernelW)}
  \item \mintinline{c}{nOutputChannel} is the number of output channels
  \item There are \mintinline{c}{nOutputChannel}'s of kernels, each responsible for producing an output channel
  \item With \mintinline{c}{k = nInputChannel} and \mintinline{c}{n = nOutputChannel * kernelH * kernelW},
    the kernel tensor is stored as a matrix $B \in \mathbb{R}^{k \times n}$
\end{itemize}

The code of $col2im$ is given in listing \ref{code:col2im}:

\begin{code}
\begin{minted}{c}
// content of data_im set to 0 already
const int n = nOutputChannel * kernelH * kernelW;
for (int j = 0; j < n; ++j) {
    int w_offset = j % kernelW;
    int h_offset = (j / kernelW) % kernelH;
    int c_im = j / kernelH / kernelW;
    for (int h_col = 0; h_col < inputHeight; ++h_col) {
        for (int w_col = 0; w_col < inputWidth; ++w_col) {
            int h_im = h_col * strideH - padH + h_offset * dilationH;
            int w_im = w_col * strideW - padW + w_offset * dilationW;
            if (h_im >= 0 && h_im < outputHeight &&
                w_im >= 0 && w_im < outputWidth) {
                data_im[(c_im * outputHeight + h_im) * outputWidth + w_im] +=
                    data_col[(j * inputHeight + h_col) * inputWidth + w_col];
            }
        }
    }
}
\end{minted}
\captionof{listing}{C Implementation of $col2im$}
\label{code:col2im}
\end{code}

Here \mintinline{c}{data_im} is the target image while \mintinline{c}{data_col} is the result of \gls{gemm}, namely, \mintinline{c}{c} in listing \ref{code:naivegemm}.
The outermost loop iterates through the columns of $C \in \mathbb{R}^{m \times n}$. The two nested loops
iterate the rows of $C$, since \mintinline{c}{m = inputHeight * inputWidth}. \mintinline{c}{c_im} is the
index of the channel in the output image. %\mintinline{c}{h_offset} and \mintinline{c}{w_offset} are the offset in each

For transposed convolution, \mintinline{c}{data_im} is typically smaller than
\mintinline{c}{data_col}. This leads to a key optimization idea: it is possible to merge \gls{gemm} and
$col2im$ together and compute transposed convolution by doing \gls{gemm} sparsely. In doing so,
\mintinline{c}{data_col} can be abandoned and the results will be directly placed in \mintinline{c}{data_im},
that is, there is no need for an extra large buffer for intermediate results.

\begin{code}
\begin{minted}{c}
int j = 0;
for (int c_im = 0; c_im < nOutputChannel; c_im++) {
    for (int h_offset = 0; h_offset < kernelH; h_offset++) {
        for (int w_offset = 0; w_offset < kernelW; w_offset++) {
            int i = 0;
            for (long h_col = 0; h_col < inputHeight; h_col++) {
                for (long w_col = 0; w_col < inputWidth; w_col++) {
                    int h_im = h_col * strideH - padH + h_offset * dilationH;
                    int w_im = w_col * strideW - padW + w_offset * dilationW;
                    if (h_im >= 0 && h_im < outputHeight &&
                        w_im >= 0 && w_im < outputWidth) {
                        float sum = 0;
                        for (long l = 0; l < k; l++)
                            sum += a[l*lda + i] * b[l*ldb + j];
                        int idx = (c_im * outputHeight + h_im) *
                                  outputWidth + w_im;
                        data_im[idx] += sum;
                    }
                    i++;
                }
            }
            j++;
        }
    }
}
\end{minted}
\captionof{listing}{C Implementation of $transposed\_convolution$}
\label{code:transposed_convolution_in_c}
\end{code}

The key to understand this code of merge is to notice that the for-loop indexed by \mintinline{c}{j} in
\mintinline{c}{gemm} can be split into three nested for-loops indexed by \mintinline{c}{c_im},
\mintinline{c}{h_offset} and \mintinline{c}{w_offset}.
Similarly, the for-loop indexed by \mintinline{c}{i} in \mintinline{c}{gemm} is equivalent to the two
nested for-loops indexed by \mintinline{c}{h_col} and \mintinline{c}{w_col}, same as in \mintinline{c}{col2im}.

This last C code in listing \ref{code:transposed_convolution_in_c} serves as the blueprint for implementing
transposed convolution on \gls{fpga} with Verilog. It can be seen from the code listing
that the output channels can be computed in groups or even by each channel individually.
This is a convenient fact when the weights of a layer cannot be fit into the
\gls{bram} on the \gls{fpga} chip all at once.

\clearpage %force the next chapter to start on a new page. Keep that as the last line of your chapter!


% numerikk.tex
% Part of VertEgg documentation
%

\chapter{Numerical Methods}

The numerical solutions are computed on a fixed equidistant grid.  The
number of grid cells is denoted $N$ and the cell height is $\Delta
z$. The grid is staggered as shown in fig.~\ref{fig:grid}.  The
$z$-axis points upwards.

The cell interfaces, the \emph{flux points}\index{flux points}, are
\begin{equation}\label{eq:flushpt}
  z_i = (1-i) \Dz \quad \text{for} \quad i = 1, \dots, N+1 .
\end{equation}
The cell centers, the \emph{concentration points}\index{concentration
points} or the \emphi{egg points}, are
\begin{equation}\label{eq:eggpt}
  \bar{z}_i = \frac{z_i + z_{i+1}}{2} = (\half-i) \Dz
            \quad \text{for} \quad i = 1, \dots, N .
\end{equation}

\begin{figure}[h]
\begin{center}
\setlength{\unitlength}{1mm}
\begin{picture}(65,20)
  \multiput(10.0, 8.5)(20,0){3}{\line(0, 1){3}}
  \put(20.0,10.0){\makebox(0,0){$\times$}}
  \put(40.0,10.0){\makebox(0,0){$\times$}}
  \put(10.0, 6.0){\makebox(0,0){$z_{i+1}$}}
  \put(30.0, 6.0){\makebox(0,0){$z_{i}$}}
  \put(50.0, 6.0){\makebox(0,0){$z_{i-1}$}}
  \put(20.0, 6.0){\makebox(0,0){$\bar{z}_{i}$}}
  \put(40.0, 6.0){\makebox(0,0){$\bar{z}_{i-1}$}}
  \put(10.0,14.0){\makebox(0,0){$F_{i+1}$}}
  \put(30.0,14.0){\makebox(0,0){$F_{i}$}}
  \put(50.0,14.0){\makebox(0,0){$F_{i-1}$}}
  \put(20.0,14.0){\makebox(0,0){$\phi_{i}$}}
  \put(40.0,14.0){\makebox(0,0){$\phi_{i-1}$}}
  \put(0,10){\vector(1,0){60}}
\end{picture}
\end{center}
\caption{Horizontal view of the vertical grid}\label{fig:grid}
\end{figure}

The variables are discretized in the following ways. The egg
concentration $\phi_i$ represents the mean concentration in
cell $i$, that is
\begin{equation}\label{eq:cellav}
  \phi_i \Dz = \int_{z_{i+1}}^{z_i} \!\phi(z)\,dz,
                 \quad i = 1, \dots ,N .
\end{equation}
The $\phi_i$ values may be considered living on the egg points
$\bar{z}_i$ as in fig.~\ref{fig:grid}. As the flux values are computed
from the vertical velocity and the eddy diffusivity,
$F_i$, $w_i$ and $K_i$ are taken as point values on the flux points
$z_i$ for $i = 1, \dots, N+1$. The source terms $P_i$ and $\alpha_i$
are cell averages and live on the egg points.

\section{The Transient Problem}\label{sec:numtrans}

The numerical solution of the convection-diffusion
equation~(\ref{eq:difflaw}) are covered by several authors.  A classic
source is Roache \shortcite{roac72}. A newer source is chapter 9 in
the book by Fletcher \shortcite{flet91}. Recently a whole book, edited
by Vreugdenhil and Koren \shortcite{vreu93}, has been devoted to this
equation.  For conservative methods, as will be used here, the book by
LeVeque \shortcite{leve92} is also recommended.

For our problem, convection and diffusion of concentration of fish
eggs, some properties of the numerical method is important.  Fish eggs
are usually found in a subrange of the water column with values close
to zero outside this range. And of course a real concentration do not
have negative values.  The method must therefore be
\emph{positive}, that is it must not create
any negative values.

In the absence of source and sink terms, eggs are not created or
destroyed. The vertical integrated concentration is therefore constant
in time as shown in section~\ref{sec:vertint}.  The numerical method
should have the same property, it should be \emph{mass
conserving}\index{mass conserving method}.

Of course the numerical solution should be as close as possible to the
real solution. That is the \emph{accuracy} of the method should be
good. This concept includes low artificial diffusion and no or very
limited wiggles development.

A convection -- diffusion problem is characterised by the following
non-dimensional numbers, all defined at the interior flux points,
$z_i$ for $i = 2, \dots, N$.
\begin{align}
  & \text{Courant number}         & c_i & = w_i\frac{\Dt}{\Dz} \\
  & \text{Diffusive parameter}    & s_i & = K_i \frac{\Dt}{\Dz^2} \\
  & \text{Cell Peclet number}     & \Pcell_i & =
       \frac{\abs{w_i} \Dz}{K} = \frac{\abs{c_i}}{s_i}
\end{align}
\index{Courant number}\index{diffusive parameter}\index{cell Peclet number}
If the coefficients $w$ and $K$
are constant, the subscripts are simply dropped.

For fish eggs, the terminal velocity is in the order of a couple of
millimetres per second. The velocity can be positive (\emph{pelagic}
eggs)\index{pelagic eggs}, negative (\emph{benthic})\index{benthic
eggs} or change sign some place in the water column
(\emph{mesopelagic})\index{mesopelagic eggs}. The vertical eddy
diffusion show a very large range of variation, from more than
$10^{-2}$ \sqmps\ in the upper mixing layer to $10^{-5} \sqmps$
in the pycnocline layer.  With a grid size of the
order of one meter, the Cell Peclet number $\Pcell$ take values from
$10^{-1}$ to $10^2$. This means that the process may be dominated by
diffusion in the upper layer and convection below.

The numerical methods considered here are \emph{finite difference} or
really \emph{finite volume} schemes given in \emph{conservation
form}\index{conservation form} (or \emph{flux
formulation}\index{flux formulation}).  These methods are
conceptually natural, working directly with the integral form of the
conservation law~(\ref{eq:intlaw}).  More precisely, the
equation~(\ref{eq:intlaw}) is approximated by
\begin{equation}\label{eq:numlaw}
  (\phi_i^{n+1} - \phi_i^n) \Dz =
           (F_{i+1}^n - F_i^n) \Dt + Q_i^n \Dz \Dt ,
           \quad i = 2, \dots, N
\end{equation}
where the superscripts indicate the time step.
The boundary conditions (\ref{eq:boundcond}) simply become
$F_1 = F_{N+1} = 0$. The various methods
differ in their estimation of the total flux function $F_i = \Fconv_i
+ \Fdiff_i$ and the source term $Q_i$.  One advantage of this flux
formulation is that mass conservation is automatically fulfilled, as
the fluxes cancel out during vertical integration.

Without source term the total concentration is conserved. Therefore
the local concentration values can not become arbitrary large, unless
there are negative values in some other cells. In other words,
positivity is a sufficient (but not necessary) condition for stability
of such schemes.

In the following several methods are described.  They are implemented in
the toolbox as \edbi{ftcs}, \edbi{lwendrof}, \edbi{upstream},
\edbi{posmet}, and \edbi{minlim} respectively. Their performance
will be studied in the example section~\ref{sec:sens}. Several methods
for the same problem causes a new problem, which method to choose. This
depends on the range of $\Pcell$ values in the problem. A general
advice is to try Lax-Wendroff first. This is an accurate and fast method
when applicable. If oscillations occur, go for the flux-limited
methods or use higher spatial resolution.  In both cases more computing
time is required.

\subsection{Linear conservative schemes}\label{seq:linsch}

The linear conservative schemes considered here estimates the total
flux function in the form
\begin{equation}\label{eq:alphabeta}
  F_i = \alpha_i \phi_i + \beta_i \phi_{i-1} ,
\end{equation}
where the $\alpha_i$-s and $\beta_i$-s are independent of
the $\phi_i$-s. Sometimes this will be used in non-dimensional form
\begin{equation}\label{eq:ab}
  F_i = \frac{\Dz}{\Dt} (a_i \phi_i + b_i \phi_{i-1}) .
\end{equation}
Some general theory for this kind of numerical schemes is presented
in Appendix~\ref{app:lincons}

\subsubsection{The FTCS scheme}\index{FTCS scheme}

The simplest scheme is often called FTCS (forward time central space)
after the differencing. This scheme is described for instance in
chapter 9.4 in \cite{flet91}. Here both flux
components are centred around $z = z_i$,
\begin{equation}
  \Fconv_i = w_i \frac{\phi_{i-1} + \phi_i}{2}
\end{equation}
\begin{equation}\label{eq:centdifflux}
  \Fdiff_i = - K_i \frac{\phi_{i-1} - \phi_i}{\Dz} .
\end{equation}
In the notation of equation (\ref{eq:alphabeta}) the method is given by
\begin{equation}
   \alpha_i = \frac{1}{2} w_i + \frac{K_i}{\Dz} , \quad
   \beta_i  = \frac{1}{2} w_i - \frac{K_i}{\Dz} ,
\end{equation}
and non-dimensionalised by
\begin{equation}
   a_i = \frac{1}{2} c_i + s_i , \quad
   b_i = \frac{1}{2} c_i - s_i .
\end{equation}

The following positivity condition for the FTCS scheme follows from
the general condition in Appendix~\ref{app:pos}.
\begin{gather}
     \abs{c_i} \le 2 s_i,  \quad i = 2, \dots, N \\
      s_2 \le 1 + \half c_2 \\
  s_i + s_{i+1} \le 1 + \half (c_i - c_{i+1}), \quad i = 2, \dots, N-1 \\
      s_N \le 1 - \half c_N
\end{gather}
The first condition can be restated as $\Pcell \le 2$.

With constant coefficients, the positivity conditions reduce to
\begin{equation}
  \abs{c} \le 2 s \le 1,
\end{equation}
which is stronger than the stability condition
\begin{equation}
  c^2 \le 2 s \le 1 .
\end{equation}

The numerical ``diffusion'' is negative,
\begin{equation}
  K_{num} = - \half w^2 \Dt
\end{equation}
which is negligible if $c^2 \ll 2s$.

This method is implemented in the toolbox as the function \edbi{ftcs}.

\subsubsection{The Lax-Wendroff Scheme}\index{Lax-Wendroff scheme}

An alternative is the Lax-Wendroff scheme as analysed for instance in
\cite{vreu93b}. The scheme compensates for the negative numerical
``diffusion'' in FTCS.  The diffusive flux is still given by
equation~(\ref{eq:centdifflux}) but the convective flux is modified
\begin{equation}\label{eq:lwflux}
  \Fconv_i = w_i \frac{\phi_{i-1} + \phi_i}{2}
      - \half w_i^2 \frac{\Dt}{\Dz}
       (\phi_{i-1} -\phi_i) .
\end{equation}
In the notation of equation (\ref{eq:alphabeta}) the Lax-Wendroff
method is given by
\begin{equation}
   \alpha_i = \frac{1}{2} w_i(1+w_i\frac{\Dt}{\Dz}) + \frac{K_i}{\Dz} , \quad
   \beta_i  = \frac{1}{2} w_i(1-w_i\frac{\Dt}{\Dz}) - \frac{K_i}{\Dz} ,
\end{equation}
and non-dimensionalised by
\begin{equation}
   a_i = \frac{1}{2} c_i(1+c_i) + s_i , \quad
   b_i = \frac{1}{2} c_i(1-c_i) - s_i .
\end{equation}

From Appendix~\ref{app:pos} the conditions for positivity are
\begin{gather}
     \abs{c_i} \le 2 s_i + c_i^2,  \quad i = 2, \dots, N \\
     s_i + s_{i+1} \le 1 + \half (c_i - c_{i+1}) - \half(c_i^2 + c_{i+1}^2),
               \quad i = 2, \dots, N-1.
\end{gather}
The first condition can be restated as
\begin{equation}\label{eq:lwpcell}
    \Pcell \le \frac{2}{1-\abs{c_i}} .
\end{equation}

With constant coefficients, the positivity
conditions reduce to
\begin{equation}
 \abs{c} \le c^2 + 2 s \le 1,
\end{equation}
which is stronger than the stability condition
\begin{equation}
  c^2 + 2 s \le 1 .
\end{equation}

There is no second order numerical diffusion in the transient
solution.  Wiggles will not occur if the positivity
condition~(\ref{eq:lwpcell}) is fulfilled.
This method is implemented in the toolbox as the function \edbi{lwendrof}.

\subsubsection{The Upstream Scheme}\index{upstream scheme}

A non-centred alternative is the upstream method.  This is the method
used by West\-g{\aa}rd \shortcite{west89}.  The upstream scheme is
studied in all books on the subject.  The same diffusive flux
(\ref{eq:centdifflux}) is used but the convective flux is estimated on
the inflow side.
\begin{equation}\label{eq:usflux}
  \Fconv_i = w_i^+ \phi_i + w_i^- \phi_{i-1}
\end{equation}
where
\begin{equation}
   x^+ = \half (x + |x|) =
       \begin{cases}
          x& \text{if $x \ge 0$},\\
          0& \text{if $x  < 0$}.
       \end{cases}
\end{equation}
and $x^- = x - x^+$.
In the notation of equation (\ref{eq:alphabeta}) the method is given by
\begin{equation}
   \alpha_i =  w_i^+ + \frac{K_i}{\Dz} , \quad
   \beta_i  =  w_i^- - \frac{K_i}{\Dz} ,
\end{equation}
and non-dimensionalised by
\begin{equation}
   a_i = c_i^+ + s_i , \quad
   b_i = c_i^- - s_i .
\end{equation}

From Appendix~\ref{app:pos} the positivity condition is simply
\begin{equation}\label{eq:uspos}
  c_i^+ - c_{i+1}^- + s_i + s_{i+1} \le 1 .
\end{equation}
With constant coefficients this reduces to
\begin{equation}
  \abs{c} + 2 s \le 1 .
\end{equation}
which is also the stability condition.

The numerical diffusion in the upstream scheme may be quite large
\begin{equation}
  K_{num} = \half w \Dz (1-\abs{c})
\end{equation}
This is negligible if $K_{num} \ll K$, or equivalently
\begin{equation}
  \Pcell \ll \frac{2}{1 - \abs{c}} .
\end{equation}

The upstream scheme is implemented in the toolbox as the function
\edbi{upstream}.

\subsection{Nonlinear methods}\label{sec:nonlin}\index{non
linear method}

The Lax-Wendroff scheme is second order in space but may develop
wiggles and negative concentration values. The upstream method is
positive but may be too diffusive. These are fundamental problems with
linear schemes.  Several nonlinear schemes has been developed to
overcome these problems.  A general idea is to combine the
Lax-Wendroff and upstream methods to produce positive schemes with low
numerical diffusion. Overviews of such methods are given by LeVeque
\shortcite{leve92} and in the collection \citep{vreu93}.

Egg distribution problems are somewhat non-symmetrical. It is
important to have high accuracy near maxima where most of the eggs are
found. Local minima are less interesting and they occur more seldom in
the interior of the water column. For instance, with the steady state
solution (\ref{eq:sstatesol}) without source terms, a local minimum in
the interior can occur only in static instable situations when the egg
is lighter than the water above and heavier saline than the water
below.

The methods below are not total variation diminishing (TVD) as some of
the more advanced non-linear methods.  Instead of a finely tuned
linear combination, the schemes use simple on/off mechanisms to switch
between the Lax-Wendroff and upstream fluxes.  On the other hand, the
asymmetry above is exploited. The schemes have high accuracy at maxima
because the unmodified Lax-Wendroff flux is used in this situation.

\subsubsection{The positive method}\index{positive scheme}

This is a simple scheme, mostly using the Lax-Wendroff
fluxes but limiting to the upstream fluxes where Lax-Wendroff produces
negative concentration values. The algorithm consists of three steps,
\begin{enumerate}
\item Compute the Lax-Wendroff fluxes including diffusivity by
   formul{\ae} (\ref{eq:lwflux}) and (\ref{eq:centdifflux}).
\item Apply the fluxes to compute a test distribution
\begin{displaymath}
  \phi_i^{test} = \phi_i - \frac{\Dt}{\Dz}(F_i - F_{i+1}) .
\end{displaymath}
\item Where $\phi_i^{test} < 0$, recompute $F_i$ and $F_{i-1}$ by the
  upstream formulation (\ref{eq:usflux}) and diffusion (\ref{eq:centdifflux}).
\end{enumerate}

Positivity of the upstream scheme or Lax-Wendroff scheme implies
positivity of the flux limited scheme. The positivity
condition~(\ref{eq:uspos}) is therefore a sufficient (but not
necessary) condition for positivity of the combined scheme.

The scheme is implemented in the toolbox as the function \edbi{posmet}.

\subsubsection{The minimum limiting method}
\index{minimum limiting scheme}

Although the method above is positive, it may create wiggles around a
positive value.  To improve on this situation a slight variant is
proposed.  The new criteria for switching from Lax-Wendroff to
upstream flux is the occurrence of a local minimum.  As the first
negative value must be a local minimum prevents the method from
creating negative values (if the upstream scheme is stable).

Steps 1 and 2 in the algorithm are identical to the positive scheme.
The third step is modified to
\begin{quote}
  3'. Where $\phi_i^{test} < \min (\phi_{i-1}^{test},\phi_{i+1}^{test})$,
      recompute $F_i$ and $F_{i-1}$ by the
      upstream formulation (\ref{eq:usflux}) and diffusion
      (\ref{eq:centdifflux}).
\end{quote}

This scheme is implemented in the toolbox as the function \edbi{minlim}.

\subsection{The Source Term}

Neglecting the fluxes for the moment, the transport equation
\pref{eq:difflawfull} reduces to an ordinary differential equation
\begin{equation}\label{eq:noflux}
  \Od{\phi}{t} = P - \alpha \phi .
\end{equation}
The numerical scheme \pref{eq:numlaw} reduces to
\begin{equation}\label{eq:numnoflux}
  \phi_i^{n+1} - \phi_i^n = Q_i^n \Dt .
\end{equation}
The exact solution of (\ref{eq:noflux}) with
constant coefficients is
\begin{equation}
  \phi^{n+1} = \e^{-\alpha \Dt} \phi^n +
                 (1 - \e^{- \alpha \Dt}) \frac{P}{\alpha} .
\end{equation}
This is in the form \pref{eq:numnoflux} with
\begin{equation}\label{eq:kildediskret}
  Q_i = (P_i - \alpha_i \phi_i)
         \frac{1-\e^{- \alpha_i \Dt}}{\alpha_i \Dt} .
\end{equation}
This scheme will never produce negative concentration values.

Combining this with the convection-diffusion solvers above is
straightforward. The combined positivity condition becomes more
restrictive as discussed in Appendix~\ref{app:posloss}.
In general the number $1$ appearing as upper limit must be replaced
by $\exp(-\alpha \Dt)$.  For instance, with constant coefficients
the positivity conditions for the familiar linear schemes become
\begin{align}
  & \text{FTCS}         & \abs{c} \le 2 s & \le \e^{-\alpha \Dt} , \\
  & \text{Lax-Wendroff} & c^2 + 2 s       & \le \e^{-\alpha \Dt} , \\
  & \text{Upstream}     &  \abs{c} + 2 s  & \le \e^{-\alpha \Dt} .
\end{align}

\section{The Stationary Problem}\label{sec:statprob}

In many problems only the steady state solution is needed.  Also for
transient problems, a fast and accurate way of reaching the stationary
solution is of interest.

If the coefficients $w$ and $K$ are constant, the exact
solution~(\ref{eq:eggsact}) can be used directly. With negative
velocity and low diffusivity, $m = w/K \ll 0$, the formula may overflow.  This
can be avoided by using the symmetry relation~(\ref{eq:symmetry}) for
negative $m$.  This solution is computed by the function \edbi{eggsact}
in the toolbox. For the discretized solution to have the correct
vertical integral and be comparable to the numerical solutions, cell
averages
\begin{equation}
  \phi_i = \frac{\Phi}{\Dz}
           \frac{\e^{m z_i} - \e^{m z_{i+1}}}{1 - \e^{-mH}}
\end{equation}
are better. This is also computed by \edbi{eggsact}.

General $w$ and $K$ can be regarded as constant on the grid cells.
Suppose $w$ and $K$ and their quotient $m$ live on the flux points as
in the transient problem. Form the cell average $\bar{m}_i = (m_i +
m_{i+1}) / 2$. The cell averaged solution becomes
\begin{equation}
  \bar{\phi}_i =
     \frac{C_i}{\Dz}
     \frac{\e^{\bar{m}_i z_i} - \e^{\bar{m}_i z_{i+1}}}{\bar{m}_i}
\end{equation}
where the $C_i$-s are computed by continuity
\begin{equation}
  \phi_i(z_i) = \phi_i(z_{i+1})
\end{equation}
and vertical integral
\begin{equation}
  \Dz \sum_{i = 1}^N \bar{\phi_i} = \Phi
\end{equation}
With low mixing and high sinking velocity the exponential terms may
overflow. The computation of the $C_i$-terms may overflow.  The last
problem is overcome by working with the logarithms. For the first
problem the $C_i$-terms are renormalised by finding a suitable value for
$C_1$. The method is implemented in the toolbox as the function
\edbi{sstate}.

%\section{Particle Methods}


\documentclass[12pt]{article}
\usepackage[]{algorithm2e}
\usepackage{amssymb}
\usepackage{amsmath}
\usepackage[hyphens]{url}
\usepackage{listings}
\usepackage{xcolor}

\definecolor{listinggray}{gray}{0.9}
\definecolor{lbcolor}{rgb}{0.9,0.9,0.9}
\lstset{
	backgroundcolor=\color{lbcolor},
	tabsize=4,
	language=C++,
	captionpos=b,
	tabsize=3,
	frame=lines,
	numbers=left,
	numberstyle=\tiny,
	numbersep=5pt,
	breaklines=true,
	showstringspaces=false,
	basicstyle=\footnotesize,
	%  identifierstyle=\color{magenta},
	keywordstyle=\color[rgb]{0,0,1},
	commentstyle=\color{Darkgreen},
	stringstyle=\color{red}
}

\begin{document}

\title{Project 03 CS-790}
\author{Brandon Bluemner}
\date{2017}
\maketitle
% ================================================
% Abstract
% ================================================
\begin{abstract}
Algorithmic approach to the Matrix Shifting Puzzle
\end{abstract}

% =================================================
% Overview
% =================================================
\section{Overview}
\subsection{Matrix shifting Puzzle}
Let $M$ be an $n \times n$ array of numbers 1 through $n^2$,
each move $rotate(row,p)$ or $rotate(col,p)$ cost p s.t. $p \in [0...n-1]$
rotate would yield two options, rotate left or rotate right, which will
have an impact on the out come of the algorithm. The objective is to find
the minimum cost from start state $\Rightarrow$ goal state.
\section{Implementation}
% =================================================
% Heuristic function
% =================================================
\subsection{Heuristic function}
The code implements a relative distance.
Trying to find the approximate distance to gaol.
This is done by finding the distance from the two points of the grid
start at $(current_x,current_y) \rightarrow (goal_x,goal_y)$.
The sum absolute value of the difference with respect to the partials is
the used to get the current value. (see Figure \ref{fig:h_func})
\begin{figure}
\begin{lstlisting}
	int cost = 0;
	int temp[2]={0,0};
	for(int i=0; i < current.size(); i++ ){
		for(int j=0; j< current.at(i).size(); j++ ){
			get_goal_position(current[i][j], goal, temp);
			int dx = temp[0]-i;
			int dy = temp[1]-j;
			cost += std::abs(dx) +  std::abs(dy);
		}
	}
	return cost;
\end{lstlisting}
\caption{Heuristic function}
\label{fig:h_func}
\end{figure}

Anther attempt was made on the same code base with the following
change to line 8 of Figure \ref{fig:h_func} as shown in Figure \ref{fig:h_func_1}
\begin{figure}
\begin{lstlisting}
			cost +=  ((int) (std::sqrt( dx*dx + dy*dy )))

\end{lstlisting}
\caption{Heuristic function Change}
\label{fig:h_func_1}
\end{figure}
This yield a worst result and significate performance impact, which if you consider
the math abs can be simplified by using a bit ``hack'' (see Figure \ref{fig:bit_twiddle}) which
can eliminate computational steps compared to takeing the square root.
\begin{figure}
	\begin{lstlisting}
	int my_abs(int x)
	{
		int s = x >> 31;
		return (x ^ s) - s;
	}
	\end{lstlisting}
	\caption{Example abs implementation}
	\label{fig:bit_twiddle}
\end{figure}
% =================================================
% Hashing function
% =================================================
\subsection{Hashing}
A problem that arises with any Implementation of a board state
game is how to represent a state with the minimum amount of data.
One solution is Hashing or using a number or string to represent a state.
This Implementation uses a custom hashing method based off of Zobrist
Hashing \cite{Zobrist}used in chess like board games. This hash code is
used to prevent recalculation of the Heuristic function an getting into
a cycle in the algorithm.
\begin{figure}
\begin{lstlisting}
long long int get_hash_value(std::vector<std::vector<int>> &matrix){
	long long int result =0;
	for(int i=0; i< matrix.size();i++){
		for(int j=0; j<matrix[i].size(); j++){
			auto row = (long long int)  ( (i+1) * std::pow(10, (matrix.size()-1 ) *2));
			auto col = (long long int)  ( (j+1) * std::pow(10,matrix.size()-1));
			long long int temp  = row +  col+ matrix[i][j];
			std::hash<long long int> hasher;
			auto _hash  = hasher(temp) ;
			result ^=  _hash +  0x9e3779b9   + (result<<6) + (result>>2);
		}
	}
\end{lstlisting}
	\caption{Hashing Code segment}
	\label{fig:Hashing}
\end{figure}
% =================================================
% Search Algorithm function
% =================================================
\subsection{Algorithm}
The algorithm used in this project was a modified version of $A*$.
Some major changes are the Implementation of hashing to improve the
running time by eliminating checks when nodes are in
the frontier or explored section the hashing function gets cached on
the cpu and ram thus causing a moderate speed gain.
% =================================================
% Result
% =================================================
\section{Results}
The ``Path size'' will represent the transition between each state
the ``Cost'' is the cost of the transition state not including the Heuristic function weight.
\\
\subsection{2x2 matrix}
Starting position:
\begin{tabular}{ l }
	04 03 \\
	02 01
\end{tabular}
$\Rightarrow$
Goal:
\begin{tabular}{ l }
	01 02 \\
	03 04
\end{tabular}
\\
The results below are from a $\times5$ run on the PC(see \ref{PC}) with a 1000000 $CLOCKS PER SEC$
\\
\begin{tabular}{ | l | l | l | l | l | l | l | }
\hline
Run  & Path Size & Cost & Running Time Alg & Cpu Start & Cpu End & Total cpu time\\\hline
1 & 4 & 4 & 0.00037s & 15625 & 15625 & 0s\\\hline
2 & 4 & 4 & 0.00037s & 15625 & 15625 & 0s\\\hline
3 & 4 & 4 & 0.0003685s & 15625 & 15625 & 0s\\\hline
4 & 4 & 4 & 0.0002143s & 15625 & 15625 & 0s\\\hline
5 & 4 & 4 & 0.0002142s & 15625 & 15625 & 0s\\\hline
\end{tabular}
\\
The results below are from a $\times5$ run on Server(see \ref{Server}) with a 1000000 $CLOCKS PER SEC$
\\
\begin{tabular}{ | l | l | l | l | l | l | l | }
\hline
Run  & Path Size & Cost & Running Time Alg & Cpu Start & Cpu End & Total cpu time\\\hline
1 & 4 & 4 & 0.000589516s & 12088 & 12672 & 0.000584s\\\hline
2 & 4 & 4 & 0.000521357s & 10037 & 10553 & 0.000516s\\\hline
3 & 4 & 4 & 0.000623622s & 10185 & 10807 & 0.000622s\\\hline
4 & 4 & 4 & 0.000544579s & 9955 & 10497 & 0.000542s\\\hline
5 & 4 & 4 & 0.000579305s & 9709 & 10286 & 0.000577s\\\hline
\end{tabular}
\subsection{3x3 matrix}
Starting position:
\begin{tabular}{ l }
09 08 07 \\
06 05 04 \\
03 02 01
\end{tabular}
$\Rightarrow$
Goal:
\begin{tabular}{ l }
	01 02 03 \\
 	04 05 06 \\
 	07 08 09
\end{tabular}
\\
The results below are from a $\times5$ run on the PC(see \ref{PC}) with a 1000000 $CLOCKS PER SEC$
\\
\begin{tabular}{ | l | l | l | l | l | l | l | }
\hline
Run  & Path Size & Cost & Running Time Alg & Cpu Start & Cpu End & Total cpu time\\\hline
1 & 34 & 34 & 0.0771355s & 31250 & 109375 & 0.078125s\\\hline
2 & 34 & 34 & 0.0402095s & 15625 & 46875 & 0.03125s\\\hline
3 & 34 & 34 & 0.0326797s & 0 & 31250 & 0.03125s\\\hline
4 & 34 & 34 & 0.0325114s & 0 & 31250 & 0.03125s\\\hline
5 & 34 & 34 & 0.0324343s & 0 & 31250 & 0.03125s\\\hline
\end{tabular}
\\
The results below are from a $\times5$ run on Server(see \ref{Server}) with a 1000000 $CLOCKS PER SEC$
\\
\begin{tabular}{ | l | l | l | l | l | l | l | }
\hline
Run  & Path Size & Cost & Running Time Alg & Cpu Start & Cpu End & Total cpu time\\\hline
1 & 34 & 34 & 0.08514s & 12444 & 97607 & 0.085163s\\\hline
2 & 34 & 34 & 0.0843959s & 11669 & 96036 & 0.084367s\\\hline
3 & 34 & 34 & 0.0852655s & 11209 & 96469 & 0.08526s\\\hline
4 & 34 & 34 & 0.0837059s & 11251 & 94951 & 0.0837s\\\hline
5 & 34 & 34 & 0.0835822s & 10498 & 94075 & 0.083577s\\\hline
\end{tabular}

\subsection{4x4 matrix}

Starting position:
\begin{tabular}{ l }
16 15 15 13\\
12 11 10 09\\
08 07 06 05\\
04 03 02 01\end{tabular}
$\Rightarrow$
Goal:
\begin{tabular}{ l }
01 02 03 04\\
05 06 07 08\\
09 10 11 12\\
13 14 15 16\end{tabular}
\\
The results below are from a $\times5$ run on the PC(see \ref{PC}) with a 1000000 $CLOCKS PER SEC$
\\
\begin{tabular}{ | l | l | l | l | l | l | l | }
\hline
Run  & Path Size & Cost & Running Time Alg & Cpu Start & Cpu End & Total cpu time\\\hline
1 & 153 & 178 & 19.3723s & 15625 & 19375000 & 19.3594s\\\hline
2 & 153 & 178 & 19.2784s & 0 & 19281250 & 19.2812s\\\hline
3 & 153 & 178 &  19.3407s & 15625 & 19281250 & 19.2656s\\\hline
4 & 153 & 178 & 19.2833s & 0 & 19281250 & 19.2812s\\\hline
5 & 153 & 178 & 19.2716s & 0 & 19281250 & 19.2812s\\\hline
\end{tabular}
\\
The results below are from a $\times5$ run on Server(see \ref{Server}) with a 1000000 $CLOCKS PER SEC$
\\
\begin{tabular}{ | l | l | l | l | l | l | l | }
\hline
Run  & Path Size & Cost & Running Time Alg & Cpu Start & Cpu End & Total cpu time\\\hline
1 & 153 & 178 & 50.1818s & 12055 & 50126065 & 50.114s\\\hline
2 & 153 & 178 & 50.2406s & 12573 & 50170881 & 50.1583s\\\hline
3 & 153 & 178 & 50.1994s & 11521 & 50125078 & 50.1136s\\\hline
4 & 153 & 178 & 50.3866s & 12512 & 50319531 & 50.307s\\\hline
5 & 153 & 178 & 50.0151s & 11048 & 49937159 & 49.9261s\\\hline
\end{tabular}
\\
\\
The results has the same path size and cost.
From this data the algorithm is consistent with its result with path size.
There for from the data a tentative solution is provided, how ever for larger
numbers it becomes harder to prove minimum cost.
\subsection{Other applications}
The shifting row function
was also consider in some attempts to find new algorithms for encryption \cite{rotation_enc}.
As general Purpose graphic processing unit (GPGPU) can take advantage of basic rotation, this would allow for new forms of encryption.

gpu.cpp contains a partial code segment on generating the first depth needed for a search Heuristic done on the gpu using Opencl. given a little more time
and with the assistance of ``\underline{Massively Parallel A* Search on a GPU}''\cite{a_start_gpu} the solvable solution size would increase to around $n=128$.
$n=129$ over loads my GPGPU, This is most likely due to the gpu on PC (see \ref{PC})  being used to drive 3 1920 x1080 monitors.

\subsection{Output}
Each run generates a file, stored in the data folder, with information
about each run.

Out put file gives the hash for the start and end state \\
The Algorithm runs \\
Then it show the Visited count (explored) and the number
Iterations it went through.\\
The path is out printed next show the transitions\\
Finally the run time stats are printed.

\begin{lstlisting}
Start Hash:706246336224068
Goal Hash:706246335411732
============= Algorithm  ===========
Goal Found!!
Visited count:5
Iterations5
1	2
3	4
Cost:1
706246335411732->706246335412049
1	2
4	3
Cost:1
706246335412049->706246336219922
4	2
1	3
Cost:1
706246336219922->706246336224256
4	3
1	2
Cost:1
706246336224256->706246336224068
4	3
2	1
Path size: 4	Cost: 4
Running time Algorithm:	0.000589516s
cpu start: 12088	cpu end:12672	CLOCKS_PER_SEC:1000000
cpu time:	0.000584s
\end{lstlisting}
% =================================================
% Sources of error
% =================================================
\section{Sources of error}
\subsection{Compiler}
Introducing hashing caused some ``error'' into the application.
This is due to how hashing is implemented in the compiler (or windows debugger), running
the code on windows seems to yield a less accrete result, where accuracy
is gauge by minimum cost.
\\
\\
Below is an out put running on PC (see \ref{PC})
\\
**Note: the running time for windows includes
the loading to the debugging library for a pdb file (as window runs the debugger)
\\
Visual C++ \textsuperscript{TM}
\begin{lstlisting}
Path size: 156	Cost: 180
Running time Algorithm:	42.9065s
cpu start: 54	cpu end:42961	CLOCKS_PER_SEC:1000
cpu time:	42.907s
\end{lstlisting}
GNU g++
\begin{lstlisting}
Path size: 153  Cost: 178
Running time Algorithm: 20.0533s
cpu start: 15625	cpu end:19828125	CLOCKS_PER_SEC:1000000
cpu time:	19.8125s
\end{lstlisting}
\subsection{Data structures}
This implementation only allows for n to be less then 5, if 5 is chosen
the std map library will throw a segmentation fault for exceeding size.
If given more time this issue could have been resolved by creating custom
data structures to handle larger hash values and more combinations.
\subsection{Cpu boost}
During some of my runs the cpu on PC (See \ref{PC}) were being affected
the the cpu boosting into higher GHz or speed. this is error is prevalent during $3\times3$
run.

% ================================
% System
% ================================
\section{System}
\subsection{IDE}\label{IDE}
This code was programming in Visual Studio Code\cite{vscode} which an MIT ``Source Code'' editor
and debugger. which also has the
\subsection{PC} \label{PC}
Cpu: Intel(R) Core(TM) i5-6600K CPU @3.50 GHz (stock) boost to 4.10GHz
\\
RAM: 16GB DDR4
\\
Operating System: Window 10
\subsection{Laptop} \label{Laptop}
Cpu: Intel(R) Celeron(TM)  N3150 Quad-core 1.60 GHz (stock) boost to 1.8GHz
\\
RAM: 8GB DDR3L
\\
Operating System: Window 10
\subsection{Server} \label{Server}
Cpu Intel(R) Xenon(R) CPU E5345 @ 2.33 GHZ (4 cores allocated to vm with hyper-threading)
\\
RAM: 8GB DDR2 - ECC  (Error correcting Memory)
\\
Operating System: Ubuntu Server (running on a hypervisor)
\bibliographystyle{unsrt}
\bibliography{bib}

\end{document}


\chapterimage{head2.png} % Chapter heading image
\chapter{Spectral Finite Element Method}
\section{Domain of sFEM}

\subsection{Dimensionless version}
The grid size is 0.0313. (The distance between two red points). Totally, there are 193 points.
\begin{center}
        \includegraphics[scale=0.3]{ch3/node_dimensionless.pdf}
\end{center}
\begin{itemize}
        \item The number of spectral element, $N_h=64$
        \item The order of interpolation polynomial, $N_p=4$
\end{itemize}

\subsection{Version with dimension}
The grid size is 0.6250 Å. (The distance between two red points). Totally, there are 193 points.
\begin{center}
        \includegraphics[scale=0.3]{ch3/node.pdf}
\end{center}
\begin{itemize}
        \item The number of spectral element, $N_h=64$
        \item The order of interpolation polynomial, $N_p=4$
\end{itemize}

\subsection{Mathematical Concept}
Therefore, we now have $V$, a vector space  of dimension $193$. This vector space has a natural basis, or we called it the standard basis
\begin{equation}
        \{\textbf{e}_1, \textbf{e}_2, ..., \textbf{e}_{193}\}
\end{equation}
where
\begin{equation}
\textbf{e}_1=  \begin{bmatrix} 1 \\ 0 \\ \vdots \\ 0 \end{bmatrix}~~
\textbf{e}_2=  \begin{bmatrix} 0 \\ 1 \\ \vdots \\ 0 \end{bmatrix}~~
\cdots ~~
\textbf{e}_{193} = \begin{bmatrix} 0 \\ 0 \\ \vdots \\ 1 \end{bmatrix}
\end{equation}

\begin{definition}[Orthonormal basis from sFEM]
After doing spectral finite element method, we can get a set of orthonormal basis
\begin{equation}
        B = \{ \psi_1, \psi_2, \psi_3, ..., \psi_{72} \}
\end{equation}
\end{definition}

\begin{definition}[$\rho$ with respect to the $B$ basis]
Now, we have an orthonormal basis $B$, so $\rho$ can be represented
\begin{align*}
        \rho = c_1 \psi_1 + c_2 \psi_2 + \cdots + c_{72} \psi_{72}
\end{align*}
More precisely,
\begin{align*}
        [\rho]_{B} =  \begin{bmatrix} c_1 \\ c_2 \\ \vdots \\ c_{72} \end{bmatrix}
\end{align*}
\end{definition}

\section{Weight function, orthogonality and norm}
\begin{definition}[inner product]
By using integral calculus, it is common to use the following to define the inner product of two functions $f$ and $g$ with respect to a nonnegative weight function $w$ over an interval $[a, b]$:
\begin{equation}
        \langle f, g\rangle_w = \int_a^b f(x)g(x)w(x)\,dx \approx \sum_{i=1}^{193}w(x_i)f(x_i)g(x_i)
\end{equation}
\end{definition}

\begin{definition}[weight function $w(x)$]
From the  Gauss-Lobatto quadrature, we have
\begin{center}
        \includegraphics[scale=0.35]{ch3/weight_function.png}
\end{center}
\end{definition}

\begin{definition}[Orthogonal]
We say that functions $f$ and $g$ are orthogonal if their inner product (equivalently, the value of this integral) is zero:
\begin{equation}
        \langle f,g\rangle _{w}=0.
\end{equation}
\end{definition}

\begin{definition}[Norm]
We define the norm with respect to this inner product as
\begin{equation}
        \|f\|_w = \sqrt{\langle f, f\rangle_w}
\end{equation}
\end{definition}

\section{Diagonalization of the operator}
\begin{definition}[Basis functions]
\begin{align}
        \psi^0_i(x) &= \rho_{\rm eq}(x) \phi^0_i(x) \\
        \phi^0_i(x) &= \sum_n c^0_n u_n(x).
\end{align}
\label{basisfunctions}
\end{definition}

\begin{definition}[Eigenvector matrix]
\begin{equation}
\Psi=
\begin{bmatrix}
\vert & \vert &  & \vert \\
\psi_1(x) & \psi_2(x) & \cdots & \psi_{N_v}(x) \\
\vert & \vert &  & \vert
\end{bmatrix}
\end{equation}
\label{eigenvectormatrix}
Here, we get a set of orthonormal basis, $\langle \psi_i |$. The left part in the following part is
\begin{equation}
        \Psi^T_{72\times 193}\Psi_{193 \times 72} = (\Psi^T\Psi)_{72 \times 72}
\end{equation}
The completeness relationship is actually can be seen by the blue points in the right part:
\begin{equation}
        \langle \psi_i(x),\psi_i(x)\rangle _{w} = \sum_{j=1}^{193}w(x_j)\psi_i(x_j)\psi_i(x_j)  = 1
\end{equation}
\begin{center}
        \includegraphics[scale=0.4]{ch3/eigenvec_matrix_complete.png}
\end{center}
\end{definition}

\section{Photon operator and Emission probability}
Assume we have the graphical model like the following
\begin{center}
        \includegraphics[scale=0.8]{ch2/four_states_ex.png}
\end{center}
The complete likelihood function is
\begin{equation}
\mathcal{P}(X(t), Y(t)) = p(x_{t_0}) \prod_{\tau=1}^4 p(y_{t_{\tau}}|x_{t_{\tau}}) p(x_{t_{\tau}}|x_{t_{\tau -1}})
\end{equation}
where the emission probability $p(y_{t_{\tau}}|x_{t_{\tau}})$ is defined by a Gaussian
\begin{equation}
        p(y_{t_{\tau}}|x_{t_{\tau}}) =  \mathcal{N}(\mu = y_{t_{\tau}}  ,\sigma ^{2})
\end{equation}

\begin{definition}[Emission Probability as linear transformation $T$]
For example, if we have an observation $y_1$ in $t_{1}$, we will propagate like the following:
\begin{align*}
        T(\rho) = \textbf{y} \rho =
        \begin{bmatrix}
              f(x_1) & 0 & 0 & \cdots & 0 \\
              0 & f(x_2) & 0 & \cdots & 0 \\
              \vdots & \vdots & \vdots & \vdots & \vdots \\
              0 & 0 & 0 & \cdots & f(x_{193}) \\
        \end{bmatrix}
        \begin{bmatrix} \rho_1 \\ \rho_2 \\ \vdots \\ \rho_{193} \end{bmatrix}
\end{align*}
We redefine a function $f(x)$ for emission probability
\begin{align*}
f(x; \mu = y_1, \sigma) ={\frac {1}{\sigma {\sqrt {2\pi }}}}e^{-{\frac {1}{2}}\left({\frac {x-\mu }{\sigma }}\right)^{2}}
\end{align*}
\begin{center}
        \includegraphics[scale=0.5]{ch3/linear_transform.pdf}
\end{center}
\end{definition}

\begin{definition}[Transformation matrix with respect to the $B$ basis]
First, the change of basis matrix for $B$
\begin{align*}
        C =
        \begin{bmatrix}
              \vert & \vert &  & \vert \\
              \psi_1   & \psi_2 & \cdots & \psi_{72} \\
              \vert & \vert &  & \vert
        \end{bmatrix}_{193 \times 72}
\end{align*}
And its transpose is
\begin{align*}
        C^{T} =
        \begin{bmatrix}
        - & \psi_1 & - \\
        - & \psi_2 & - \\
         & \vdots & \\
         - & \psi_{72} & - \\
        \end{bmatrix}_{72 \times 193}
\end{align*}
And you can see
\begin{align*}
        C^{T}C = I
\end{align*}
so \( C^{T}\) is left inverse
\begin{align*}
        C^{T} = C^{-1}
\end{align*}
\begin{center}
        \includegraphics[scale=0.5]{ch3/transform_map.pdf}
\end{center}
Therefore, we get a transformation matrix $D$ with repect to $B$ basis
\begin{equation}
        [T(\rho)]_{B} = D [\rho]_{B}
\end{equation}
where
\begin{align*}
        D =  \begin{bmatrix}
                - & \psi_1 & - \\
                - & \psi_2 & - \\
                 & \vdots & \\
                 - & \psi_{72} & - \\
             \end{bmatrix}_{72 \times 193}
          \begin{bmatrix}
          f(x_1) & 0 & \cdots & 0 \\
          0 & f(x_2) & \cdots & 0 \\
          \vdots & \vdots & \vdots & \vdots \\
          0 & 0 & \cdots & f(x_{193}) \\
          \end{bmatrix}_{193 \times 193}
          \begin{bmatrix}
                \vert & & \vert \\
                \psi_1   & \cdots & \psi_{72} \\
                \vert &  & \vert
          \end{bmatrix}_{193 \times 72}
\end{align*}
$D$ can also be expressed by bra-ket notation
\begin{align*}
        D=\begin{bmatrix}
                \left< \psi_1(x) | \textbf{y} | \psi_1(x) \right> & \left< \psi_1(x) | \textbf{y} | \psi_2(x) \right> & \cdots & \left< \psi_1(x) | \textbf{y} | \psi_{72}(x) \right> \\
                \left< \psi_2(x) | \textbf{y} | \psi_1(x) \right> & \left< \psi_2(x) | \textbf{y} | \psi_2(x) \right> & \cdots & \left< \psi_2(x) | \textbf{y} | \psi_{72}(x) \right> \\
                \vdots & \vdots & \cdots & \vdots \\
                \left< \psi_{72}(x) | \textbf{y} | \psi_1(x) \right> & \left< \psi_{72}(x) | \textbf{y} | \psi_2(x) \right> & \cdots & \left< \psi_{72}(x) | \textbf{y} | \psi_{72}(x) \right> \\
                \end{bmatrix}_{72 \times 72}
\end{align*}
where
\begin{align*}
        \left< \psi_i(x) | \textbf{y} | \psi_j(x) \right> = \int w(x) \psi_i(x) f(x) \psi_j(x) dx \approx \sum_{k=1}^{193} w(x_k) \psi_i(x_k) f(x_k) \psi_j(x_k)
\end{align*}
\end{definition}

\section{Single Well}
\begin{center}
        \includegraphics[scale=0.45]{ch3/single_well_1.pdf}
\end{center}
\begin{center}
        \includegraphics[scale=0.35]{ch3/single_well_2.pdf}
\end{center}

\section{Double Well}
\begin{center}
        \includegraphics[scale=0.45]{ch3/double_well_1.pdf}
\end{center}
\begin{center}
        \includegraphics[scale=0.35]{ch3/double_well_2.pdf}
\end{center}

\section{Triple Well}
\begin{center}
        \includegraphics[scale=0.45]{ch3/triple_well_1.pdf}
\end{center}
\begin{center}
        \includegraphics[scale=0.35]{ch3/triple_well_2.pdf}
\end{center}


\section{Use of Curry and Foldr / Foldl}

\begin{lstlisting}[language=Haskell]
module ProgExercises.FS_2019_ProgExer04Prob_V01 where

-- Exercise (Higher-Order Functions)

import Prelude hiding (flip, curry, uncurry)

toBeImplemented = undefined

-- flip f takes its (first) two arguments in the reverse order of f
exaFlip = flip take [1,2,3,4,5] 3 == [1,2,3]

flip :: (a -> b -> c) -> (b -> a -> c)
flip f x y = f y x

-- curry converts a function on pairs to a curried function
exaCurry = curry (\(x,y) -> x + y) 3 4 == 7

curry :: ((a, b) -> c) -> (a -> b -> c)
curry f x y = f (x, y)

-- uncurry converts a curried function to a function on pairs
exaUncurry = uncurry (\x y -> x + y) (3, 4) == 7

uncurry :: (a -> b -> c) -> ((a, b) -> c)
uncurry f (x,y) = f x y

exaReverseFr = reverseFr [1 .. 20000] == [20000, 19999 .. 1]
exaReverseFl = reverseFl [1 .. 20000] == [20000, 19999 .. 1]

-- implement reverse using foldr and (++)
reverseFr :: [a] -> [a]
reverseFr = foldr (\x accu -> accu ++ [x]) []

-- implement reverse using foldl, (:), and flip
reverseFl :: [a] -> [a]
reverseFl = foldl (flip (:)) []

-- revAppend prepends the first list in reverse order before the second list
exaRevAppend = revAppend [3,2,1] [4,5,6] == [1,2,3,4,5,6]
-- implement revAppend using foldl and flip

revAppend :: [a] -> [a] -> [a]
revAppend = flip (foldl (flip (:)))

exaMapFr = mapFr (*2) [1 .. 10] == map (*2) [1 .. 10]
exaMapFl = mapFl (*2) [1 .. 10] == map (*2) [1 .. 10]

mapFr :: (a -> b) -> [a] -> [b]
mapFr f = foldr (\x accu -> f x : accu) []

mapFl :: (a -> b) -> [a] -> [b]
mapFl f = foldl (\accu x -> accu ++ [f x]) []

-- for estimating performance
lr = length (mapFr (*2) [1 .. 20000])
ll = length (mapFl (*2) [1 .. 20000])

exaFilterFr = filterFr odd [1 .. 10] == filterFr odd [1 .. 10]
exaFilterFl = filterFl odd [1 .. 10] == filterFl odd [1 .. 10]

filterFr :: (a -> Bool) -> [a] -> [a]
filterFr p = foldr (\x accu -> if p x then x : accu else accu) []

filterFl :: (a -> Bool) -> [a] -> [a]
filterFl p = foldl (\accu x -> if p x then accu ++ [x] else accu) []

exaLengthFr = lengthFr [1 .. 1000] == 1000
exaLengthFl = lengthFl [1 .. 1000] == 1000

lengthFr :: [a] -> Int
lengthFr = foldr (\_ accu -> 1 + accu) 0

lengthFl :: [a] -> Int
lengthFl = foldl (\accu _ -> accu + 1) 0

exaAppendFr = appendFr [4,5,6] [1,2,3] == [1 .. 6]
exaAppendFl = appendFl [1,2,3] [4,5,6] == [1 .. 6]

appendFr :: [a] -> [a] -> [a]
appendFr = flip (foldr (:))

appendFl :: [a] -> [a] -> [a]
appendFl = foldl (\accu x -> accu ++ [x])
\end{lstlisting}

\clearpage


\subsection{Hopfield Network}

% Wenting.
Hopfield's model is an associative(content-addressable) memory model using binary information and its network is featured with threshold and feedback. A binary input vector to a Hopfield Network will be recursively processed(fed back) at the granularity level of bit, until a threshold criterium is met, the produced output vector possesses the feature that is with the shortest Hamming distance to its origin input vector (see figure \ref{fig:hopfield_network}). There properties give rise to associative memory recall, where an input pattern (i.e. memory cue) is presented to the Hopfield network, which produces an output vector that is closest in Hamming distance to a previously stored memory, thus filling in the gaps to recall a memory through association.

\begin{figure}[htbp]
	\begin{center}
		\includegraphics[width=0.5\textwidth]{inc/hopfield_network.png}
		\caption{A Hopfield network consisting of 4 nodes, with an input and output vector of length 4. Additionally, each node takes as input the state of each other node in the network.\protect\footnotemark}
		\label{fig:hopfield_network}
	\end{center}
\end{figure}
\footnotetext{Original image (CC BY-SA): \url{https://upload.wikimedia.org/wikipedia/commons/9/95/Hopfield-net.png}}

In paper from J.J.Hopfield(1982) \cite{computational_abilities}, the drawbacks of Perceptron were addressed through its intractable back-coupling, lack of abstraction properties and requirement of synchronism. Information storage was improved with help of Non-linearity, and emergent computational properties were obtained from simple properties of many cells rather than complex circuitry(which is a result of linear associativity). The input-output relationship of non-linear computation, binary threshold units and concept of the energy function were introduced.

Collective behaviours of the model was studied and resulted with the following findings: a few stable states was resulted from most of the initial state space, properties necessary for a physical content-addressable memory were not dependent on the symmetry of the connectivity matrix $T_{ij}$. Statement supported by findings from experiments is that ``about 0.15N(memory storage bits, number of neurons) states can be simultaneously remembered before error in recall is severe'', which refers to the memory capacity of the associative memory. Case with arbitrary starting state was studied and results of memories near to the starting state was highly produced. The nominally assigned memories which were called ``attractors'' dominates the phase flow whereas the flow is not entirely deterministic, which leads to a convergence to local optimum.

Case of consistent internal correlations in the memory was as well addressed, and Hebb synapses was used and slightly modified to generate non-symmetric term~$\delta T_{ij}$, which limitation of sequence of four states was addressed.


\chapter{The Design of SmartFin} \label{combinator-DSL}

The main goal of this project is to provide a smart contract implementation of a DSL for financial contracts. Before discussing this implementation, this chapter defines the syntax and semantics of the DSL being implemented, SmartFin. \\

The syntax and semantics of SmartFin are derived from a DSL proposed by Peyton Jones et al.\cite{SPJ}, described in section \ref{DSL-design}, but SmartFin varies slightly from this original DSL. The smart contract implementing SmartFin must behave correctly when any SmartFin contract definition is provided, according to the syntax and semantics laid out in this chapter.

\section{Overview of SmartFin Financial Contracts}

SmartFin is a combinator domain-specific language used to describe financial contracts, and in general operates very similarly to the DSL defined by Peyton Jones et al.\cite{SPJ} which is described in section \ref{DSL-overview}. The general gist is that a SmartFin contract represents a financial contract between two parties, which can define payments between these parties. The \textit{holder} party is able to acquire a SmartFin contract - just as a traditional financial contract would be signed - and any obligations are carried out subsequently. SmartFin contracts can expire, and contracts can rely on external input.

\section{Syntax} \label{DSL-BNF}

The syntax of SmartFin is very simple, due to its combinatorial nature. The Backus-Naur form of the grammar is as follows, where \texttt{<name>} is a string starting with a non-integer character, \texttt{<time>} is a date and time, \texttt{<integer>} is an integer value, and \texttt{<address>} is an Ethereum address: \\

\setlength{\grammarindent}{10em}
\begin{grammar}
<contract> ::= `zero'
\alt `one'
\alt `give' <contract>
\alt `get' <contract>
\alt `anytime' <contract>
\alt `scale' <observable> <contract>
\alt `truncate' <time> <contract>
\alt `and' <contract> <contract>
\alt `or' <contract> <contract>
\alt `then' <contract> <contract>

<observable> ::= <integer> | <name> <address>
\end{grammar}

This syntax has one major difference from the syntax of the original DSL presented in the paper by Peyton Jones et al.\cite{SPJ}. This difference is the representation of \textit{observables}, used with the \texttt{scale} combinator in the \texttt{<contract>} rule. In the original DSL, an \texttt{observable} takes a constant value, or a representation of a time-varying value, but its syntax was left abstract due to the somewhat abstract nature of the combinators' implementation in the paper. The paper was more focused on evaluating financial contracts written in this form than representing them programmatically. As this project requires a concrete implementation of the DSL, the syntax cannot be left abstract. Because of this, it is necessary to give a specific definition of an observable's syntax; the chosen definition being a constant integer value, or a name and an Ethereum address. The purpose of these representations is explained further in section \ref{DSL-semantics}. The original DSL also allowed observables to have mathematical operations carried out on them, whereas SmartFin does not. \\

For clarity, the format of the \texttt{<time>} rule in the provided BNF can be either UNIX Epoch time, or a date and time in the format \texttt{"<DD/MM/YYYY HH:mm:ss +ZZ>"} - where \texttt{"DD"} is a two-digit date, \texttt{"MM"} is a two-digit month, \texttt{"YYYY"} is a four-digit year, \texttt{"HH"} is a two-digit hour, \texttt{"mm"} is a two-digit minute, \texttt{"ss"} is a two-digit second, and \texttt{"+ZZ"} is an optional positive or negative two-digit time zone offset.

\section{Semantics} \label{DSL-semantics}

Each combinator has a specific meaning, potentially depending on sub-combinators, times, and/or observables. This section gives a definition of the semantics of SmartFin combinators where they differ from the original DSL, namely \texttt{one} and \texttt{scale}. For combinators not listed here, see \ref{combinators} for their semantics. The conventions used to represent the syntax of these combinators is defined in figure \ref{combinator-semantics-notation}, and the definition of each combinator's semantics is as follows: \\

\begin{table}[ht]
    \begin{center}
        \begin{tabular}{|ll|}
            \hline
            $c, d$ &\textit{Contract} \\
            $o$ &\textit{Observable} \\
            $x$ &\textit{Constant Value} \\
            $n$ &\textit{Observable Name (as in section \ref{DSL-BNF})} \\
            $a$ &\textit{Ethereum Address} \\
            $t$ &\textit{Time} \\
            \hline
        \end{tabular}
        \caption{Conventions for the description of the SmartFin's semantics}
        \label{combinator-semantics-notation}
    \end{center}
\end{table}

\parbox{\textwidth}{
\texttt{zero, give c, and c d, or c d, truncate t c, then c d, get c, anytime c} \\

These combinators' semantics are unchanged from the original DSL, described in section \ref{combinators}. \\ \\

}

\parbox{\textwidth}{
\texttt{one} \\

This combinator represents a contract which requires the counter-party to pay the holder 1 Wei upon acquisition. The currency of payments is always Ether, as opposed to the original DSL's \texttt{one} combinator which takes a currency. This contract can be acquired at any time, and thus has no horizon. \\ \\
}

\texttt{scale o c} \\

A \texttt{scale} combinator represents \texttt{c} with all payments multiplied by the value of the observable \texttt{o} at the time of acquisition. \texttt{scale(o, c)} has the same horizon as \texttt{c}. \\

An observable can be provided in the format \texttt{x}, or \texttt{n a}. An observable in the form \texttt{x} is a constant integer value. For example, \texttt{scale 5 one} requires the counter-party to pay the holder 5 Wei on acquisition. \\

An observable in the form \texttt{n a} is a time-varying value. The name \texttt{n} is an identifier for the observable, and the address \texttt{a} represents an arbiter for the observable's value. This address is treated as the canonical source of the observable's value at the time of acquisition. No two observables may have the same name and arbiter, or there would be no way to differentiate the two, even though their values may differ (if they are acquired at different times, for instance). \\

\section{Remarks}

Overall, the SmartFin DSL is very similar to the original DSL described by Peyton Jones et al.\cite{SPJ}, with a few differences for the sake of compatibility with the Ethereum platform. The next chapter will describe the top-level implementation of a smart contract which can represent any given SmartFin contract, and the following chapter describes the implementation of specific combinators' semantics.


\subsection{A Short Analysis of Seasonal Pattern in TDIF and PRCP}

Spectrum analysis\cite{priestley1981spectral}, also referred to as frequency domain analysis, is the technical process of decomposing a complex signal into simpler parts. If we consider the time series of TDIF as a signal with a seasonal pattern, we can use the spectrum analysis method to identify the dominant frequency.

First let's see the plot on the left of Figure \ref{patt}. There is an obvious peak in the plot, which is the frequency domain. The cycle corresponding to the peak is 375 days, i.e. TDIF basically follows a cycle of 375 days. And there are no other peaks in the plot, so it indeed is the dominant one.

\begin{figure}[h]
\centering
\begin{minipage}[t]{0.48\textwidth}
\centering
\includegraphics[width=6cm]{patt1.png}
\end{minipage}
\begin{minipage}[t]{0.48\textwidth}
\centering
\includegraphics[width=6cm]{patt2.png}
\end{minipage}
\caption{Spectrum Plot and Time Plot}
\label{patt}
\end{figure}

On the right hand side is the time plot of TDIF (the red line) and PRCP (the black line). The red line shows a clear cycle per year, corresponding to the spectrum analysis before. On the other hand, no clear pattern of the black line can be observed. But it can tell us that PRCP is likely to be high when TDIF is low and vice versa. Overall even if we confirm the existence of a seasonal pattern in PRCP (which should be true), it may not play a crucial role in predicting daily weather. However, what we learn from the analysis above is, the TDIF is important in predicting PRCP and they are likely to be not positively, but negatively correlated.


\subsection{Bias of OLS estimator from ommitted variables}


\chapter{Large Scale Modular Physical Models}\label{ch:largeScale}
This chapter provides an extended summary for the work presented in the papers ``Real-Time Control of Large-Scale Modular Physical Models using the Sensel Morph'' \citeP[A] and ``Physical Models and Real-Time Control with the Sensel Morph'' \citeP[B].  Paper \citeP[A] presents the work done on various physical models connected by nonlinear springs using three instruments as case studies: the esraj (bowed sitar), the hammered dulcimer and the hurdy gurdy. The implementations and a video showcasing the hurdy gurdy can be found online.\footnote{\url{https://github.com/SMC-AAU-CPH/ConnectedElements/releases/tag/v5.0}}\textsuperscript{,}\footnote{\url{https://youtu.be/BkxLji2ap1w}} Paper \citeP[A] follows \cite{theBible} and \cite{Bilbao2009Modular} and uses `scaling' (see Section \ref{sec:1DwaveContTime}). To relate the paper to the theory presented in this thesis, this chapter presents the models in a non-scaled, dimensional form. The eventual implementation of the models is equivalent.
% Furthermore, this chapter will build on the contents of paper \citeP[A] by providing more details on the implementation.\todo{will it though?}

\section{Physical models}\label{sec:modelsLargeScale}
All instruments use multiple instances of the stiff string presented in Chapter \ref{ch:stiffString} and one instance of the thin plate presented in Section \ref{sec:thinPlate}. The latter was used as a simplified instrument body for the resulting simulations (see Section \ref{sec:largeScaleInstruments}). Theory on connections can be found in Chapter \ref{ch:connections}, and information on the string-plate connection, specifically, is presented in Section \ref{sec:stringPlateConnection}.

Consider set of strings, where the transverse displacement of string $s$ is described by $u_s = u_s(\chi_s, t)$ (in m) defined for $t\geq 0$ and $\chi_s \in \D_s$ for domain $\D_s = [0, L_s]$ and length $L_s$ (in m). Notice that every string is defined for a separate coordinate system $\chi_s$. In the following, spatial derivatives $\partial_{\chi_s}$ are the same as those described in Section \ref{sec:FDoperators}, but with respect to coordinate $\chi_s$. The PDE of string $s$ with an external connection force is defined as %(after division by $\rho_sA_s$)
\begin{equation}
    \begin{aligned}
    \ptt u_s = c_s^2 \partial_{\chi_s\chi_s} u_s &- \kappa_s^2 \partial_{\chi_s\chi_s\chi_s\chi_s} u_s - 2 \szX[s]\pt u_s\\
    &\quad + 2 \soX[s] \partial_{\chi_s\chi_s} u_s - \delta(\chi_s - \chi_{s, \ctxt})\frac{f_s}{\rho_sA_s},
    \end{aligned}
\end{equation}
where spatial Dirac delta function $\delta(\chi_s - \chi_{s,\ctxt})$ (in m$^{-1}$) localises the connection force between the string $s$ and the plate to connection location $\chi_{s, \ctxt}$. Other parameters are as defined in Eq. \eqref{eq:stiffStringPDE} but have a subscript $s$ to denote that they can be different for each strings.

As all connections in the implementation are between an individual string and the plate, the PDE of the thin plate in Eq. \eqref{eq:platePDE} can be extended to
\begin{equation}
    \begin{aligned}
    \!\!\!\!\ptt w = -\kappa_\ptxt^2\Delta\Delta w &\!-\! 2\szX[\ptxt]\pt w\! +\! 2\soX[\ptxt] \pt\pxx w+ \!\sum_s\delta(x \!-\! x_{\ctxt,s}, y \!-\! y_{\ctxt,s})\frac{f_s}{\rho_\ptxt H},\!\!\!\!\!\!
    \end{aligned}
\end{equation}
where 2D spatial Dirac delta function $\delta(x_s - x_{s,\ctxt}, y_s - y_{s,\ctxt})$ (in m$^{-2}$) localises the connection force of between the plate and string $s$ to coordinate $(x_s, y_s)$ on the plate. Other parameters are as defined in Eq. \eqref{eq:platePDE}.

Finally, the connection force between the plate and string $s$ is defined as a nonlinear damped spring (see Eq. \ref{eq:nonlinearForce})
\begin{equation}
    f_s = K_1\eta_s + K_3\eta_s^3 + R \dot \eta_s,
\end{equation}
where
\begin{equation}
    \eta_s = u_s(\chi_{\ctxt,s}, t) - w(x_{\ctxt,s}, y_{\ctxt,s}, t)
\end{equation}
is the relative displacement between string $s$ and the plate at their respective connection locations. Notice that the plate is placed below the strings such that the sign of the force terms are negative for the strings and positive for the the plate.

\section{Implementation}
This section provides considerations for implementing the above models. Details on discretisation of the models and how to solve for $f_s$ are presented in Section \ref{sec:stringPlateConnection} and are not be given here.

The spatial Dirac delta functions are discretised using 0\thOrder spreading operators for simplicity (see Section \ref{sec:interpolationSpreading} (1D) and Section \ref{sec:interpolationSpreading2D} (2D)). Furthermore, the connection locations on the plate are implemented to be non-overlapping. Overlaps would require to solve a system of linear equations to obtain the connection forces (see e.g. \cite{Bilbao2009Modular}). Looking towards real-time implementation, an explicit solution for the each connection is desired.

\section{Summary}
This section provides a summary of the instrument simulations presented paper \citeP[A]. All instruments were implemented in real-time in C++ using the JUCE framework (see Chapter \ref{ch:realtime}). Finally, a summary of the results and conclusion will be given.

\subsection{Instruments}\label{sec:largeScaleInstruments}
Using the setup presented in Section \ref{sec:modelsLargeScale} various configurations inspired by real instruments have been made. The choices of simulated instruments were aimed at those containing many (sympathetic) strings. Furthermore, physical models of these instruments using FDTD methods should not exist in the literature at the time of writing the papers.

Three implementations inspired by real-life instruments were created and their setups are presented here. The implementations were controlled by a pair of Sensel Morph controllers (see Section \ref{sec:sensel}). The mapping between the controllers and the instruments is explained in papers \citeP[A] and \citeP[B].

\subsubsection{Esraj: bowed sitar}
The first instrument simulation is inspired by the \textit{esraj}: the bowed sitar. This instrument uses many strings, some of which are bowed and others are sympathetic strings that resonate when the instrument is played. As one can also interact with the latter, several strings in the implementation could be plucked as well.

In total, 20 strings were implemented, all connected to a thin plate: 2 strings could be bowed, 5 strings could be plucked, and 13 strings are sympathetic. The bow was implemented using the static friction model presented in Section \ref{sec:staticFricMod} and the pluck was modelled as a time-varying raised cosine found in Section \ref{sec:timeVaryingRaisedCos}.

\subsubsection{Hammered dulcimer}
The hammered dulcimer, or santur, can be seen as an `open piano' where the player hammers several strings at once. In the implementation, 20 pairs of strings are implemented, and one in each pair is connected to the plate. This causes a slight detuning between the strings resulting in a characteristic `chorus' effect exhibited by the instrument. To excite the strings, the time-varying strike presented in Section \ref{sec:timeVaryingRaisedCos} is used.

\subsection{Hurdy gurdy}
The hurdy gurdy is a bowed string instrument also containing sympathetic strings. Rather than a bow, instrument uses a rosined wheel attached to a crank and bows the strings as it is turned. As for the esraj, the static friction model presented in Section \ref{eq:staticFriction} was used to implement the wheel.

The instrument simulation consists of 5 bowed strings and 13 sympathetic strings, all connected to a plate.

\subsection{Results and conclusion}
All instrument simulations were able to run in real time on a MacBook Pro with a 2.2 GHz Intel i7 processor.
Interaction with the implementations shows that when exciting one string, the connections with the plate cause other (sympathetic) strings to vibrate as well. Specifically, strings tuned to one of the harmonic partials of the excited string were found to resonate to a high degree. This phenomenon is consistent to real-world processes.

Finally, informal evaluations of the instruments were carried out on experts in the sound and music computing field, and showed that the mapping between the Sensels and the instruments, specifically the bowing interaction, was considered natural and intuitive.