\documentclass{amsart}

\usepackage{amssymb}

\def\vec#1{\mathchoice{\mbox{\boldmath$\displaystyle#1$}}
	{\mbox{\boldmath$\textstyle#1$}}
	{\mbox{\boldmath$\scriptstyle#1$}}
	{\mbox{\boldmath$\scriptscriptstyle#1$}}}
\newcommand{\floor}[1]{\left\lfloor #1\right\rfloor}
\newcommand{\ceil}[1]{\left\lceil #1\right\rceil}
\newcommand{\F}{\mathbb{F}}
\newcommand{\N}{\mathbb{N}}

\newcommand{\Input}{\textbf{Input:}}
\newcommand{\Output}{\textbf{Output:}}

\newcommand{\field}{\normalfont\texttt{gf256}}
\newcommand{\transforms}{\normalfont\texttt{transforms}}
\newcommand{\hermite}{\normalfont\texttt{hermite}}
\newcommand{\encode}{\normalfont\texttt{encode}}

\newcommand{\XtoN}{LCHToNewton}
\newcommand{\NtoX}{NewtonToLCH}
\newcommand{\XtoL}{LCHEval}
\newcommand{\LtoX}{LCHInterp}
\newcommand{\lsXtoL}{LowSpaceLCHEval}
\newcommand{\lsLtoX}{LowSpaceLCHInterp}
\newcommand{\XtoM}{LCHToMonomial}
\newcommand{\MtoX}{MonomialToLCH}
\newcommand{\Taylor}{TaylorExpansion}
\newcommand{\InverseTaylor}{InverseTaylorExpansion}

\makeatletter
\newcommand*{\bdiv}{%
	\nonscript\mskip-\medmuskip\mkern5mu%
	\mathbin{\operator@font div}\penalty900\mkern5mu%
	\nonscript\mskip-\medmuskip
}
\makeatother

\let\originalleft\left
\let\originalright\right
\renewcommand{\left}{\mathopen{}\mathclose\bgroup\originalleft}
\renewcommand{\right}{\aftergroup\egroup\originalright}

\newenvironment{inputs}{\Input\par\begin{tabular}{@{}rcl}}{\end{tabular}}
\newenvironment{outputs}{\Output\par}{}

\setlength{\parindent}{0pt}
\setlength{\parskip}{1ex plus 0.5ex minus 0ex}

\begin{document}

\title{\lowercase{ftoc2}: Fast transforms over characteristic 2}
\maketitle

\section{\field{}: Implementation of arithmetic in $\F_{2^8}$}

The module \field{} implements field arithmetic for $\F_{2^8}$. We let
$\F_{2^8}=\F_2(\alpha)$ for a root $\alpha$ of $x^8+x^4+x^3+x^2+1$, and
$\{\beta_0,\dotsc,\beta_7\}$ be the basis of the extension obtained by letting
$\beta_7=\alpha^5$ and $\beta_i=\beta^2_{i+1}-\beta_{i+1}$ for
$i\in\{0,\dotsc,6\}$. This construction yields a so-called Cantor basis (see
\cite[Appendix~A]{gao2010}). Define maps $[{}\cdot{}]_k:\N\rightarrow\{0,1\}$
for $k\in\N$ by
\begin{equation*}
	i=\sum_{k\in\N}2^k[i]_k
	\quad\text{for $i\in\N$}.
\end{equation*}
The field $\F_{2^8}$ is enumerated as $\{\omega_0,\dotsc,\omega_{255}\}$, with
\begin{equation*}
	\omega_i=\sum^7_{k=0}[i]_k\beta_k
	\quad\text{for $i\in\{0,\dotsc,255\}$}.
\end{equation*}
Then $\F_{2^d}=\{\omega_0,\dotsc,\omega_{2^d-1}\}$ for $d\in\{1,2,4,8\}$.

An element $\omega_i\in\F_{2^8}$ is represented by the byte
$[i]_7[i]_6\dotsb[i]_0$. Thus, addition of field elements corresponds to
computing the XOR of bytes. Logarithm and exponent tables are used for
multiplication. The array $\texttt{LOG}$ contains logarithms base $\alpha$:
$\texttt{LOG}[i]$ is the byte that corresponds to $\log_\alpha\omega_i$ for
$i\in\{1,\dotsc,255\}$, and $\texttt{LOG}[0]$ is arbitrarily set to zero.
Similarly, $\texttt{EXP}[i]$ corresponds to $\alpha^i$ for
$i\in\{0,\dotsc,254\}$.

\subsection{Functions}\

\texttt{unsigned char mul(unsigned char x, unsigned char y)}

\begin{inputs}
	\texttt{x} & - & field element, \\
	\texttt{y} & - & field element.
\end{inputs}

\begin{outputs}
	The product of the two elements $x,y\in\F_{2^8}$ that correspond to the inputs.
\end{outputs}

\section{\transforms{}: Transforms over $\F_{2^8}$}

The module \transforms{} implements several of the fast transforms proposed
in~\cite{gao2010,lin2014,lin2016a,coxon2018b}. Define polynomials
\begin{equation*}
	N_i
	=
	\prod^{i-1}_{j=0}
	\left(x-\omega_j\right)
	\quad\text{and}\quad
	X_i
	=
	\prod^7_{k=0}
	\prod^{2^k[i]_k-1}_{j=0}
	\left(x-\omega_j\right)
\end{equation*}
for $i\in\{0,\dotsc,255\}$. The polynomials $N_i$ are the Newton polynomials
associated with the enumeration $\{\omega_0,\dotsc,\omega_{255}\}$ of
$\F_{2^8}$. The polynomials $X_i$ were introduced by Lin, Chung and Han
\cite{lin2014}, and referred to hereafter as the LCH basis polynomials.

\subsection{Functions}\

\texttt{unsigned int log2(unsigned int n)}

Ceiling of base two logarithm.

\begin{inputs}
	\texttt{n} & - & an integer.
\end{inputs}

\begin{outputs}
	The ceiling of $\log_2 n$.
\end{outputs}

\texttt{void \NtoX(int l, unsigned char[:]\ a)}

Newton basis to LCH basis conversion.

\begin{inputs}
	\texttt{l} & - & length of the polynomial, \\
	\texttt{a} & - & coefficient array.
\end{inputs}

\begin{outputs}
	If initially $\texttt{a}[i]=f_i\in\F_{2^8}$ for $i\in\{0,\dotsc,\ell-1\}$, then
	on termination $\texttt{a}[i]=h_i\in\F_{2^8}$ for $i\in\{0,\dotsc,\ell-1\}$ such
	that
	\begin{equation}\label{eqn:newton-lch}
		\sum^{\ell-1}_{i=0}f_iN_i
		=\sum^{\ell-1}_{i=0}h_iX_i.
	\end{equation}
\end{outputs}

\texttt{void \XtoN(int l, unsigned char[:]\ a)}

LCH basis to Newton basis conversion.

\begin{inputs}
	\texttt{l} & - & length of the polynomial, \\
	\texttt{a} & - & coefficient array.
\end{inputs}

\begin{outputs}
	If initially $\texttt{a}[i]=h_i\in\F_{2^8}$ for $i\in\{0,\dotsc,\ell-1\}$, then
	on termination $\texttt{a}[i]=f_i\in\F_{2^8}$ for $i\in\{0,\dotsc,\ell-1\}$ such
	that \eqref{eqn:newton-lch} holds.
\end{outputs}

\texttt{void \LtoX(unsigned char shift, int c, int l, unsigned char[:]\ a)}

Interpolation on the LCH basis.

\begin{inputs}
	\texttt{shift} & - & shift parameter,                \\
	\texttt{c} & - & number of evaluations provided, \\
	\texttt{l} & - & length of the polynomial,       \\
	\texttt{a} & - & coefficient array of length $2^{\ceil{\log_2\ell}}$.
\end{inputs}

\begin{outputs}
	Given $\texttt{shift}=\lambda\in\F_{2^8}$, $\texttt{a}[i]=f_i\in\F_{2^8}$ for
	$i\in\{0,\dotsc,c-1\}$, and $\texttt{a}[i]=h_i\in\F_{2^8}$ for
	$i\in\{c,\dotsc,\ell-1\}$, the function terminates with
	$\texttt{a}[i]=h_i\in\F_{2^8}$ for $i\in\{0,\dotsc,c-1\}$ such that
	\begin{equation}\label{eqn:lagrange-lch}
		\sum^{\ell-1}_{i=0}
		h_i
		X_i\left(\omega_j+\lambda\right)
		=
		f_j
		\quad
		\text{for $j\in\{0,\dotsc,c-1\}$}.
	\end{equation}
\end{outputs}

\texttt{void \XtoL(unsigned char shift, int c, int l, unsigned char[:]\ a)}

Evaluation on the LCH basis.

\begin{inputs}
	\texttt{shift} & - & shift parameter,                  \\
	\texttt{c} & - & number of evaluations to compute, \\
	\texttt{l} & - & length of the polynomial,         \\
	\texttt{a} & - & coefficient array of length
	$\max(\ell,2^{\ceil{\log_2c}})$.
\end{inputs}

\begin{outputs}
	Given $\texttt{shift}=\lambda\in\F_{2^8}$ and $\texttt{a}[i]=h_i\in\F_{2^8}$ for
	$i\in\{0,\dotsc,\ell-1\}$, the function terminates with
	$\texttt{a}[i]=f_i\in\F_{2^8}$ for $i\in\{0,\dotsc,c-1\}$ such that
	\eqref{eqn:lagrange-lch} holds.
\end{outputs}

\texttt{void \lsXtoL(unsigned char shift, int c, int l, unsigned char[:]~a)}

In-place evaluation on the LCH basis.

\begin{inputs}
	\texttt{shift} & - & shift parameter,                  \\
	\texttt{c}     & - & number of evaluations to compute, \\
	\texttt{l}     & - & length of the polynomial,         \\
	\texttt{a}     & - & coefficient array.
\end{inputs}

\begin{outputs}
	Given $\texttt{shift}=\lambda\in\F_{2^8}$, $\texttt{a}[i]=h_i\in\F_{2^8}$ for
	$i\in\{0,\dotsc,\ell-1\}$, and $\texttt{a}[i]\in\F_{2^8}$ for
	$i\in\{c,\dotsc,\ell-1\}$ (i.e, their value does not matter), the function terminates with
	$\texttt{a}[i]=f_i\in\F_{2^8}$ for $i\in\{0,\dotsc,c-1\}$ such that
	\eqref{eqn:lagrange-lch} holds, while $\texttt{a}[c],\dotsc,\texttt{a}[\ell-1]$
	retain their initial values if $c<\ell$.
\end{outputs}

\texttt{void \lsLtoX(unsigned char shift, int c, int l, unsigned char[:]~a)}

In-place interpolation on the LCH basis.

\begin{inputs}
	\texttt{shift} & - & shift parameter,                \\
	\texttt{c}     & - & number of evaluations provided, \\
	\texttt{l}     & - & length of the polynomial,       \\
	\texttt{a}     & - & coefficient array.
\end{inputs}

\begin{outputs}
	Given $\texttt{shift}=\lambda\in\F_{2^8}$, $\texttt{a}[i]=f_i\in\F_{2^8}$ for
	$i\in\{0,\dotsc,c-1\}$, and $\texttt{a}[i]=h_i\in\F_{2^8}$ for
	$i\in\{c,\dotsc,\ell-1\}$, the function terminates with
	$\texttt{a}[i]=h_i\in\F_{2^8}$ for $i\in\{0,\dotsc,c-1\}$ such that
	\eqref{eqn:lagrange-lch} holds, while $\texttt{a}[c],\dotsc,\texttt{a}[\ell-1]$
	retain their initial values.
\end{outputs}

\texttt{void \Taylor(int t, int l, unsigned char[:]\ a)}

Generalised Taylor expansion at $x^{2^t}-x$.

\begin{inputs}
	\texttt{t} & - & exponent,                 \\
	\texttt{l} & - & length of the polynomial, \\
	\texttt{a} & - & coefficient array.
\end{inputs}

\begin{outputs}
	If initially $\texttt{a}[i]=f_i\in\F_{2^8}$ for $i\in\{0,\dotsc,\ell-1\}$, then
	on termination $\texttt{a}[i]=h_i\in\F_{2^8}$ for $i\in\{0,\dotsc,\ell-1\}$ such
	that
	\begin{equation}\label{eqn:taylor}
		\sum^{\ell-1}_{i=0}f_ix^i
		=
		\sum^{\ell-1}_{i=0}
		h_i
		x^{i-2^t\floor{i/2^t}}
		\left(x^{2^t}-x\right)^{\floor{i/2^t}}.
	\end{equation}
\end{outputs}

\texttt{void InverseTaylorExpansion(int t, int l, unsigned char[:]\ a)}

Inverse generalised Taylor expansion at $x^{2^t}-x$.

\begin{inputs}
	\texttt{t} & - & exponent,                 \\
	\texttt{l} & - & length of the polynomial, \\
	\texttt{a} & - & coefficient array.
\end{inputs}

\begin{outputs}
	If initially $\texttt{a}[i]=h_i\in\F_{2^8}$ for $i\in\{0,\dotsc,\ell-1\}$, then
	on termination $\texttt{a}[i]=f_i\in\F_{2^8}$ for $i\in\{0,\dotsc,\ell-1\}$ such
	that \eqref{eqn:taylor} holds.
\end{outputs}

\texttt{void \MtoX(int l, unsigned char[:]\ a)}

Monomial basis to LCH basis conversion.

\begin{inputs}
	\texttt{l} & - & length of the polynomial, \\
	\texttt{a} & - & coefficient array.
\end{inputs}

\begin{outputs}
	If initially $\texttt{a}[i]=f_i\in\F_{2^8}$ for $i\in\{0,\dotsc,\ell-1\}$, then
	on termination $\texttt{a}[i]=h_i\in\F_{2^8}$ for $i\in\{0,\dotsc,\ell-1\}$ such
	that $\sum^{\ell-1}_{i=0}f_ix^i=\sum^{\ell-1}_{i=0}h_iX_i$.
\end{outputs}

\texttt{void \XtoM(int l, unsigned char[:]\ a)}

LCH basis to monomial basis conversion.

\begin{inputs}
	\texttt{l} & - & length of the polynomial, \\
	\texttt{a} & - & coefficient array.
\end{inputs}

\begin{outputs}
	If initially $\texttt{a}[i]=h_i\in\F_{2^8}$ for $i\in\{0,\dotsc,\ell-1\}$, then
	on termination $\texttt{a}[i]=f_i\in\F_{2^8}$ for $i\in\{0,\dotsc,\ell-1\}$ such
	that $\sum^{\ell-1}_{i=0}h_iX_i=\sum^{\ell-1}_{i=0}f_ix^i$.
\end{outputs}

\texttt{void TaylorExpansionHighCoeffs(int t, int c, int l, unsigned char[:]\
	a)}

High coefficients of the generalised Taylor expansion at $x^{2^t}-x$.

\begin{inputs}
	\texttt{t} & - & exponent,                 \\
	\texttt{c} & - & cut-off,                  \\
	\texttt{l} & - & length of the polynomial, \\
	\texttt{a} & - & coefficient array.
\end{inputs}

\begin{outputs}
	If initially $\texttt{a}[i]=f_i\in\F_{2^8}$ for ${i\in\{c,\dotsc,\ell-1\}}$,
	then on termination $\texttt{a}[i]=h_i\in\F_{2^8}$ for $i\in\{c,\dotsc,\ell-1\}$
	such that
	\begin{equation}\label{eqn:taylor}
		\sum^{\ell-1}_{i=c}f_ix^i
		=
		\sum^{\ell-1}_{i=0}
		h_i
		x^{i-2^t\floor{i/2^t}}
		\left(x^{2^t}-x\right)^{\floor{i/2^t}},
	\end{equation}
	for some $h_0,\dots,h_{c-1}\in\F_{2^8}$, while
	$\texttt{a}[0],\dotsc,\texttt{a}[c-1]$ retain their initial values.
\end{outputs}

\texttt{void \MtoX HighCoeffs(int c, int l, unsigned char[:]\ a)}

Monomial basis to LCH basis conversion.

\begin{inputs}
	\texttt{c} & - & cut-off,                  \\
	\texttt{l} & - & length of the polynomial, \\
	\texttt{a} & - & coefficient array.
\end{inputs}

\begin{outputs}
	If initially $\texttt{a}[i]=f_i\in\F_{2^8}$ for ${i\in\{c,\dotsc,\ell-1\}}$,
	then on termination $\texttt{a}[i]=h_i\in\F_{2^8}$ for $i\in\{c,\dotsc,\ell-1\}$
	such that
	$\sum^{\ell-1}_{i=c}f_ix^i=\sum^{\ell-1}_{i=0}h_iX_i$ for some
	$h_0,\dots,h_{c-1}\in\F_{2^8}$, while $\texttt{a}[0],\dotsc,\texttt{a}[c-1]$
	retain their initial values.
\end{outputs}

\section{\hermite{}: Hermite interpolation and evaluation over $\F_{2^8}$}

The module \hermite{} is an implementation of the Hermite interpolation and
evaluation algorithms proposed in \cite{coxon2018}, specialised to $\F_{2^8}$
and its subfields. These algorithms reduce instances of the Hermite problems to
instances of regular (i.e., without the presence of derivatives) interpolation
and evaluation problems. We implement these reduction, and use the \transforms{}
module to solve the problems they admit. The algorithms used in the module are
more general than their counterparts in~\cite{coxon2018}, since they include an
additional parameter $\ell$ that accounts for polynomial length.

For $i\in\N$, let $D^i:\F_{2^8}[x]\rightarrow\F_{2^8}[x]$ be the map that sends
$f\in\F_{2^8}[x]$ to the coefficient of $y^i$ in $f(x+y)\in\F_{2^8}[x][y]$,
called the $i$th Hasse derivative on $\F_{2^8}[x]$.

\subsection{Functions}\

\texttt{void Evaluate(int c, int l, unsigned char[:]\ a)}

Algorithm 1.

\begin{inputs}
	\texttt{c} & - & number of evaluations to compute, \\
	\texttt{l} & - & length of the polynomial,         \\
	\texttt{a} & - & coefficient array.
\end{inputs}

\begin{outputs}
	If initially $\texttt{a}[i]=f_i\in\F_{2^8}$ for $i\in\{0,\dotsc,\ell-1\}$, then
	on termination $\texttt{a}[i]=f(\omega_i)\in\F_{2^8}$ for
	$f=\sum^{\ell-1}_{i=0}f_ix^i$ and $i\in\{0,\dotsc,c-1\}$.
\end{outputs}

\texttt{void Interpolate(int c, int l, unsigned char[:]\ a)}

Algorithm 3.

\begin{inputs}
	\texttt{c} & - & number of evaluations provided, \\
	\texttt{l} & - & length of the polynomial,       \\
	\texttt{a} & - & coefficient array.
\end{inputs}

\begin{outputs}
	If initially $\texttt{a}[i]=h_i\in\F_{2^8}$ for $i\in\{0,\dotsc,c-1\}$, and
	$\texttt{a}[i]=f_i\in\F_{2^8}$ for $i\in\{c,\dotsc,\ell-1\}$, then on
	termination $\texttt{a}[i]=f_i\in\F_{2^8}$ for $i\in\{0,\dotsc,c-1\}$ such that
	$f=\sum^{\ell-1}_{i=0}f_ix^i$ satisfies $f(\omega_i)=h_i$ for
	$i\in\{0,\dotsc,c-1\}$.
\end{outputs}

\texttt{void PrepareLeft(int d, int n, int c, int l, unsigned char[:]\ a)}

The function \textsf{PrepareLeft} from Algorithm 2.

\texttt{void PrepareRight(int d, int n, int c, int l, unsigned char[:]\ a)}

The function \textsf{PrepareRight} from Algorithm 4.

\texttt{void HermiteEvaluate(int d, int n, int c, int l, unsigned char[:]\ a)}

Algorithm 2.

\begin{inputs}
	\texttt{d} & - & field degree,                     \\
	\texttt{c} & - & number of evaluations to compute, \\
	\texttt{l} & - & length of the polynomial,         \\
	\texttt{a} & - & coefficient array of length
	$2^{\lceil\log_2\lceil\ell/2^d\rceil\rceil+d}$.
\end{inputs}

\begin{outputs}
	If initially $\texttt{a}[i]=f_i\in\F_{2^8}$ for $i\in\{0,\dotsc,\ell-1\}$, then
	on termination
	$\texttt{a}[i]=(D^{i\bdiv{2^d}}f)(\omega_{i\bmod{2^d}})\in\F_{2^8}$ for
	$f=\sum^{\ell-1}_{i=0}f_ix^i$ and $i\in\{0,\dotsc,c-1\}$.
\end{outputs}

\texttt{void HermiteInterpolate(int d, int n, int c, int l, unsigned char[:]\
	a)}

Algorithm 4.

\begin{inputs}
	\texttt{d} & - & field degree,                   \\
	\texttt{c} & - & number of evaluations provided, \\
	\texttt{l} & - & length of the polynomial,       \\
	\texttt{a} & - & coefficient array of length
	$2^{\lceil\log_2\lceil\ell/2^d\rceil\rceil+d}$.
\end{inputs}

\begin{outputs}
	If initially $\texttt{a}[i]=h_i\in\F_{2^8}$ for $i\in\{0,\dotsc,c-1\}$, and
	$\texttt{a}[i]=f_i\in\F_{2^8}$ for $i\in\{c,\dotsc,\ell-1\}$, then on
	termination $\texttt{a}[i]=f_i\in\F_{2^8}$ for $i\in\{0,\dotsc,c-1\}$ such that
	$f=\sum^{\ell-1}_{i=0}f_ix^i$ satisfies
	$(D^{i\bdiv{2^d}}f)(\omega_{i\bmod{2^d}})=h_i$ for $i\in\{0,\dotsc,c-1\}$.
\end{outputs}

\section{\encode{}: Systematic encoding of multiplicity codes over $\F_{2^8}$}

The module \encode{} is an implementation of the systematic encoding algorithm
for multiplicity codes proposed in \cite{coxon2017}, specialised to codes over
$\F_{2^8}$ and its subfields. To encode, the algorithm solves a multivariate
Hermite interpolation problem, followed by a multivariate Hermite evaluation
problem. Both these problems are solved by algorithms that reduce the
multivariate problems to instances of the univariate problems. The module
\hermite{} is used to solve the univariate problems. The reduction also relies
on the use of a multivariate Newton-like basis. The module \transforms{} is used to
perform conversions between this basis and the monomial basis.

The ring of polynomials over $\F_q$ in indeterminates $x_1,\dotsc,x_m$ is
denoted by $\F_q[\vec{x}]=\F_q[x_1,\dotsc,x_m]$. Define
$\vec{x}^{\vec{i}}=x^{i_1}_1\dotsm x^{i_m}_m$ for
$\vec{i}=(i_1,\dotsc,i_m)\in\N^m$. For $\vec{i}\in\N^m$, let
$D^{\vec{i}}:\F_q[\vec{x}]\rightarrow\F_q[\vec{x}]$ be the map that sends
$f\in\F_q[\vec{x}]$ to the coefficient of $\vec{y}^{\vec{i}}$ in
$f(\vec{x}+\vec{y})\in\F_q[\vec{x}][\vec{y}]$, called the $\vec{i}$th Hasse
derivative on $\F_q[\vec{x}]$. Let $\F_q[\vec{x}]_\ell$ denote the space of
polynomials in $\F_q[\vec{x}]$ of total degree less than $\ell$. The weight of a
vector $\vec{i}\in\N^m$, denoted $\left|\vec{i}\right|$, is defined to be the
sum of its entries. Define
$S_{m,s}=\{\vec{s}\in\N^m\mid\left|\vec{s}\right|<s\}$ for positive $s\in\N$.
Then for $q$ a prime power and positive $m,\ell,s\in\N$ such that $\ell\leq sq$,
the corresponding multiplicity code is
\begin{equation*}
	\mathrm{Mult}(q,m,\ell,s)
	=
	\left\{
		\left(
			\left(
				(D^{\vec{s}}f)(\vec{\omega})
			\right)_{\vec{s}\in S_{m,s}}
		\right)_{\vec{\omega}\in\F^m_q}
		\mid
		f\in\F_q[\vec{x}]_\ell
	\right\}.
\end{equation*}

This module is limited to multiplicity codes with $q=2^d$ for some
$d\in\{1,2,4,8\}$. Consequently, $q$ is assumed to be of this form hereafter. We
index the elements of $\F^m_q$ by vectors in $\{0,\dotsc,q-1\}^m$ by defining
$\vec{\omega}_{\vec{i}}=(\omega_{i_1},\dotsc,\omega_{i_m})$ for
$\vec{i}=(i_1,\dotsc,i_m)\in\{0,\dotsc,q-1\}^m$. The class \texttt{Codeword},
which subclasses NumPy's ndarray, is used to store codewords (i.e., elements) of
a multiplicity code. In particular, a codeword is represented by a
one-dimensional ndarray of length $(qs)^m$. This is roughly $m!$ times the
length of the code, so much memory is wasted. If an array represents the
codeword corresponding to $f\in\F_q[\vec{x}]$, then the index of
$(D^{\vec{s}}f)(\vec{\omega}_{\vec{i}})$ in the array is
$\sum^m_{k=1}\left(i_k+s_kq\right)(sq)^{k-1}$, where $\vec{s}=(s_1,\dotsc,s_m)$
and $\vec{i}=(i_1,\dotsc,i_m)$. If in addition $\sum^m_{k=1}i_k+s_kq<\ell$, the
entry is part of the message of the codeword.

For $\vec{s}=(s_1,\dotsc,s_m)\in\N^m$ and
$\vec{i}=(i_1,\dotsc,i_m)\in\{0,\dotsc,q-1\}^m$, define
\begin{equation*}
	N_{\vec{i}+\vec{s}q}
	=N_{i_1}(x_1)\dotsm N_{i_m}(x_m)
	\left(x^q_1-x_1\right)^{s_1}\dotsm\left(x^q_m-x_m\right)^{s_m}.
\end{equation*}
The multivariate Newton basis of $\F_q[\vec{x}]$ defined in~\cite{coxon2017} is then equal to the set of all such polynomials.

\subsection{Functions}\

\texttt{void MonomialInterpolate(int d, int l, unsigned char[:]\ a)}

Univariate interpolation with respect to the monomial basis.

\begin{inputs}
	\texttt{d} & - & field degree,              \\
	\texttt{l} & - & length of the polynomial,  \\
	\texttt{a} & - & coefficient array.
\end{inputs}

\begin{outputs}
	If initially $\texttt{a}[i]=h_i\in\F_{2^8}$ for $i\in\{0,\dotsc,\ell-1\}$, then
	on termination $\texttt{a}[i]=f_i\in\F_{2^8}$ for $i\in\{0,\dotsc,\ell-1\}$ such
	that $f=\sum^{\ell-1}_{i=0}f_ix^i$ satisfies
	$(D^{i\bdiv{2^d}}f)(\omega_{i\bmod{2^d}})=h_i$ for $i\in\{0,\dotsc,\ell-1\}$.
\end{outputs}

\texttt{void MonomialEvaluate(int d, int l, int s, unsigned char[:]\ a)}

Univariate evaluation with respect to the monomial basis.

\begin{inputs}
	\texttt{d} & - & field degree,              \\
	\texttt{l} & - & length of the polynomial,  \\
	\texttt{s} & - & bound on derivative order, \\
	\texttt{a} & - & coefficient array.
\end{inputs}

\begin{outputs}
	If initially $\texttt{a}[i]=f_i\in\F_{2^8}$ for $i\in\{0,\dotsc,\ell-1\}$, then
	on termination
	$\texttt{a}[i]=(D^{i\bdiv{2^d}}f)(\omega_{i\bmod{2^d}})\in\F_{2^8}$ for
	$f=\sum^{\ell-1}_{i=0}f_ix^i$ and $i\in\{0,\dotsc,2^ds-1\}$.
\end{outputs}

\texttt{void SmallMonomialToNewton(int l, unsigned char[:]\ a)}

Conversion from monomial to Newton basis for $\ell\leq 2^8$.

\begin{inputs}
	\texttt{l} & - & length of the polynomial, \\
	\texttt{a} & - & coefficient array.
\end{inputs}

\begin{outputs}
	If initially $\texttt{a}[i]=f_i\in\F_{2^8}$ for $i\in\{0,\dotsc,\ell-1\}$, then
	on termination $\texttt{a}[i]=h_i\in\F_{2^8}$ such that
	$\sum^{\ell-1}_{i=0}h_iN_i=\sum^{\ell-1}_{i=0}f_ix^i$.
\end{outputs}

\texttt{void MonomialToNewton(int d, int l, unsigned char[:]\ a)}

Conversion from monomial to Newton basis.

\begin{inputs}
	\texttt{d} & - & field degree,             \\
	\texttt{l} & - & length of the polynomial, \\
	\texttt{a} & - & coefficient array.
\end{inputs}

\begin{outputs}
	If initially $\texttt{a}[i]=f_i\in\F_{2^8}$ for $i\in\{0,\dotsc,\ell-1\}$, then
	on termination $\texttt{a}[i]=h_i\in\F_{2^8}$ such that
	\begin{equation}\label{eqn:gen-newton-monomial}
		\sum^{\ell-1}_{i=0}f_ix^i
		=
		\sum^{\ell-1}_{i=0}
		h_i
		N_{i-2^d\floor{i/2^d}}
		\left(x^{2^d}-x\right)^{\floor{i/2^d}}.
	\end{equation}
\end{outputs}

\texttt{void SmallNewtonToMononial(int l, unsigned char[:]\ a)}

Conversion from Newton to monomial basis for $\ell\leq 2^8$.

\begin{inputs}
	\texttt{l} & - & length of the polynomial, \\
	\texttt{a} & - & coefficient array.
\end{inputs}

\begin{outputs}
	If initially $\texttt{a}[i]=h_i\in\F_{2^8}$ for $i\in\{0,\dotsc,\ell-1\}$, then
	on termination $\texttt{a}[i]=f_i\in\F_{2^8}$ such that
	$\sum^{\ell-1}_{i=0}f_ix^i=\sum^{\ell-1}_{i=0}h_iN_i$.
\end{outputs}

\texttt{void NewtonToMonomial(int d, int l, unsigned char[:]\ a)}

Conversion from Newton to monomial basis.

\begin{inputs}
	\texttt{d} & - & field degree,             \\
	\texttt{l} & - & length of the polynomial, \\
	\texttt{a} & - & coefficient array.
\end{inputs}

\begin{outputs}
	If initially $\texttt{a}[i]=h_i\in\F_{2^8}$ for $i\in\{0,\dotsc,\ell-1\}$, then
	on termination $\texttt{a}[i]=f_i\in\F_{2^8}$ such that
	\eqref{eqn:gen-newton-monomial} holds.
\end{outputs}

\texttt{void NewtonInterpolate(int d, int l, unsigned char[:]\ a)}

Univariate interpolation with respect to the Newton basis.

\begin{inputs}
	\texttt{d} & - & field degree,             \\
	\texttt{l} & - & length of the polynomial, \\
	\texttt{a} & - & coefficient array.
\end{inputs}

\begin{outputs}
	If initially $\texttt{a}[i]=h_i\in\F_{2^8}$ for $i\in\{0,\dotsc,\ell-1\}$, then
	on termination $\texttt{a}[i]=f_i\in\F_{2^8}$ such that
	\begin{equation}\label{eqn:univariate-newton}
		f
		=
		\sum^{\ell-1}_{i=0}
		f_i
		N_{i-2^d\floor{i/2^d}}
		\left(x^{2^d}-x\right)^{\floor{i/2^d}}
	\end{equation}
	satisfies $(D^{i\bdiv{2^d}}f)(\omega_{i\bmod{2^d}})=h_i$ for
	$i\in\{0,\dotsc,\ell-1\}$
\end{outputs}

\texttt{void NewtonEvaluate(int d, int l, int s, unsigned char[:]\ a)}

Univariate evaluation with respect to the Newton basis.

\begin{inputs}
	\texttt{d} & - & field degree,              \\
	\texttt{l} & - & length of the polynomial,  \\
	\texttt{s} & - & bound on derivative order, \\
	\texttt{a} & - & coefficient array.
\end{inputs}

\begin{outputs}
	If initially $\texttt{a}[i]=f_i\in\F_{2^8}$ for $i\in\{0,\dotsc,\ell-1\}$, then
	on termination $\texttt{a}[i]=(D^{i\bdiv{2^d}}f)(\omega_{i\bmod{2^d}})$ for the
	polynomial $f$ defined by \eqref{eqn:univariate-newton} and
	$i\in\{0,\dotsc,2^ds-1\}$.
\end{outputs}

\texttt{InfoSet(m, l, b)}

Generator function that yields
\begin{equation*}
	\left(
	i_1+i_2b+\dotsb+i_mb^{m-1},
	i_1+\dotsb+i_m
	\right)
\end{equation*}
for all $(i_1,\dotsc,i_m)\in\N^m$ such that $i_1+\dotsb+i_m<\ell$.

\texttt{RecoverPolynomial(d, m, l, C)}

Computes the polynomial that corresponds to a message.

\begin{inputs}
	\texttt{d} & - & field degree,
	\\
	\texttt{m} & - & number of variables,
	\\
	\texttt{l} & - & polynomial degree bound,
	\\
	\texttt{C} & - & a codeword array containing a message, with all other entries
	set to zero.
\end{inputs}

\begin{outputs}
	Let $b=\texttt{C.b}$, $I=\{\vec{i}\in\N^m\mid\left|\vec{i}\right|<\ell\}$, and
	define $\pi:\N^m\rightarrow\N$ by
	$(i_1,\dotsc,i_m)\mapsto\sum^m_{k=1}i_kb^{k-1}$. Suppose that initially
	$\texttt{C}[i]=h_i\in\F_{2^8}$ for $i\in\pi(I)$, while all remaining entries of
	the array are zero. Then on termination, $\texttt{C}[i]=f_i\in\F_{2^8}$ for
	$i\in\pi(I)$ such that the polynomial
	\begin{equation}\label{eqn:multivariate-newton}
		f=\sum_{\vec{i}\in I}f_{\pi(\vec{i})}N_{\vec{i}}
	\end{equation}
	satisfies
	$(D^{\vec{i}\bdiv{2^d}}f)(\vec{\omega}_{\vec{i}\bmod{2^d}})=h_{\pi(\vec{i})}$
	for $\vec{i}\in I$, while all remaining entries of the array are zero.
\end{outputs}

\texttt{EvalSet(d, m, l, s, b)}

Generator function that yields
\begin{equation*}
	\left(
	i_1+i_2b+\dotsb+i_mb^{m-1},
	i_1+\dotsb+i_m,
	\floor{i_1/2^d}+\dotsb+\floor{i_m/2^d}
	\right)
\end{equation*}
for all $(i_1,\dotsc,i_m)\in\N^m$ such that $i_1+\dotsb+i_m<\ell$ and
$\floor{i_1/2^d}+\dotsb+\floor{i_m/2^d}<s$.

\texttt{EncodePolynomial(d, m, l, s, C)}

Computes the codeword that corresponds to a polynomial.

\begin{inputs}
	\texttt{d} & - & field degree,
	\\
	\texttt{m} & - & number of variables,
	\\
	\texttt{l} & - & polynomial degree bound,
	\\
	\texttt{s} & - & derivative order bound,
	\\
	\texttt{C} & - & a codeword array containing the coefficients of a polynomial.
\end{inputs}

\begin{outputs}
	Let $b=\texttt{C.b}$, $I=\{\vec{i}\in\N^m\mid\left|\vec{i}\right|<\ell\}$,
	$C=\{\vec{i}+2^d\vec{s}\mid\vec{i}\in\{0,\dots,2^d-1\}^m,\vec{s}\in S_{m,s}\}$,
	and define $\pi:\N^m\rightarrow\N$ by
	$(i_1,\dotsc,i_m)\mapsto\sum^m_{k=1}i_kb^{k-1}$. Suppose that initially
	$\texttt{C}[i]=f_i\in\F_{2^8}$ for $i\in\pi(I)$, while all remaining entries of
	the array are zero. Then on termination, $\texttt{C}[i]=h_i\in\F_{2^8}$ for
	$i\in\pi(C)$ such that the polynomial \eqref{eqn:multivariate-newton} satisfies
	$(D^{\vec{i}\bdiv{2^d}}f)(\vec{\omega}_{\vec{i}\bmod{2^d}})=h_{\pi(\vec{i})}$
	for $\vec{i}\in C$.
\end{outputs}

\texttt{SystematicallyEncode(C)}

Systematic encoding algorithm.

\begin{inputs}
	\texttt{C} & - & a codeword array containing a message, with all other entries
	set to zero.
\end{inputs}

\begin{outputs}
	The array \texttt{C} equal to systematic encoding of the message.
\end{outputs}

\bibliographystyle{amsplain}

\begin{thebibliography}{1}

	\bibitem{coxon2017}
	Nicholas Coxon, \emph{Fast systematic encoding of multiplicity codes}, J.
	Symbolic
	Comput. \textbf{94} (2019), 234--254.

	\bibitem{coxon2018}
	Nicholas Coxon, \emph{Fast {H}ermite interpolation and evaluation over finite
		fields of characteristic two}, J. Symbolic
	Comput. \textbf{98} (2020), 270--283.

	\bibitem{coxon2018b}
	Nicholas Coxon, \emph{Fast transforms over finite fields of characteristic two},
	J. Symbolic	Comput., to appear.

	\bibitem{gao2010}
	Shuhong Gao and Todd Mateer, \emph{Additive fast {F}ourier transforms over
		finite fields}, IEEE Trans. Inform. Theory \textbf{56} (2010), no.~12,
	6265--6272.

	\bibitem{lin2016a}
	Sian-Jheng Lin, Tareq~Y. Al-Naffouri, Yunghsiang~S. Han, and Wei-Ho Chung,
	\emph{Novel polynomial basis with fast {F}ourier transform and its
		application to {R}eed--{S}olomon erasure codes}, IEEE Trans. Inform. Theory
	\textbf{62} (2016), no.~11, 6284--6299.

	\bibitem{lin2014}
	Sian-Jheng Lin, Wei-Ho Chung, and Yunghsiang~S. Han, \emph{Novel polynomial
		basis and its application to {R}eed-{S}olomon erasure codes}, 55th {A}nnual
	{IEEE} {S}ymposium on {F}oundations of {C}omputer {S}cience---{FOCS} 2014,
	IEEE Computer Soc., Los Alamitos, CA, 2014, pp.~316--325.

\end{thebibliography}

\end{document}


\subsection{Nested logit}

The probability of \(j\) being chosen is:

\(P_{ij}=P(\epsilon_{ik} <v_{ij} -v_{ik} +\epsilon_{ij}\forall k\ne j)\)

If the error terms are not IID this is more difficult to calculate.

We divide the \(J\) alternatives into nests. Within each of these we assume IID error terms, but allow variation between them.

For example we could have a nest of public/private transport. We could have a nest of types of product, and within that the firms offering the product.

The nested logit model does \(2\) or more seqential IID logit models. One to select the nest, and the other to select the alternative within the nest.


\documentclass[a4paper]{article}
\input{head}
\usepackage{algorithm}
\usepackage{verbatim}
\usepackage[noend]{algpseudocode}
\newcommand{\algrule}[1][.2pt]{\par\vskip.5\baselineskip\hrule height #1\par\vskip.5\baselineskip}
\newcommand{\floor}[1]{\left\lfloor #1 \right\rfloor}
\newcommand{\ceil}[1]{\left\lceil #1 \right\rceil}

\begin{document}

%-------------------------------
%	TITLE SECTION
%-------------------------------

\title{\textbf{COL351 : Analysis and Design of Algorithm \\ Assignment 3 }}
\author{Gaurav Jain (2019CS10349) \& T Abishek (2019CS10407)}
\date{}

%-------------------------------
%	CONTENTS
%-------------------------------

\maketitle

\section{Convex Hull}
The Divide and Conquer algorithm to compute Convex Hull is present below:

{\centering
\begin{minipage}{\linewidth}
\begin{algorithm}[H]
\caption{Convex Hull Algorithm}\label{alg:chull}
\begin{algorithmic}[1]
\Procedure{ConvexHull}{P = \{($x_1$,$y_1$),($x_2$,$y_2$)....($x_n$,$y_n$)\}}
\If{n $\leq$ 5}
 \State Solve using Brute Force method
\EndIf
\State Sort P in increasing order according to x coordinate
\State Divide P into A and B such that: A contains the left $\floor{\frac{n}{2}}$ points and B contains the right $\ceil{\frac{n}{2}}$ points.

\State $Q_1 \gets$ \textsc{ConvexHull}(A)
\State $Q_2 \gets$ \textsc{ConvexHull}(B)

\State $Q \gets$ \textsc{Merge}($Q_1$,$Q_2$)

\State \Return $Q$

\EndProcedure
\algrule
\Procedure{Merge}{A,B}
\State $(x_1,y_1) \gets$  \textsc{UpperTangent}(A,B)
\State $(x_2,y_2) \gets$ \textsc{LowerTangent}(A,B)
\State U $\gets$ \{\}
\State $u \gets x_1$
\While{$u \neq x_2$}
    \State Add $u$ to U
    \State $u \gets$ next element in A in counter clockwise direction
\EndWhile
\State $u \gets y_1$
\While{$u \neq y_2$}
    \State Add $u$ to U
    \State $u \gets$ next element in B in clockwise direction
\EndWhile

\State \Return U
\EndProcedure

\algrule
\Procedure{UpperTangent}{A,B}
\State a $\gets$ Rightmost point of A
\State b $\gets$ Leftmost point of B
\State T $\gets$ (a,b)
\While{T = ab not a tangent to both A and B}
    \While{T not a tangent to A}
    \State a $\gets$ next element in A in counter clockwise direction
    \EndWhile

    \While{T not a tangent to B}
    \State b $\gets$ next element in B in clockwise direction
    \EndWhile
\EndWhile

\State \Return T
\EndProcedure
\algrule
\Procedure{LowerTangent}{A,B}
\State a $\gets$ Index of rightmost point of A
\State b $\gets$ Index of leftmost point of B
\State T $\gets$ ab
\While{T = ab not a tangent to both A and B}
    \While{T not a tangent to A}
    \State a $\gets$ next element in A in clockwise direction
    \EndWhile

    \While{T not a tangent to B}
    \State b $\gets$ next element in B in counter clockwise direction
    \EndWhile
\EndWhile

\State \Return T
\EndProcedure

\end{algorithmic}
\end{algorithm}
\end{minipage}
\par}

\newpage
\textbf{Runtime Analysis:}\\

The time complexity of the divide and conquer algorithm to compute convex hull is calculated using the recurrence relation: T(n) = 2T(n/2)+O(n)+merge operation time complexity. Median is calculated in O(n) using $k^{th}$ smallest element problem discussed in lectures. The brute force method is used for base case when $n\leq5$ which take $O(n^3)$ time for n points. Thus, there is only a small increase in runtime.\\
The time taken in merge operation depends on the time taken to calculate upper tangent and lower tangent of the two convex hulls to be merged and the time taken to merge these two convex hulls and the two tangents which is performed in a while loop iterating over all elements of A and B.\\
The lower tangent and upper tangent function has same time complexity which is $O(size A)$ for convex hull A. Thus, the time complexity of merge operation is $O(size A)$ + $O(size B)$ + $O(n)$ = $O(n)$.\\

\textbf{Correctness of Algorithm:}\\

\textit{\underline{Claim 1}} \\
The line given by the \textsc{LowerTangent} procedure touches A and B at their lower halves and does not intersect A and B at any other points.\\
\textit{\underline{Proof}} \\
The procedure tends to move both points located on A and B in the same direction and this leads to a line segment which passes through the lowest end of the lower halves of A and B.\\
Due to this movement, line T becomes a direct tangent to the convex hulls A and B. This line also never intersect at any other point of A and B.{\hfill\qed}

\textit{\underline{Claim 2}} \\
The polygon formed after the merging step of two convex hulls A and B is a convex hull.\\
\textit{\underline{Proof}} Proof by Contradiction \\
Since A and B are convex and they are connected using upper and lower tangents, the merged polygon is also convex in nature. Suppose the polygon formed after merging A and B is not a convex hull. This means that there is at least one extra point in the merged polygon.\\
So after removing this point, the new polygon is a convex hull and the removed point should lie inside the new polygon. This implies that the removed point was part of a concave edge which is a contradiction as A and B are convex in nature.
So the above claim holds.{\hfill\qed}\\\\
We can proof the correctness of the algorithm using induction on number of points present in the plane. By dividing the plane into smaller and smaller parts, we reach the base case which is solved using brute force method. Using claim 1 and 2, merging the smaller convex hulls results in the final answer.

\newpage

\section{Particle Interaction}

\textbf{Observation}:\\

F\textsubscript{j} $=$ C q\textsubscript{j} \bigg( $\sum\limits_{i<j}^{}\frac{q\textsubscript{i}}{(j-i)\textsuperscript{2}}$ $-$ $\sum\limits_{i>j}^{}\frac{q\textsubscript{i}}{(j-i)\textsuperscript{2}}$ \bigg)
\\
F\textsubscript{j} $=$ C q\textsubscript{j} c\textsubscript{j}
\\\\

Where, \\
c\textsubscript{k} $=$  $\sum\limits_{i<j}^{}\frac{q\textsubscript{i}}{(j-i)\textsuperscript{2}}$ $-$ $\sum\limits_{i>j}^{}\frac{q\textsubscript{i}}{(j-i)\textsuperscript{2}}$  for all k $\in$ [1,n] \hfill(1)
\\\\

Consider the two polynomials, \\
A(x) $=$ q\textsubscript{1}x + q\textsubscript{2}x\textsuperscript{2} + . . . + q\textsubscript{n}x\textsuperscript{n}\\

B(x) $=$ $ - \frac{1}{(n-1)\textsuperscript{2}}x -  . . . - \frac{1}{4}x\textsuperscript{n-2} - x\textsuperscript{n-1} - 0$.$x\textsuperscript{n} + x\textsuperscript{n+1} + \frac{1}{4}x\textsuperscript{n+2} + . . . +  \frac{1}{(n-1)\textsuperscript{2}}x\textsuperscript{2n-1} $
\\

Consider the product, P(x) = A(x)$*$B(x).
\\Co-efficient of x\textsuperscript{k} for k in range (n,2n+1) $=$ $\sum\limits_{l = 1}^n a\textsubscript{l}$b\textsubscript{k-l} \hfill(2)\\\\

From equation (1) and equation (2), it is observable that coefficient of $x^{n+j}$ in P(x) = $c_j$. So, to obtain $c_j$, we need P(x) which can be calculated using Fast Fourier Transform discussed in the lectures. The time complexity here is $O(nlogn)$.
\\\\
Now, using c\textsubscript{j} and equation (1), we can obtain F\textsubscript{j} for all the particles $(j \in [1,n])$ within $O(nlogn)$ time complexity.
\\

{\centering
\begin{minipage}{\linewidth}
\begin{algorithm}[H]
\caption{Particle Interaction Algorithm}\label{pia}
\begin{algorithmic}[1]
\Procedure{ParticleInteraction}{}
\State{$A$ $\gets$ $[q\textsubscript{1}, q\textsubscript{2}, ... , q\textsubscript{n}]$}
\State{$B$ $\gets$ $[ -$ $\frac{1}{(n-1)\textsuperscript{2}}$, - $\frac{1}{(n-2)\textsuperscript{2}}$, $-1, 0, 1,$ $\frac{1}{(n-2)\textsuperscript{2}}$, $\frac{1}{(n-1)\textsuperscript{2}}$]}

\State{$P \gets$ MULTIPLY(A, B)}
\State{$TotalForce \gets$ Array of size n}
\For{$i \gets 1$ to $n$}
    \State{$TotalForce[i] \gets$ $C * A[i] * P[n+i]$}
\EndFor
\EndProcedure
\Function{Multiply}{$A, B$}
    \State{$dft_A \gets DFT(A)$}
    \State{$dft_B \gets DFT(B)$}
    \State{$dft_P \gets$ Array of size 2n+1}
    \For{$i \gets 1$ to $len(dft_A)$}
    \State{$dft_P[i] \gets$ $dft_A[i] * dft_B[i]$}
    \EndFor
    \State{$P \gets$ $InvDFT(dft_P)$}
    \State\Return{$P$}
\EndFunction
\end{algorithmic}
\end{algorithm}
\end{minipage}
\par}

\textbf{Runtime Analysis:}\\
The above algorithm returns $TotalForce$ array which has $j^{th}$ element as the final totalforce acting on $j^{th}$ particle. The \textsc{Multiply} function invloves calculating DFT for 2 vectors, each has time complexity of O(nlogn) as discussed in the lecture. \\\\
Next we have a for loop which has O(n) time complexity. Further, there is InverseDFT which again takes O(2nlog2n). Next, after the \textsc{Multiply} function we calculate the $TotalForce$ using elements of P and A. This for loop takes O(2n) time complexity. So,
\begin{center}
    T(n) = 2*O(nlogn) + O(n) + O(2nlog2n) + O(2n) = O(nlogn)
\end{center}

    %\begin{algorithm}[H] %

%\end{algorithm}%
\newpage
\section{Distance Computation using Matrix Multiplication}

\begin{enumerate}[label=(\alph*)]
\item \textbf{
Prove that the graph H = (V, E\textsubscript{H}) can be computed from G in O(n\textsuperscript{$\omega$}) time, where $\omega$ is the exponent of matrix-multiplication.}
\\\\
Solution: Using the property of transitive closure(discussed in lecture notes). Assume A is the adjacency matrix of graph G. Then, (A\textsuperscript{k})\textsubscript{ij} $>$ 0 iff there is a walk of length exactly k from i to j. Here edges exist between vertices in H, if there is a walk of length 2 or 1 in graph G. (A\textsuperscript{2}) gives the adjacency matrix of edges who had walks of length of 2 in G. So, Adjacency matrix of H is given by (A\textsuperscript{2}) + A. Matrix Addition is O(n\textsuperscript{2}) and Matrix Multiplication is O(n\textsuperscript{$\omega$}). So, overall time complexity is O(n\textsuperscript{$\omega$}) if $\omega > 2$\\

\item \textbf{
Argue that for any x, y $\in$ V , D\textsubscript{H}(x, y) = $\ceil{ \textbf{D\textsubscript{G}(x, y)/2} }$. }
\\\\
Solution: Assume for some vertice x,y the distance in graph G is k. The Path is (x,$a_1$, $a_2$, $a_3$ ........ $a_(k-1)$, y). As all the vertices who have walk of distance 2 between them get edges in the graph H, x and $a_2$, $a_2$ and $a_4$.... all have edges between them. So the path between x and y becomes (x, $a_2$, $a_4$ ........ $a_(k-2)$, y) if k is even and (x, $a_2$, $a_4$ ........ $a_(k-1)$, y) if k is odd. The distance is k/2 if k is even and k/2 + 1 if k is odd.
$\implies $ D\textsubscript{H}(x, y) = $\ceil{ \textbf{D\textsubscript{G}(x, y)/2} }$
Proved.

\item \textbf{
Let A\textsubscript{G} be adjacency matrix of G, and M $=$ D\textsubscript{H}$\star$A\textsubscript{G}. Prove that for any x, y $\in$ V, the following holds.\\\\
$D\textsubscript{G}(x, y) =
 \begin{cases}
      2D\textsubscript{H}(x, y) & M(x, y) $ \geqslant$ degree\textsubscript{G}(y) · D\textsubscript{H}(x, y) \\
      2D\textsubscript{H}(x, y) - 1 & M(x, y) $ \lneq$ degree\textsubscript{G}(y) · D\textsubscript{H}(x, y) \\
   \end{cases}
$}
\\
\item \textbf{
Use (c) to argue that D\textsubscript{G} is computable from D\textsubscript{H} in O(n\textsuperscript{$\omega$}) time.}
\\
From (c) we have
$D\textsubscript{G}(x, y) =
 \begin{cases}
      2D\textsubscript{H}(x, y) & M(x, y) $ \geqslant$ degree\textsubscript{G}(y) · D\textsubscript{H}(x, y) \\
      2D\textsubscript{H}(x, y) - 1 & M(x, y) $ \lneq$ degree\textsubscript{G}(y) · D\textsubscript{H}(x, y) \\
   \end{cases}
$
where  A\textsubscript{G} is the adjacency matrix of G and M = D\textsubscript{H}$\star$A\textsubscript{G}.\\
As, $D_G$ is computable using $D_H$ which can be computed in O(n\textsuperscript{$\omega$}) time. M can be computed in O(n\textsuperscript{$\omega$}) time too. So, the overall time complexity is O(n\textsuperscript{$\omega$}).

\item \textbf{
Prove that all-pairs-distances in n-vertex unweighted undirected graph can be computed in O(n\textsuperscript{$\omega$}log n) time, if $\omega$ is larger than two.}
\\

{\centering
\begin{minipage}{\linewidth}
\begin{algorithm}[H]
\caption{Pair Distance}\label{pia}
\begin{algorithmic}[1]
\Procedure{shortestdistance}{$A_G$}

\State \If{$A_G$ elements are non-empty}
\State \Return $A_G$
\State \Else
\State $A_H$ = ($A_G$\textsuperscript{2}) + $A_G$
\State $D_H$ = SHORTESTDISTANCE($A_H$)
\State \Return dpart($D_H$)
\EndIf
\EndProcedure

\end{algorithmic}
\end{algorithm}
\end{minipage}
\par}

\textbf{Runtime Analysis:}\\
This is a recursive algorithm, where T(n) = T(n/2) + O(n\textsuperscript{$\omega$}), as each time part d is called, the graph's distance halves. This when solved, the time complexity becomes O(n\textsuperscript{$\omega$}log n) time

\textbf{Correctness of Algorithm:}\\
As, $D_H$ gives $D_G$ using computation done in part D, using that we can say that, if $D_H$ is correct, then $D_G$ calculated will also be correct. In the base case, when the all the vertices are connected, that itself is returned. So, the base case is correct. In the induction step, when until n paths are calculated, the next step would give the correct distance too. Therefor, by induction, proved.

\end{enumerate}
\newpage
\section{Hashing}

\begin{enumerate}[label=(\alph*)]
\item The approximate probability can be calculated by:

\begin{center}
    $P &= {\frac{n*n^{n - \log_2 n}}{n^n}} * {n \choose \log_2 n}$
\end{center}
In the denominator, we have $n^n$ because, n numbers are being assigned and each number has n possible positions that it can go into.\\
In the numerator, we have n, as the maximum chain, could be any one of the n positions in the hash table. and $n\textsuperscript{(n-logn)}$ because $n-logn$ numbers can be assigned to any position and the rest is assigned to the single position. It is also multiplied with n choose ($logn$) because from the n numbers, logn numbers are choosen to be used in the max chain. This final calculation is actually an approximation which is greater than the actual probability, because the expression above actually recounts the same cases multiple times due to the  $n\textsuperscript{(n-logn)}$ factor. And below, we prove that this bigger approximation is lesser than 1/n and thus the probability is also lesser than 1/n.
\begin{center}
    $P &= {\frac{n}{n^\log_2 n}} * {\frac{n!}{(\log_2 n)!(n-\log_2 n)!}}$
\end{center}

\begin{center}
    $P &= \frac{n}{(\log_2 n)!} * {\frac{n(n-1)(n-2)....(n-\log_2 n+1)}{n^{\log_2 n}}}$
\end{center}

\begin{center}
    $P \leq \frac{n}{(\log_2 n)!}$
\end{center}

\begin{center}
    Using Sterling Approximation,
\end{center}

\begin{center}
    $\log(k!) = k*log(k) - k$
\end{center}

\begin{center}
    So, $\log(\log_2 n!) = (\log_2 n)(\log (n/e))$
\end{center}

\begin{center}
    $ \frac{\log(\log_2 n!)}{\log n} = \frac{(\log_2 n)(\log (n/e))}{\log n}$
\end{center}

\begin{center}
    $ \frac{\log(\log_2 n!)}{\log n} = \frac{(\log (n/e))}{\log 2}$
\end{center}

\begin{center}
    For large n,
\end{center}

\begin{center}
    $\frac{(\log (n/e))}{\log 2} > 2$
\end{center}

\begin{center}
    $\frac{\log(\log_2 n!)}{\log n} > 2$
\end{center}

\begin{center}
    $\log(\log_2 n!) > 2*\log n$
\end{center}

\begin{center}
    $\log(\log_2 n!/n^2) > 1$
\end{center}

\begin{center}
    $\log(\log_2 n!/n^2) > 1$
\end{center}

\begin{center}
    So, $\frac{n}{(\log_2 n)!} < \frac{1}{n}$
\end{center}
\item Prove that for any given r $\in$ [1,p-1], there exists at least $M/n \choose n$ subsets of U of size n in which maximum chain length in hash-table corresponding to $H_r(x)$ is $\Theta(n)$.\\
\textbf{Solution:}\\
As x is invertible with rx mod p with the given constraints(given in lecture), rx mod p $\in$ [0,M-1].\\
Take y = rx mod p, then $H_r(x) = H(y)$. \\
The aim is to have a set S such that, when hashed using H(y), all the numbers go to the same spot and the maximum-chain length is n, which is $\Theta(n)$.\\
Assume S = $\{a_1, a_2..... a_n \}$, which implies that, $a_1$ mod n = $a_2$ mod n, $a_2$ mod n = $a_3$ mod n ..... \\
$\implies a_1-a_2$ mod n = 0 ....\\
$\implies a_1 - a_2 = cn$ where c is an integer.\\
$\implies a_1 = b + c_1n$ where b (fixed for a specific set) $\in$ [0,n-1] and $c_1$ $\in$ [0, $(M-1)/n$] as $a_1$ $\in$ [0,M]. \\
All elements in S can be represented in the above form. And all the elements with above form can be put in a set S which satisfies the set constraints we are looking for.\\
As, $c_1$ can have M/n unique values, a set S can choose from M/n numbers while forming the set of n numbers.\\
$\implies$ the possible number of subsets with a fixed b, is {$M/n\choose n$}, whose maximum length is n $\in \Theta(n)$.\\
$\implies$ there exists atleast {$M/n\choose n$} subsets that whose maximum chain length is $\Theta(n)$. {\hfill\qed}

\item The graph plotted is shown below:

\begin{figure}[H]
            \centering
        	\includegraphics[scale=0.65]{plot5.png}
        	\caption{Graph of Maxchain length. \label{fig:1}}
        \end{figure}

        We see that the H() hashing function gives a linear line whereas the Hr() hashing function's max chain seems to be almost constant. This is because, as we increase k, the numbers in the set whose hashing table position is same increases linearly. Due to this, the max chain length too increases. But in the Hr() hashing function, the rx mod p part, helps "randomize" the number before applying the hashing function, thus reducing the max chain length and almost keeping it at a constant level.
\end{enumerate}

The code used to plot is pasted below:
\verbatiminput{4c.py}

%------------------------------------------------

\end{document}


\subsection{Hash-to-curve Functions}
\label{ssec:hash-to-curve}

The contents of this section should not be considered a full proof
of security but are for implementation reference.
Formal treatment of the security proofs for hash-to-curve
functions are handled in referenced works.

We turn our attention to the hash-to-curve functions
implemented in our system.
The contents of this section are described hereafter.
First, we review a mechanism often employed to solve this problem.
Then, we briefly discuss why this solution is not ideal in our setting.
Finally, we introduce the basis of our implementation and proceed into the
definition of the algorithms used in our system after a brief review of
some required mathematical operations.
All algorithms may be found at the end of this section.

The seemingly standard, non-deterministic method to perform a hash-to-curve
operation in the elliptic curve setting is to use the ``MapToGroup''
method as presented in the original BLS short signature
paper~\cite{boneh2001short}.
In this method values are hashed into
$\F_{p}$ by modular arithmetic with a concatenated counter.
This counter starts at a fixed value, and is incremented until
a value is found that creates a valid point on the specified
elliptic curve.
While this may be sufficient in some instances, we prefer
deterministic methods due to the need for bounded
computational overhead.
In our system, the need for bounded computational
overhead arises from a desire to allow an Ethereum smart contract to
perform the hash-to-curve operations with bounded gas consumption.
Deterministic methods also have the benefit of minimizing
side-channel attacks in those
algorithms that require such protection.

The hash-to-curve implementation selected allows the problem space to be
divided into independent problems such that their solutions may be composed.
Specifically, we first hash to the base field
(hash map $\mathfrak{h}:\braces{0,1}^{*}\to \F$)
and then find a deterministic map from the base field
to the elliptic curve (function $f:\F\to E(\F)$).
This approach allows for a separation of concerns and has become a
standard approach to the problem of hashing into an elliptic curve
~\cite{icart2009hash,ft2012bnhashtocurve,boneh2019h2cBLS12}.
Although this strategy does offer a simplified view of the problem,
mapping from the base field to the elliptic curve is nontrivial.
Additionally, it is frequently the case that $f$ is not surjective, but
we can overcome this limitation to obtain a surjective hash-to-curve algorithm
under easily-satisfied
conditions~\cite{tibouchi2014elligator,ft2012bnhashtocurve}.
Specifically, we use domain-separation in order to obtain independent hash
functions.
These independent hash functions allow us overcome a non-surjective
mapping.
We will fully address this concern later in this document.

Our discussion of hashing functions follow
\cite{ft2012bnhashtocurve,boneh2019h2cBLS12}.
We ask the reader to note that in the remaining work of this section,
we view $E(\F_{p})$ as an additive group unless otherwise specified.
We highlight this fact because this is different from the multiplicative
notation used previously in this document.
Before we define our implementation of the hash-to-curve algorithms employed,
we feel a review of the mathematics would benefit the reader.
Thus, we first
review the mathematics necessary to perform the hash-to-curve operations.
After this review, we present the algorithm for hashing to $\G_{1}$
and then present the algorithm for hashing to $\G_{2}$.

For reference, the full \textsc{HashToG1} algorithm can be
found in Alg.~\ref{alg:hash-to-G1} and the full algorithm for \textsc{HashToG2}
can be found in Alg.~\ref{alg:hash-to-G2}.

\subsubsection{Inverses, Square Roots, and Legendre Symbols
    in $\F_{p}$}
\label{sssec:finite_math_Fp}

In this section we review some finite field mathematics that are
important in our hash-to-curve setting.

We begin by reviewing inversion in $\F_{p}$.
First, we recall $\F_{p}^{*} \equiv \F_{p}\setminus\braces{0}$,
the nonzero elements of our finite field.
For $a\in\F_{p}^{*}$, we have Euler's formula:

\begin{equation}
    a^{p-1} = 1 \mod p.
\end{equation}

\noindent
This implies $a^{-1} \mod p = a^{p-2}$.
We acknowledge more efficient methods for computing modular inverses are
possible, but exponentiation can easily be performed in constant time, which
is a goal of our implementation. This concludes our discussion of computing
inverses in $\F_{p}$.

We now review the mechanisms for
computing Legendre symbols.
We recall that $a\in\F_{p}^{*}$ is a \emph{quadratic residue}
if there is $x\in\F_{p}$ such that $x^{2} = a \mod p$;
otherwise, $a$ is a called a \emph{quadratic nonresidue}.
This allows us to define the Legendre symbol~\cite{imc2008}:

\begin{equation}
    \chi_{p}(a) \equiv \begin{cases}
        1 \quad& \text{if there $a$ is a quadratic residue modulo $p$.} \\
        -1 \quad& \text{if there $a$ is a quadratic nonresidue modulo $p$.} \\
        0 \quad& \text{if $p \mid a$}
    \end{cases}
\end{equation}

\noindent
The Legendre symbol has a simple formula:

\begin{equation}
    \chi_{p}(a) = a^{\frac{p-1}{2}}.
\end{equation}

\noindent
This formula holds even when $a=0$.
This concludes our discussion of computing the Legendre Symbol in $\F_{p}$.

Computing square roots is more challenging.
We now review the mechanism of computing square roots.
In our case $p = 3\mod 4$, so there is a simple
formula to solve $x^{2} = a$:

\begin{equation}
    x = a^{\frac{p+1}{4}}.
\end{equation}

\noindent
This relies on the assumption that $a$ is a quadratic residue,
so $a^{\frac{p-1}{2}} = 1$.
This concludes our discussion of computing the square roots in $\F_{p}$.

Taking inverses, Legendre symbols, and square roots
gives us the necessary tools to hash to $\G_{1}$.
This ends the preliminary work necessary to develop
\textsc{HashToG1}.

\subsubsection{Inverses, Square Roots, and Legendre Symbols
    in $\F_{p^{2}}$}
\label{sssec:finite_math_Fp2}

The previous section reviewed the mathematics of inverses, square roots, and
Legendre Symbols in $\F_{p}$.
We must be able to perform the same operations
in $\F_{p^{2}}$ if we wish to hash to $\G_{2}$.
While computing square roots and
inverses may be familiar to the reader in $\F_{p}$, the operations require
special handling in $\F_{p^{2}}$.
We review these mechanisms now.

We first address the problem of computing inverses in $\F_{p^{2}}$.
Our discussion and methods follow~\cite{adj2012sqrtEvenExt},
and we present their general results applied to our particular case.
As mentioned above, the setting of our elliptic curve is $p = 3\mod 4$.
This implies $-1$ is a quadratic nonresidue.
Thus, we have the following isomorphism:

\begin{equation}
    \F_{p^{2}} \simeq \F_{p}[i]/\parens{i^{2}+1}.
\end{equation}

\noindent
This is the analogous to constructing the complex numbers $\C$ from
the real numbers $\R$.
Our implementation uses this construction. We may use
this construction to compute an efficient inversion as follows:

\begin{equation}
    \parens{a_{0} + a_{1}i}^{-1} = \frac{a_{0}-a_{1}i}{a_{0}^{2}+a_{1}^{2}}.
\end{equation}

\noindent
The main computational cost of this operation is the inversion of an element
in $\F_{p}$.
This concludes our discussion of computing inverses in $\F_{p^{2}}$.

We now begin our discussion of computing the Legendre Symbol in $\F_{p^{2}}$
If $a = a_{0} + a_{1}i\in\F_{p^{2}}$, then $a$ is a
quadratic residue in $\F_{p^{2}}$ if and only if $a_{0}^{2} + a_{1}^{2}$
is a quadratic residue in $\F_{p}$.
The main computational cost of this operation is the computation of the Legendre
symbol of an element in $F_{p}$.
From the above we have the Legendre symbol in $\F_{p^{2}}$,
which we denote as \textsc{LegendreFP2} or $\chi_{p^{2}}(\cdot)$;
this particular algorithm is presented in
Alg.~\ref{alg:legendre-fp2}.
This concludes our discussion of computing the Legendre Symbol in
$\F_{p^{2}}$.

We will now look at computing square roots in $\F_{p^{2}}$.
The main idea is to find $b\in\F_{p^{2}}$ and odd $s$ such
$b^{2}a^{s} = 1$.
In this case, we see

\begin{align}
    \brackets{ba^{\frac{s+1}{2}}}^{2} &= b^{2}a^{s+1} \nonumber\\
        &= a.
\end{align}

\noindent
If we set

\begin{align}
    b &= \parens{1 + a^{\frac{p-1}{2}}}^{\frac{p-1}{2}} \nonumber\\
    s &= \frac{p-1}{2},
\end{align}

\noindent
then when $b\ne0$, we have $b^{2}a^{s} = 1$.
When $b=0$, we have $a^{\frac{p-1}{2}}=-1$.
In this case, our square root is $ia^{\frac{p+1}{4}}$.
This procedure is formally presented in~Alg.~\ref{alg:sqrt-fp2}.
The main computational cost of this operation is two exponentiations
in $\F_{p^{2}}$.
This concludes our discussion of computing square roots in $\F_{p^{2}}$
and the preliminary review of those operations
necessary to develop \textsc{HashToG2}.

\subsubsection{Hashing to Base}
\label{sssec:hash-to-base}

In this section we will describe the hash-to-base operation.
We begin by discussing the construction of a random oracle into
$\F_{p}$ using a single cryptographic hash function with
domain separation.
We then bound the deviation from uniformity in this operation.

In the following $H$ is a $256$-bit hash function.
In our implementation we use \textsc{Keccak256}.
Note this is the \textsc{Sha3} variant used by Ethereum
that differs from the NIST approved \textsc{Sha3} hash function due to a
difference in the handling of padding.

Let $H$ act as a random oracle.
We map from $H$ to $\Z$ by interpreting the output of a
cryptographic hash function as a big endian unsigned integer.
This can be seen in lines 4 and 5 of $\textsc{HashToBase}$
as the function named $\texttt{b2u}$.
Although we may naively map from $\Z$ to $\Z_{p}$ by simply taking the
output of $H$ modulo $p$, this would be insecure in our setting due to the
nonuniformity of this operation.
In order to ensure the mapping from $\Z$ to $\Z_{p}$ is more
uniformly distributed, domain separation is utilized.
Specifically, we use domain separation in order obtain independent hash
functions from $H$ through concatenation of constants with the message being
hashed.
These independent hash functions allow us to create a secure 512-bit random
number from a single cryptographic hash function.
The full explanation of this operation is below.

Let $\textsc{HashToBase}:\braces{0,1}^{*}\times\braces{0,1}^{8}\times
\braces{0,1}^{8}\to\F_{p}$ denote our random oracle into the
underlying field $\F_{p}$.
In the $\textsc{HashToBase}$ operation the first component corresponds to the
underlying message being hashed, while the last two elements provide the
necessary domain separation.
See Alg.~\ref{alg:hash-to-fp} for the full implementation.

Due to the fact $p$ is prime and not a power of 2, there will be some
nonuniformity in the resulting distribution of \textsc{HashToBase}.
We investigate this nonuniformity now.

First, we assume that $H:\braces{0,1}^{*}\to\Z_{N}$
is a random oracle and $p\in\braces{1,2,\cdots,N-1}$.
We want to determine how much $H(m)\mod p$ deviates from uniformity.
We restrict ourselves to the case when $p\nmid N$.
Let

\begin{equation}
    N = qp + r
\end{equation}

\noindent
with $0\le r< p$ and $q\ge1$.
Because $p\nmid N$, we have $r\ge1$.
Let $X$ be uniformly distributed on $\Z_{N}$ and set $X_{p} = X \mod p$.
Furthermore, we let $U_{p}$ be the uniform distribution modulo $p$.
Then

\begin{equation}
    \mathcal{P}\parens{X_{p}\in\braces{0,\cdots,r-1}} = \frac{q+1}{N}
\end{equation}

\noindent
and

\begin{equation}
    \mathcal{P}\parens{X_{p}\in\braces{r,\cdots,p-1}} = \frac{q}{N}.
\end{equation}

\noindent
Here, $\mathcal{P}$ denotes the probability of an event occurring.
We now determine the deviation of $X_{p}$ from the uniform
distribution $U_{p}$:

\begin{align}
    \Delta\parens{X_{p},U_{p}} &\equiv
        \sum_{k=0}^{p-1} \abs{\mathcal{P}(X_{p}=k) - \mathcal{P}(U_{p}=k)}
        \nonumber\\
    &= \sum_{u=0}^{r-1} \abs{\frac{q+1}{N} - \frac{1}{p}} +
        \sum_{u=r}^{p-1} \abs{\frac{q}{N} - \frac{1}{p}} \nonumber\\
    &= r\frac{qp + p - N}{pN} + \parens{p-r}\frac{N-qp}{pN}
        \nonumber\\
    &\le \frac{p}{N}.
\end{align}

\noindent
From this, we see that if $p$ is a $k$-bit prime and
$N = 2^{k+\ell}$, then the deviation from uniformity is $\le2^{-\ell}$.

In our case, $p$ is a 254-bit prime and we concatenate the output
of independent hash functions in order to have a uniformly distributed
512-bit output.
From the above it may be seen that \textsc{HashToBase} produces outputs whose
deviation from uniformity is less than $2^{-258}$.
This deviation is sufficiently small as to not be of concern.
Further work is required to more formally prove this assumption, but
this work is not included at this time.

\subsubsection{Base to $\G_{1}$}
\label{sssec:base-to-G1}

In this section we discuss the construction of a hash-to-G1 algorithm.
We begin by noting the non-surjective nature for many functions
$f:\F_{p}\to E(\F_{p})$.
Then, we cite a known solution to this problem and provide necessary
mathematics to understand the fundamental operation that
overcomes the problem.
Next, we discuss the actual implementation.
Lastly, we discuss specific exclusion of three points from the allowable
outputs of this algorithm for security purposes.

Let us now suppose that we have a hash function
$\mathfrak{h}:\braces{0,1}^{*}\to\F_{p}$ and a
deterministic map $f:\F_{p}\to E(\F_{p})$.
As has been previously stated, in many
situations~\cite{icart2009hash,ft2012bnhashtocurve,boneh2019h2cBLS12}
$f$ is not surjective.
That is, there are points on the elliptic curve $E(\F_{p})$
(sometimes a nontrivial fraction) which cannot be reached by $f$.
Even so, if we use domain separation to construct independent hash functions,
$\mathfrak{h}_{1}, \mathfrak{h}_{2}:\braces{0,1}^{*}\to\F$,
then

\begin{equation}
    F(\texttt{m}) = f(\mathfrak{h}_{1}(\texttt{m}))
                    + f(\mathfrak{h}_{2}(\texttt{m}))
\end{equation}

\noindent
is indistinguishable from a random oracle on $E(\F_{p})$
under certain restrictions on $f$.
See~\cite{ft2012bnhashtocurve,tibouchi2014elligator} for details.

We now turn our attention to determining $f:\F_{p}\to E(\F_{p})$.
Finding a map $f:\F_{p}\to E(\F_{p})$ is involved.
Our BN curve has the form

\begin{align}
    E:y^{2} &= g(x) \nonumber\\
            &= x^{3} + b.
\end{align}

\noindent
From~\cite{ft2012bnhashtocurve}, it possible to show there
are $x_{1},x_{2},x_{3},y\in\F_{p}$ such that

\begin{equation}
    g(x_{1})g(x_{2})g(x_{3}) = y^{2}.
\end{equation}

\noindent
When $y\ne0$, quadratic reciprocity implies that $g(x_{i})$ is square
for some $i$; that is, for some $i$ we have
$(x_{i},\sqrt{g(x_{i})})\in E(\F_{p})$.
For uniqueness, we choose the smallest $i$.
We will use the construction of~\cite{ft2012bnhashtocurve}
to determine such points with some modifications based
on work in~\cite{boneh2019h2cBLS12}.
The exact algorithm can be found in Alg.~\ref{alg:base-to-G1}.

One of the main difficulties is determining $i$ in such a way
as to not leak information; because of this, we do not wish to
rely upon if statements.
In~\cite{ft2012bnhashtocurve}, they suggested the function

\begin{equation}
    \psi(r_{1},r_{2}) = \brackets{\parens{r_{1}-1}r_{2}\mod3} + 1.
    \label{eq:ftAB}
\end{equation}

\noindent
This function works under the assumption that modular
arithmetic always returns positive integers.
This is not always the case in programming languages;
in particular, it does not hold in \textsc{Go} (Golang), the language
we use to implement these algorithms.
To circumvent this, we use the following function,
which is implemented in Line~\ref{alg_line:new_coef_func}
of Alg.~\ref{alg:base-to-G1}:

\begin{equation}
    \parens{r_{1}-1}\parens{r_{2}-3}/4 + 1.
    \label{eq:newAB}
\end{equation}

In~\cite{ft2012bnhashtocurve}, the authors encountered an issue when $t=0$.
Their solution was to define

\begin{equation}
    \textsc{BaseToG1}(0) = \parens{\frac{-1+\sqrt{-3}}{2}, \sqrt{1+b}}.
    \label{eq:baseToG1zero}
\end{equation}

\noindent
Wahby and Boneh~\cite{boneh2019h2cBLS12} suggest another
method, which we implement, in order to have a more efficient
algorithm.
This implementation also affords the benefit of not needing to
handle the case of $t=0$ separately.
This can be seen in Line~\ref{alg_line:alpha_def}
of Alg.~\ref{alg:base-to-G1} where we define $\alpha$ as the inverse
of a value which depends on $t\in\F_{p}$.
When $t=0$, we compute $\alpha = 0$
because we compute inversions via exponentiation.
Thus, the computational convention $0^{-1} = 0 \mod p$ is established.
This leads to the same result as in Eq.~\eqref{eq:baseToG1zero}
without special handling.

We have cryptographic insecurity when
$\textsc{HashToG1}(\texttt{m}) = g_{1}^{\alpha}$ for known $\alpha$.
Note we briefly switch back to multiplicative notation at this time.
In practice, it is likely this insecurity will only be known when
$\alpha\in\braces{-1,0,1}$ or is sufficiently close to these values.
We assume we may not fix simple proximity to these values, and thus only
explicitly address the case of $\alpha\in\braces{-1,0,1}$.
For clarity, this notation specifies the hash function outputs of
the identity element, the generator, or the generator's
inverse.
Due to the concerns around the use of these points, we will not allow these
individual cases.
In order to enforce this requirement we include a
\textsc{SafePointCheck} in \textsc{HashToG1};
see Line~\ref{alg_line:safe_point_check} in Alg.~\ref{alg:hash-to-G1}.
This function checks the point returned from the hash function for
equivalence with the identity element OR equivalence of the point's
$x$ coordinate with $1$.
If either of these conditions is true, an error is raised.
Although the probability of a hash mapping to these points is small, this
error must be handled appropriately to prevent an attacker from causing
unexpected errors in a remote system due to specially crafted messages.

\subsubsection{Base to $\G_{2}$}
\label{sssec:base-to-G2}

We now take up the slightly more challenging possibility
of computing a hash function to $\G_{2}$.
Fortunately, we may utilize many of
the previously described operations.
Thus, we do not repeat those explanations and only discuss
those operations that differ.
We would like to remind the reader that the results in
Sec.~\ref{sssec:finite_math_Fp2} allow
us to compute Legendre symbols and square roots in $\F_{p^{2}}$.

Using the derivation of~\cite[Section 3]{boneh2019h2cBLS12},
we set $u_{0}=1$ as in $\G_{1}$ to obtain

\begin{align}
    x_{1} &= \frac{\sqrt{-3}-1}{2} - \frac{t^{2}\sqrt{-3}}{t^{2}+g'(1)}
        \nonumber\\
    x_{2} &= -1 - x_{2} \nonumber\\
    x_{3} &= 1 - \frac{\parens{t^{2}+g'(1)}^{2}}{3t^{2}},
\end{align}

\noindent
for $t\in\F_{p^{2}}$.
Here, we have

\begin{equation}
    E':y^{2} = g'(x) = x^{3} + b',
\end{equation}

\noindent
where $b' = b/\xi = 3/\parens{i+9}$.
With this choice, $-g'(1)$ is a residue in $\F_{p^{2}}$.
This ensures that $t\in\{0,\pm\sqrt{-g'(1)}\}$
implies $x_{1}$ is a valid point on the curve;
thus, all inputs result in valid outputs.
See Alg.~\ref{alg:base-to-twist} for the algorithm.
Thus, our hash functions to $\G_{1}$ and $\G_{2}$ are
essentially the same.

At this point, we have successfully mapped into $E'$;
however, our goal is to map into $\G_{2}$.
From~\cite{bnCurves}, we know $\abs{E'(\F_{p^{2}})} = q\parens{2p-q}$.
This gives a cofactor $r = 2p-q$ because $p\nmid q$.
We take care of this by clearing the cofactor.
See Alg.~\ref{alg:hash-to-G2} for the full hash algorithm.

\clearpage

\input{algs/hash_to_G1.tex}

\input{algs/gfp2_algs.tex}

\input{algs/hash_to_G2.tex}


\section{SOLVE Operator}\ttindex{SOLVE}
SOLVE is an operator for solving one or more simultaneous algebraic
equations. It is used with the syntax:
\begin{verbatim}
  SOLVE(EXPRN:algebraic[,VAR:kernel|,VARLIST:list of kernels])
         :list.
\end{verbatim}
{\tt EXPRN} is of the form {\tt <expression>} or
\{ {\tt <expression1>},{\tt <expression2>}, \dots \}.  Each expression is an
algebraic equation, or is the difference of the two sides of the equation.
The second argument is either a kernel or a list of kernels representing
the unknowns in the system.  This argument may be omitted if the number of
distinct, non-constant, top-level kernels equals the number of unknowns,
in which case these kernels are presumed to be the unknowns.

For one equation, {\tt SOLVE}\ttindex{SOLVE} recursively uses
factorization and decomposition, together with the known inverses of
{\tt LOG}, {\tt SIN}, {\tt COS}, {\tt \verb|^|}, {\tt ACOS}, {\tt ASIN}, and
linear, quadratic, cubic, quartic, or binomial factors. Solutions
of equations built with exponentials or logarithms are often
expressed in terms of Lambert's {\tt W} function.\index{Lambert's W}
This function is (partially) implemented in the special functions package.

Linear equations are solved by the multi-step elimination method due to
Bareiss, unless the switch {\tt CRAMER}\ttindex{CRAMER} is on, in which
case Cramer's method is used.  The Bareiss method is usually more
efficient unless the system is large and dense.

Non-linear equations are solved using the Groebner basis package.
\index{Groebner} Users should note that this can be quite a
time consuming process.

{\it Examples:}
\begin{verbatim}
            solve(log(sin(x+3))^5 = 8,x);
            solve(a*log(sin(x+3))^5 - b, sin(x+3));
            solve({a*x+y=3,y=-2},{x,y});
\end{verbatim}

{\tt SOLVE} returns a list of solutions.  If there is one unknown, each
solution is an equation for the unknown.  If a complete solution was
found, the unknown will appear by itself on the left-hand side of the
equation.  On the other hand, if the solve package could not find a
solution, the ``solution'' will be an equation for the unknown in terms
of the operator {\tt ROOT\_OF}\ttindex{ROOT\_OF}. If there
are several unknowns, each solution will be a list of equations for the
unknowns.  For example,
\begin{verbatim}
     solve(x^2=1,x);             -> {X=-1,X=1}

     solve(x^7-x^6+x^2=1,x)
                            6
            -> {X=ROOT_OF(X_  + X_ + 1,X_,TAG_1),X=1}

     solve({x+3y=7,y-x=1},{x,y}) -> {{X=1,Y=2}}.
\end{verbatim}
The TAG argument is used to uniquely identify those particular solutions.
Solution multiplicities are stored in the global variable {\tt
ROOT\_MULTIPLICITIES} rather than the solution list.  The value of this
variable is a list of the multiplicities of the solutions for the last
call of {\tt SOLVE}. \ttindex{SOLVE} For example,
\begin{verbatim}
       solve(x^2=2x-1,x); root_multiplicities;
\end{verbatim}
gives the results
\begin{verbatim}
        {X=1}

        {2}
\end{verbatim}

If you want the multiplicities explicitly displayed, the switch
{\tt MULTIPLICITIES}\ttindex{MULTIPLICITIES} can be turned on. For example
\begin{verbatim}
        on multiplicities; solve(x^2=2x-1,x);
\end{verbatim}
yields the result
\begin{verbatim}
        {X=1,X=1}
\end{verbatim}

\subsection{Handling of Undetermined Solutions}
When {\tt SOLVE} cannot find a solution to an equation, it normally
returns an equation for the relevant indeterminates in terms of the
operator {\tt ROOT\_OF}.\ttindex{ROOT\_OF}  For example, the expression
\begin{verbatim}
        solve(cos(x) + log(x),x);
\end{verbatim}
returns the result
\begin{verbatim}
       {X=ROOT_OF(COS(X_) + LOG(X_),X_,TAG_1)} .
\end{verbatim}

An expression with a top-level {\tt ROOT\_OF} operator is implicitly a
list with an unknown number of elements (since we don't always know how
many solutions an equation has).  If a substitution is made into such an
expression, closed form solutions can emerge.  If this occurs, the {\tt
ROOT\_OF} construct is replaced by an operator {\tt ONE\_OF}.\ttindex{ONE\_OF}
At this point it is of course possible to transform the result of the
original {\tt SOLVE} operator expression into a standard {\tt SOLVE}
solution.  To effect this, the operator {\tt EXPAND\_CASES}
\ttindex{EXPAND\_CASES} can be used.

The following example shows the use of these facilities:
\extendedmanual{\newpage}
\begin{verbatim}
solve(-a*x^3+a*x^2+x^4-x^3-4*x^2+4,x);
              2     3
{X=ROOT_OF(A*X_  - X_  + 4*X_ + 4,X_,TAG_2),X=1}

sub(a=-1,ws);

{X=ONE_OF({2,-1,-2},TAG_2),X=1}

expand_cases ws;

{X=2,X=-1,X=-2,X=1}
\end{verbatim}

\subsection{Solutions of Equations Involving Cubics and Quartics}

Since roots of cubics and quartics can often be very messy, a switch
{\tt FULLROOTS}\ttindex{FULLROOTS} is available, that, when off (the
default), will prevent the production of a result in closed form.  The
{\tt ROOT\_OF} construct will be used in this case instead.

In constructing the solutions of cubics and quartics, trigonometrical
forms are used where appropriate.  This option is under the control of a
switch {\tt TRIGFORM},\ttindex{TRIGFORM} which is normally on.

The following example illustrates the use of these facilities:
\begin{verbatim}
let xx = solve(x^3+x+1,x);

xx;
             3
{X=ROOT_OF(X_  + X_ + 1,X_)}

on fullroots;

xx;

                           - SQRT(31)*I
                    ATAN(---------------)
                            3*SQRT(3)
{X=(I*(SQRT(3)*SIN(-----------------------)
                              3
\end{verbatim}
\newpage
\begin{verbatim}
                      - SQRT(31)*I
               ATAN(---------------)
                       3*SQRT(3)
        - COS(-----------------------)))/SQRT(3),
                         3

                              - SQRT(31)*I
                       ATAN(---------------)
                               3*SQRT(3)
 X=( - I*(SQRT(3)*SIN(-----------------------)
                                 3

                         - SQRT(31)*I
                  ATAN(---------------)
                          3*SQRT(3)
           + COS(-----------------------)))/SQRT(
                            3

      3),

                  - SQRT(31)*I
           ATAN(---------------)
                   3*SQRT(3)
    2*COS(-----------------------)*I
                     3
 X=----------------------------------}
                SQRT(3)

off trigform;

xx;
                             2/3
{X=( - (SQRT(31) - 3*SQRT(3))   *SQRT(3)*I

                             2/3    2/3
     - (SQRT(31) - 3*SQRT(3))    - 2   *SQRT(3)*I

        2/3                           1/3  1/3
     + 2   )/(2*(SQRT(31) - 3*SQRT(3))   *6

                1/6
              *3   ),

                          2/3
 X=((SQRT(31) - 3*SQRT(3))   *SQRT(3)*I

                             2/3    2/3
     - (SQRT(31) - 3*SQRT(3))    + 2   *SQRT(3)*I

        2/3                           1/3  1/3
     + 2   )/(2*(SQRT(31) - 3*SQRT(3))   *6

                1/6
              *3   ),

                           2/3    2/3
     (SQRT(31) - 3*SQRT(3))    - 2
 X=-------------------------------------}
                          1/3  1/3  1/6
    (SQRT(31) - 3*SQRT(3))   *6   *3
\end{verbatim}

\subsection{Other Options}

If {\tt SOLVESINGULAR}\ttindex{SOLVESINGULAR} is on (the default setting),
degenerate systems such as {\tt x+y=0}, {\tt 2x+2y=0} will be solved by
introducing appropriate arbitrary constants.
The consistent singular equation 0=0 or equations involving functions with
multiple inverses may introduce unique new indeterminant kernels
{\tt ARBCOMPLEX(j)}, or {\tt ARBINT(j)}, ($j$=1,2,...),  % {\tt ARBREAL(j)},
representing arbitrary complex or integer numbers respectively.  To
automatically select the principal branches, do {\tt off allbranch;} .
\ttindex{ALLBRANCH} To avoid the introduction of new indeterminant kernels
do {\tt OFF ARBVARS}\ttindex{ARBVARS} -- then no equations are generated for the free
variables and their original names are used to express the solution forms.
To suppress solutions of consistent singular equations do
{\tt OFF SOLVESINGULAR}.

To incorporate additional inverse functions do, for example:
\begin{verbatim}
        put('sinh,'inverse,'asinh);
        put('asinh,'inverse,'sinh);
\end{verbatim}
together with any desired simplification rules such as
\begin{verbatim}
        for all x let sinh(asinh(x))=x, asinh(sinh(x))=x;
\end{verbatim}
For completeness, functions with non-unique inverses should be treated as
{\tt \verb|^|}, {\tt SIN}, and {\tt COS} are in the {\tt SOLVE}
\ttindex{SOLVE} module source.

Arguments of {\tt ASIN} and {\tt ACOS} are not checked to ensure that the
absolute value of the real part does not exceed 1; and arguments of
{\tt LOG} are not checked to  ensure that the absolute value of the imaginary
part does not exceed $\pi$; but checks (perhaps involving user response
for non-numerical arguments) could be introduced using
{\tt LET}\ttindex{LET} statements for these operators.

\subsection{Parameters and Variable Dependency}

The proper design of a variable sequence
supplied as a second argument to {\tt SOLVE} is important
for the structure of the solution of an equation system.
Any unknown in the system
not in this list is considered totally free. E.g.\  the call
\begin{verbatim}
    solve({x=2*z,z=2*y},{z});
\end{verbatim}
produces an empty list as a result because there is no function
$z=z(x,y)$ which fulfills both equations for arbitrary $x$ and $y$ values.
In such a case the share variable {\tt requirements}\ttindex{requirements}
displays a set of restrictions for the parameters of the system:
\begin{verbatim}
    requirements;

    {x - 4*y}
\end{verbatim}
The non-existence of a formal solution is caused by a
contradiction which disappears only if the parameters
of the initial system are set such that all members
of the requirements list take the value zero.
For a linear system the set is complete: a solution
of the requirements list makes the initial
system solvable. E.g.\  in the above case a substitution
$x=4y$ makes the equation set consistent. For a non-linear
system only one inconsistency is detected. If such a system
has more than one inconsistency, you must reduce them
one after the other.
\footnote{
The difference between linear and non--linear
inconsistent systems is based on the algorithms which
produce this information as a side effect when attempting
to find a formal solution; example:
$solve(\{x=a,x=b,y=c,y=d\},\{x,y\}$ gives a set $\{a-b,c-d\}$
while $solve(\{x^2=a,x^2=b,y^2=c,y^2=d\},\{x,y\}$ leads to $\{a-b\}$.
}
The  set shows you also the dependency among the parameters: here
one of $x$ and $y$ is free and a formal solution of the system can be
computed by adding it to the variable list of {\tt solve}.
The requirement set is not unique -- there may be other such sets.

A system  with parameters may have a formal solution, e.g.\
\begin{verbatim}
     solve({x=a*z+1,0=b*z-y},{z,x});

        y     a*y + b
   {{z=---,x=---------}}
        b        b
\end{verbatim}
which is not valid for all possible values of the parameters.
The variable {\tt assumptions}\ttindex{assumptions} contains then a list of
restrictions: the solutions are valid only as long
as none of these expressions vanishes. Any zero of one of them
represents a special case that is not covered by the
formal solution. In the above case the value is
\extendedmanual{\newpage}
\begin{verbatim}
    assumptions;

    {b}
\end{verbatim}
which excludes formally the case $b=0$; obviously this special
parameter value makes the system singular. The set of assumptions
is complete for both, linear and non--linear systems.

{\tt SOLVE} rearranges the variable sequence
to reduce the (expected) computing time. This behavior is controlled
by the switch {\tt varopt}\ttindex{varopt}, which is on by default.
If it is turned off, the supplied variable sequence is used
or the system kernel ordering is taken if the variable
list is omitted. The effect is demonstrated by an example:
\begin{verbatim}
   s:= {y^3+3x=0,x^2+y^2=1};

   solve(s,{y,x});

                  6       2
   {{y=root_of(y_  + 9*y_  - 9,y_),

            3
         - y
     x=-------}}
          3

   off varopt; solve(s,{y,x});

                  6       4        2
   {{x=root_of(x_  - 3*x_  + 12*x_  - 1,x_),

               4      2
        x*( - x  + 2*x  - 10)
     y=-----------------------}}
                  3

\end{verbatim}
In the first case, {\tt solve} forms the solution as a set of
pairs $(y_i,x(y_i))$ because the degree of $x$ is higher --
such a rearrangement makes the internal computation of the Gr\"obner basis
generally faster. For the second case the explicitly given variable sequence
is used such that the solution has now the form $(x_i,y(x_i))$.
Controlling the variable sequence is especially important if
the system has one or more free variables.
As an alternative to turning off {\tt varopt}, a partial dependency among
the variables can be declared using the {\tt depend}\index{depend}
statement: {\tt solve} then rearranges the variable sequence but keeps any
variable ahead of those on which it depends.
\extendedmanual{\newpage}
\begin{verbatim}
   on varopt;
   s:={a^3+b,b^2+c}$
   solve(s,{a,b,c});

                           3       6
   {{a=arbcomplex(1),b= - a ,c= - a }}

   depend a,c; depend b,c; solve(s,{a,b,c});

   {{c=arbcomplex(2),

                 6
     a=root_of(a_  + c,a_),

           3
     b= - a }}
\end{verbatim}
Here {\tt solve} is forced to put $c$ after $a$ and after $b$, but
there is no obstacle to interchanging $a$ and $b$.


\begin{questions}

\question{ Modify the code \texttt{fluidflowFD.m} to solve the equations
\begin{align*}
 w_t + \psi_y w_x - \psi_xw_y &= Pr \Delta w + RaPrT_x, \\
 T_t + \psi_y T_x - \psi_xT_y &= \Delta T, \\
\Delta \psi &= -w,
\end{align*}
where $(x,y) \in (0,1) \times (0,1)$ and $t>0$. For this exercise, set $Ra = 2 \times 10^5$ and $Pr = 0.71$ (air).

The fluid is at rest at $t=0$, with $T = \psi = w = 0$. The boundary conditions for the stream function is $\psi_{Gamma} = 0$, which implies that there is no mass transfer through the boundary $\Gamma$. The value of the vorticity at the walls is expressed as $w_{\Gamma} = -\Delta \psi_{\Gamma}$ and the temperature at $\Gamma$ is defined by
\begin{align*}
T(t,x,y) = \begin{cases}
2^9\tanh^4(100t)x^5(x-1)^4,& y =0,~0\leq x \leq 1,~t>0, \\
0, & (x,y) \in \Gamma,~y\neq 0,~t>0.
\end{cases}
\end{align*}

}

\begin{solution}

\begin{figure}[H]
\center{\includegraphics[scale=.5]{p4_f1.eps}}
\caption{Solution at $ t=1$ second}
\end{figure}

\end{solution}

\end{questions}

\subsubsection*{MATLAB}

   \begin{verbatim}
function HW6P4
% Parameters
N = 150;
Ra = 2e5;
Pr = 0.71;
dt = 1e-5;

h = 1/N; % N+1 points in each direction
[xx,yy] = meshgrid(0:h:1); % 2D gridpoints

% Laplacian with zero BCs
o = ones(N-1,1);
D2 = (diag(-2*o) + diag(o(1:N-2),-1)+ diag(o(1:N-2),1))/h^2;
% We need evals and evects to solve Poisson equation
[eV,eval] = eig(D2); lam = diag(eval);

% Initial condition & pre-allocate memory (start with zeros at t = 0)
u = 0*xx; v = u; w = u; str = u; T = u;

% boundary condition
%u(N+1,:) = 1;
ii = 2:N; jj = 2:N;  % index for interior nodes
wi = zeros(N-1,N-1); % interior values of vorticity
Ti = zeros(N-1,N-1); % interior values of temperature

count = 0;
t = 0;
Nplot = round(0.1/dt);
% main loop
while t<50
    if mod(count,1000) == 0
        sprintf('%d -- %f -- %f -- %f -- %f',count,t,norm(str,inf),...
            norm(w,inf),norm(T,inf));
    end

   % update temperature at boundary
   T = BCT(T,xx,t);

    % update vorticity at boundary
   w = BCw(u,v,w);

   % advance temperature with forward Euler
   [Trh,Tx] = Trhs(u,v,T);
   Ti = Ti + dt*Trh;
   T(ii,jj) = Ti;

   % advance vorticity with forward Euler
   wi = wi + dt*wrhs(u,v,w,Pr,Ra,Tx);
   w(ii,jj) = wi;

   % compute stream function with conjugate gradient
   str(2:end-1,2:end-1) = SolvePoisson(wi);

   % update velocity (interior nodes only)
   u(ii,jj) =  (str(ii+1,jj)-str(ii-1,jj))/(2*h);
   v(ii,jj) = -(str(ii,jj+1)-str(ii,jj-1))/(2*h);

   t = t+dt;
   count = count + 1;

   % Plot results every now and then
   if count == Nplot
       plotresults(u,v,w,T,str);
       shg
       count = 0;
       disp(t)
       sprintf('%f -- %f -- %f',norm(T,inf),norm(w,inf),norm(str,inf));
   end

end

    % Solve Poisson equation (Sylvester equation)
    function S = SolvePoisson(wi)
        ff = -eV'*wi*eV;
        S = ff;
        for j = 1:N-1
            S(:,j) = ff(:,j)./(lam(j)+lam);
        end
        S = eV*S*eV';
    end

    % Right-hand side of vorticity equation
    function wrh = wrhs(u,v,w,Pr,Ra,Tx)
        wx = (w(ii,jj+1)-w(ii,jj-1))/(2*h);
        wy = (w(ii+1,jj)-w(ii-1,jj))/(2*h);
        Lw = (w(ii,jj+1)+w(ii,jj-1)+w(ii+1,jj)+w(ii-1,jj)-4*w(ii,jj))/h^2;
        wrh = -u(ii,jj).*wx - v(ii,jj).*wy + (Pr)*Lw + Ra*Pr*Tx;
    end

 % Right-hand side of Temperature equation
    function [Trh,Tx] = Trhs(u,v,T)
        Tx = (T(ii,jj+1)-T(ii,jj-1))/(2*h);
        Ty = (T(ii+1,jj)-T(ii-1,jj))/(2*h);
        LT = (T(ii,jj+1)+T(ii,jj-1)+T(ii+1,jj)+T(ii-1,jj)-4*T(ii,jj))/h^2;
        Trh = -u(ii,jj).*Tx - v(ii,jj).*Ty + LT;
    end

   function w = BCw(u,v,w)
        % three point sided FD formula (second order accurate)
        w(1,:) = -(-3*u(1,:)+4*u(2,:)-u(3,:))/(2*h);      % = -u_y @ y = 0
        w(N+1,:) = (-3*u(N+1,:)+4*u(N,:)-u(N-1,:))/(2*h); % = -u_y @ y = 1
        w(:,1) = (-3*v(:,1)+4*v(:,2)-v(:,3))/(2*h);       % =  v_x @ x = 0
        w(:,N+1) = -(-3*v(:,N+1)+4*v(:,N)-v(:,N-1))/(2*h);% =  v_x @ x = 1
    end
 % Enforce boundary condition (Temperature)
    function T = BCT(T,xx,t)
        %T0 = @(x,y,t) 2^9 * tanh(100*t)^4 * x.^5 .* (x-1).^4 .* (y==0);
        %T(1,:) = T0(x(1,:),y(1,:),t);
        T(1,:) = 2^9*(tanh(100*t))^4*(xx(1,:).^5).*(xx(1,:)-1).^4;
        %T(N+1,:) = 0;
        %T(:,1) = 0;
        %T(:,N+1) = 0;
    end

    % Plot results
    function plotresults(u,v,w,T,str)
       % Use a subset of gridpoints
       ip = 1:3:N+1;
       up = u(ip,ip); vp = v(ip,ip);
       xp = xx(ip,ip); yp = yy(ip,ip);

       % Velocity
       subplot(2,2,1)
       quiver(xp,yp,up,vp,10)
       axis([0 1 0 1]), axis square
       title('velocity field','fontsize',16)

       % Temperature
       subplot(2,2,2)
       contourf(xx,yy,T);
       H = colorbar; set(H,'fontsize',16)
       axis square, title('Temperature','fontsize',16)

       % Stream function
       subplot(2,2,3)
       mp = max(max(str));
       mm = min(min(str));
       contour(xx,yy,str,-logspace(-10,log10(-mm),30),'r'),  hold on
       contour(xx,yy,str, logspace(-10,log10(mp),20),'k'),   hold off
       axis square, title('streamlines (logscale)','fontsize',16)

       % Vorticity
       subplot(2,2,4)
       logw = log10(abs(w));    logw(abs(w)==0) = nan;
       contourf(xx,yy,logw,-3:0.5:2),
       H = colorbar; set(H,'fontsize',16)
       set(gca,'position',[0.5703 0.1100 0.3347 0.3412])
       axis square, title('vorticity (log(abs(w))','fontsize',16)
       drawnow

    end
end
\end{verbatim}