\chapter{Normal forms}\setcounter{ProbPart}{0}

\problempart
\label{pr.DNF}
Consider the following sentences:
	\begin{earg}
		\item $(A \eif \enot B)$
		\item $\enot (A \eiff B)$
		\item $(\enot A \eor \enot (A \eand B))$
		\item $(\enot (A \eif B ) \eand (A \eif C))$
		\item $(\enot (A \eor B) \eiff ((\enot C \eand \enot A) \eif \enot B))$
		\item $((\enot (A \eand \enot B) \eif C) \eand \enot (A \eand D))$
	\end{earg}
For each sentence, find an equivalent sentence in DNF and one in CNF.
\myanswer{We give a solution for (2). The truth table for $\enot (A \eiff B)$ is:
\begin{center}
\begin{tabular}{c c | l}
$A$ & $B$ & $\enot (A \eiff B)$\\
\hline
T & T & F \\
T & F & T \\
F & T & T \\
F & F & F \\
\end{tabular}
\end{center}
A sentence in DNF can be read off from lines 2 and 3:
\[(A \eand \enot B) \eor (\enot A \eand B)\]
and one in CNF from lines 1 and~4:
\[(\enot A \eor \enot B) \eand (A \eor B).\]}

\stepcounter{chapter} % Functional completeness

\chapter{Proving equivalences}\setcounter{ProbPart}{0}

\problempart
\label{pr.DNF2}
Consider the following sentences:
\begin{earg}
	\item $(A \eif \enot B)$
	\item $\enot (A \eiff B)$
	\item $(\enot A \eor \enot (A \eand B))$
	\item $(\enot (A \eif B ) \eand (A \eif C))$
	\item $(\enot (A \eor B) \eiff ((\enot C \eand \enot A) \eif \enot B))$
	\item $((\enot (A \eand \enot B) \eif C) \eand \enot (A \eand D))$
\end{earg}
For each sentence, find an equivalent sentence in DNF and one inCNF by giving a chain of equivalences. Use (Id), (Absorp), and (Simp) to simplify your sentences as much as possible.
\myanswer{We give a solution for (2). Removing `$\eiff$' and pushing negations inward is common to both:
\begin{align*}
	& \enot (A \eiff B)\\
	& \enot((A \eif B) \eand (B \eif A)) && \text{Bicond}\\
	& \enot((\enot A \eor B) \eand (B \eif A)) && \text{Cond}\\
	& \enot((\enot A \eor B) \eand (\enot B \eor A)) && \text{Cond}\\
	& \enot(\enot A \eor B) \eor \enot(\enot B \eor A) && \text{DeM}\\
	& (\enot\enot A \eand \enot B) \eor (\enot\enot B \eand \enot A) && \text{DeM}\\
	& (A \eand \enot B) \eor (\enot\enot B \eand \enot A) && \text{DN}\\
	& (A \eand \enot B) \eor (B \eand \enot A) && \text{DN}
\intertext{The result is now in DNF. To obtain a CNF, we keep going, using (Comm) and (Dist):}
& ((A \eand \enot B) \eor B) \eand ((A \eand \enot B) \eor \enot A) && \text{Dist}\\
& (B \eor (A \eand \enot B)) \eand ((A \eand \enot B) \eor \enot A) && \text{Comm}\\
& ((B \eor A) \eand (B \eor \enot B)) \eand ((A \eand \enot B) \eor \enot A) && \text{Dist}\\
& ((B \eor A) \eand (B \eor \enot B)) \eand (\enot A \eor (A \eand \enot B)) && \text{Comm}\\
& ((B \eor A) \eand (B \eor \enot B)) \eand ((\enot A \eor A) \eand (\enot A \eor \enot B)) && \text{Dist}\\
\intertext{The result can be simplified using (Simp):}
& (B \eor A) \eand ((\enot A \eor A) \eand (\enot A \eor \enot B)) && \text{Simp}\\
& (B \eor A) \eand (\enot A \eor \enot B) && \text{Simp}
\end{align*}}

\stepcounter{chapter} % Soundness


\chapter{Lecture 30 Jun 13th 2018}%
\label{chp:lecture_30_jun_13th_2018}
% chapter lecture_30_jun_13th_2018

\section{Polynomial Ring (Continued 3)}%
\label{sec:polynomial_ring_continued_3}
% section polynomial_ring_continued_3

\subsection{Quotient Rings of Polynomials (Continued)}%
\label{sub:quotient_rings_of_polynomials_continued}
% subsection quotient_rings_of_polynomials_continued

Let $A$ be a non-zero ideal in $F[x]$. By \cref{propo:ideals_of_f_x_are_principal_ideals}, we know that $A$ is a principal ideal\index{Principal Ideal} and can be written as $A = \lra{h(x)}$, for a unique polynomial $h(x) \in F[x]$.

Suppose that $\deg h = m \geq 1$. Consider the quotient ring $R = \faktor{F[x]}{A}$, and so we have
\begin{equation*}
  R = \left\{ \bar{f(x)} : f(x) + A, f(x) \in F[x] \right\}.
\end{equation*}
Write $t = \bar{x} = x + A$. Then by the \hlnoteb{Division Algorithm}\sidenote{This entire part until Proposition 89 might need to be rewritten since I am a little lost as to some of the details regarding the discussion.}, we have
\begin{equation*}
  R = \{ \bar{a_0} + \bar{a_1} t + \hdots + \bar{a_{m - 1}} t^{m - 1} : a_i \in F \}.
\end{equation*}
The map $\theta : F \to R$, given by $a \mapsto \bar{a}$, is an injective homomorphism, since $\theta$ is not a zero map and $\ker \theta$ is an ideal of $F$ \sidenote{Note that a field $F$ has only 2 ideals: $\{0\}$ and $F$ itself. Since $\ker \theta \neq F$, we have that $\ker \theta = \{0\}$ and so $\theta$ is injective.}. Since we have $F \cong \theta(F)$ by the \hyperref[thm:first_isomorphism_theorem_for_rings]{First Isomorphism Theorem for Rings}, by identifying $F$ with $\theta(F)$, we can write
\begin{equation*}
  R = \{ a_0 + a_1 t + \hdots a_{m - 1} t^{m - 1} : a_i \in F \}.
\end{equation*}

It is clear that, in $R$, we have
\begin{gather*}
  a_0 + a_1 t + \hdots + a_{m - 1} t^{m - 1} = b_0 + b_1 t + \hdots + b_{m - 1} t^{m - 1} \\
  \iff \\
  \forall i \in \mathbb{Z} \enspace 0 \leq i \leq m - 1 \quad a_i = b_i
\end{gather*}

Finally, in the ring $R$, we have $h(t) = 0$.

The following proposition follows from the above discussion.

\begin{propo}
\label{propo:remainder_ring}
Let $F$ be a field and let $h(x), f(x) \in F[x]$ be monic with $( \deg h, \, \deg f \geq 1 )$. Then the quotient ring $R = F[x] / A$ is given by
\begin{equation*}
  R = \{ a_0 + a_1 t + \hdots + a_{m - 1} t^{m - 1} : a_i \in F, \, h(t) = 0 \}
\end{equation*}
in which each element of $R$ can be uniquely represented in the above form.
\end{propo}

\begin{note}
  In $\mathbb{Z}$, we have that $\mathbb{Z} / \lra{n} = \mathbb{Z}_n = \{ [0], [1], ..., [n-1] \}$ which is analogous to our statement in \cref{propo:remainder_ring} for the case of integers.
\end{note}

\begin{eg}
  Consider $\mathbb{R}[x]$ and let $h(x) = x^2 + 1 \in \mathbb{R}[x]$. Then
  \begin{equation*}
    \mathbb{R}[x] = \{a + bt : a, b \in \mathbb{R}, \, t^2 + 1 = 0 \} \cong \{ a + bi : a, b \in \mathbb{R}, \, i^2 = -1 \} = \mathbb{C}
  \end{equation*}
\end{eg}

\begin{note}
  Recall that $\mathbb{Z}_n$ is a field (or an integral domain) if and only if $n$ is prime.
\end{note}

\begin{propo}
\label{propo:principal_ideals_of_polyms_as_fields}
  Let $F$ be a field nad $h(x) \in F[x]$ be a monic polynomial with $\deg h \geq 1$. TFAE:
  \begin{enumerate}
    \item $F[x] \big/ \lra{h(x)}$ is a field;
    \item $F[x] \big/ \lra{h(x)}$ is an integral domain;
    \item $h(x)$ is irreducible in $F[x]$.
  \end{enumerate}
\end{propo}

\begin{proof}
  $(1) \implies (2)$ since a field is an integral domain (see \cref{propo:fields_are_integral_domains}).

  \noindent $(2) \implies (3)$: Write $A = \lra{h(x)}$, If $h(x) = f(x) g(x)$ for $f(x), \, g(x) \in F[x]$, then
  \begin{align*}
    [ f(x) + A ] [ g(x) + A ] &= f(x) g(x) + A \quad \because A \text{ is an ideal } \\
                              &= h(x) + A = 0 \in F[x] \big/ A.
  \end{align*}
  Then by $(2)$, either $f(x) + A = 0$ or $g(x) + A = 0$, i.e. either $f(x) \in A$ or $g(x) \in A$. But if $f(x) \in A = \lra{h(x)}$, then $f(x) = q(x) h(x)$ for some $q(x) \in F[x]$. Then $h(x) = f(x) g(x) = q(x) h(x) g(x)$, which then implies that $0 = h(x) [ 1 - q(x) g(x) ] \implies q(x) g(x) = 1$ since $F[x]$ is an integral domain. Then we have that $\deg g = 0$. Similarly, if $g(x) \in A$, then we have $\deg f = 0$. Therefore, $h(x)$ is irreducible in $F[x]$ by definition.

  \noindent $(3) \implies (1)$: Note that $F[x] \big/ \lra{h(x)}$ is a commutative ring. To show that it is a field, it suffices to show that every non-zero element of $F[x] \big/ \lra{h(x)}$ has an inverse. Let $f(x) + A \neq 0 \in F[x] \big/ \lra{h(x)}$ with $f(x) \in F[x]$. Then $f(x) \notin A$, and so $h(x) \not| \, f(x)$. Since $h(x)$ is irreducible by $(3)$, we have that
  \begin{equation*}
    d(x) = \gcd[ f(x), h(x) ] = 1.
  \end{equation*}
  Then by \cref{propo:properties_of_the_greatest_common_divisor}, $\exists u(x), v(x) \in F[x]$ such that
  \begin{equation*}
    1 = u(x) h(x) + v(x) f(x).
  \end{equation*}
  Since $h(x) u(x) \in A$, we have that
  \begin{equation*}
    [v(x) + A] [f(x) + A] = 1 + A.
  \end{equation*}
  It follows that $f(x) + A$ has an inverse in $F[x] \big/ \lra{h(x)}$ and thus $F[x] \big/ \lra{h(x)}$ is a field. \qed
\end{proof}

% subsection quotient_rings_of_polynomials_continued (end)

% section polynomial_ring_continued_3 (end)

\section{Factorizations in Integral Domains}%
\label{sec:factorizations_in_integral_domains}
% section factorizations_in_integral_domains

\subsection{Irreducibles and Primes}%
\label{sub:irreducibles_and_primes}
% subsection irreducibles_and_primes

We have discussed much about the similarities between $\mathbb{Z}$ and $F[x]$, and in this chapter, we wish to abstract these similarties and study them in a more general manner to see if other sets that share the same kind of properties. For example, if a set has a \hlnoteb{unique factorization} for elements and the \hlnoteb{principal ideal} being the only ideal of the set, then do we still see the same analogy playing out?

\begin{defn}[Division]\index{Division}
\label{defn:division}
  Let $R$ be an integral domain and $a, \, b \in R$. We say that $a \, | \, b$ if $b = ca$ for some $c \in R$.
\end{defn}

\begin{note}
  Recall that in $\mathbb{Z}$, if $n \, | \, m$ and $m \, | \, n$, then $n = \pm m$, and the ideal generated by them are the same, i.e. $\lra{n} = \lra{m}$.

  Similarly so in $F[x]$< if $f(x) \, | \, g(x)$ and $g(x) \, | \, f(x)$, then $f(x) = cg(x)$ for some $x \in F[x]^* = F^*$, and $\lra{f(x)} = \lra{g(x)}$.
\end{note}

\begin{propo}[Division in an Integral Domain]
\label{propo:division_in_an_integral_domain}
Let $R$ be an integral domain. Then $\forall a, b \in R$, TFAE:\marginnote{This should be an easy exercise.
\begin{ex}
  Prove \cref{propo:division_in_an_integral_domain}.
\end{ex}
}
  \begin{enumerate}
    \item $a \, | \, b$ and $b \, | \, a$;
    \item $a = ub$ for some unit $u \in R$;
    \item $\lra{a} = \lra{b}$.
  \end{enumerate}
\end{propo}

\begin{defn}[Association]\index{Association}
\label{defn:association}
  Let $R$ be an integral domain. $\forall a, b \in R$, we say that $a$ is \hldefn{associated to} $b$, denoted by $a \sim b$, if $a \, | \, b$ and $b \, | \, a$.
\end{defn}

\begin{note}
  By \cref{propo:division_in_an_integral_domain}, we have that $a \sim a$ for any $a \in R$.

  \noindent Also, $a \sim b \iff b \sim a$.

  \noindent We also have $a \sim b \, \land \, b \sim c \implies a \sim c$.

  In other words, $\sim$ is an equivalence relation\index{Equivalence Relation} in $R$. Also, it can be shown that\sidenote{More exercise is always good.
  \begin{ex}
    Prove that the two statements following this is true.
  \end{ex}
  }
  \begin{enumerate}
    \item $a \sim a' \, \land \, b \sim b' \implies ab \sim a' b'$.
    \item $a \sim a' \, \land \, b \sim b' \implies ( a \, | \, b \iff b \, | \, a )$
  \end{enumerate}
\end{note}

\begin{eg}
  Let $R = \mathbb{Z}[\sqrt{3}] = \{ m + n \sqrt{3} : m, n \in \mathbb{Z} \}$. Note that this is an integral domain\sidenote{For $(a + b\sqrt{3}), \, (c + d\sqrt{3}) \in R$ such that
  \begin{equation*}
    (a + b \sqrt{3})(c + d \sqrt{3}) = 0
  \end{equation*}
  we would have that
  \begin{gather*}
    (a + b\sqrt{3})(a - b \sqrt{3})(c + d\sqrt{3})(c - d\sqrt{3}) = 0 \\
    ( a^2 - 3b^2 )( c^2 - 3d^2 ) = 0.
  \end{gather*}
  Since $\mathbb{Z}$ is an integral domain, suppose $a^2 - 3b^2 = 0$. If $b = 0$, then $a = 0$ and we are done. If $b \neq 0$, then we have $3 = \left( \frac{a}{b} \right)^2$, and we notice that $\sqrt{3}$ is irrational. Thus it can only be that $b = 0$. Therefore, $a + b\sqrt{3} = 0$, implying that there are no zero divisors in $R = \mathbb{Z}[\sqrt{3}]$.
  }. Observe that
  \begin{equation*}
    (2 + \sqrt{3})(2 - \sqrt{3}) = 1 \implies 2 + \sqrt{3} \text{ is a unit in } R.
  \end{equation*}
  Then we would have
  \begin{equation*}
    3 + 2 \sqrt{3} = (2 + \sqrt{3}) \sqrt{3}
  \end{equation*}
  and so by \cref{propo:division_in_an_integral_domain}, we have
  \begin{equation*}
    3 + 2 \sqrt{3} \sim \sqrt{3} \in \mathbb{Z}[\sqrt{3}].
  \end{equation*}
\end{eg}

% subsection irreducibles_and_primes (end)

% section factorizations_in_integral_domains (end)

% chapter lecture_30_jun_13th_2018 (end)


\documentclass[12]{scrartcl}
\usepackage{amssymb,amsmath,gensymb,dsfont,calc,multicol,fullpage}
\makeatletter
\newcommand\Aboxed[1]{
   \@Aboxed#1\ENDDNE}
\def\@Aboxed#1&#2\ENDDNE{%
   &
   \settowidth\@tempdima{$\displaystyle#1{}$}
   \setlength\@tempdima{\@tempdima+\fboxsep+\fboxrule}
   \kern-\@tempdima
   \boxed{#1#2}
}
\makeatother

\begin{document}

\title{Homework 21, Section 4.5: 2, 6, 11, 14}
\author{Alex Gordon}
\date{\today}
\maketitle
\section*{Homework}
\subsection*{2. A)}
$R_1$ is symmetric
\subsection*{2. B)}
$R_2$ is symmetric
\subsection*{2. C)}
$R_3$ is not symmetric
\subsection*{6.}
\{\{ACBD, CBDA, BDAC, DACB\}, \{ADBC, DBCA, BCAD, CADB\}, \{ABCD,BCDA,CDAB,DABC\},\{ADCB, DCBA, CBAD, BADC\},\{ABDC,BDCA,DCAB,CABD\}, \{ACDB, CDBA, DBAC, BACD\}\}

\subsection*{11. A)}
Let $a \in \mathds{Z} $ since $a - a = 0$ and a is divisible by $n$, $(a,a) \in \mathds{R}$. This means R is reflexive.
\subsection*{11. B)}
Let $a, b \in \mathds{Z}$ so that $(a,b) \in \mathds{R}$. Since $a - b$ is divisible by $n$, which in turn means that $a - b= kn$ and $b-a= -kn$. Since $-k$ is an integer it means that $b -a$ is divisible by $n$, which means that R is symmetric.
\subsection*{11. C)}
\subsection*{11. D)}

\subsection*{14. A)}
\{(1,1),(2,2),(3,3),(3,2),(1,3),(1,2)\}
\subsection*{14. B)}
\{(1,1),(2,2),(3,3),(3,2),(1,3),(3,1),(2,3)\}
\subsection*{14. C)}
\{(1,1),(1,2),(2,1),(2,2)\}

\end{document}


% Custom environments

\theoremstyle{plain}
\newtheorem{theorem}{Theorem}[section]
\newtheorem*{theorem*}{Theorem}
\newtheorem{lemma}{Lemma}[section]
\newtheorem*{lemma*}{Lemma}
\newtheorem{prop}{Proposition}[section]
\newtheorem{cor}{Corollary}[section]

\theoremstyle{definition}
\newtheorem{definition}{Definition}
\newtheorem{remark}{Remark}
%\newtheorem{think}{Gedankenexperiment}
%\newtheorem*{think}{Think about it \faLightbulbO}

\newtheorem{example}{Example}

\newenvironment{think}
	{
		\bigskip
		\begin{tcolorbox}
		\paragraph{Think about it.}
	}{
		\end{tcolorbox}
}

\newenvironment{extra}
{
	\bigskip
	\begin{tcolorbox}
		\paragraph{Extra Information.}
	}{
	\end{tcolorbox}
}

% Custom commands

\newcommand{\naive}{na\"{\i}ve }
\newcommand{\Naive}{Na\"{\i}ve }
\newcommand{\andor}{and\textbackslash or }
\newcommand{\erdos}{Erd\H{o}s }
\newcommand{\renyi}{R\`enyi }

\newcommand{\al}{\alpha}
\newcommand{\be}{\beta}
\newcommand{\si}{\sigma}

\newcommand{\set}[1]{\{ #1 \}} % A set
\newcommand{\setII}[1]{\left\{ #1 \right\}} % A set
\newcommand{\rv}[1]{\mathbf{#1}} % A random variable
\newcommand{\x}{\rv x} % The random variable x
\newcommand{\y}{\rv y} % The random variable x
\newcommand{\U}{\rv u} % The random variable x
\newcommand{\T}{\rv t} % The random variable x
\newcommand{\X}{\rv X} % The random variable x
\newcommand{\Y}{\rv Y} % The random variable y
\newcommand{\expect}[1]{\mathbf{E}\left[ #1 \right]} % The expectation operator
\newcommand{\expectg}[2]{\mathbf{E}_{\rv{#1}}\left[ \rv{#2} \right]} % An expectation w.r.t. a particular random variable.
\newcommand{\expectn}[1]{\mathbb{E}\left[#1\right]} % The empirical expectation
\newcommand{\cov}[1]{\mathbf{Cov} \left[ #1 \right]} % The expectation operator
\newcommand{\var}[1]{\mathop{Var} \left[ #1 \right]} % The expectation operator
\newcommand{\covn}[1]{\mathbb{Cov} \left[ #1 \right]} % The expectation operator
\newcommand{\gauss}[1]{\mathcal{N}\left(#1\right)} % The gaussian distribution
\newcommand{\cdf}[2]{F_{#1} (#2)} % The CDF function
\newcommand{\survive}[2]{S_{#1} (#2)} % The survival function
\newcommand{\surviven}[2]{\hat{S}_{#1} (#2)} % The survival function
\newcommand{\hazard}[2]{h_{#1} (#2)} % The survival function
\newcommand{\hazardn}[2]{\hat{h}_{#1} (#2)} % The survival function
\newcommand{\cuhazard}[2]{H_{#1} (#2)} % The survival function
\newcommand{\cdfn}[2]{\mathbb{F}_{#1}(#2)} % The empirical CDF function
\newcommand{\icdf}[2]{F_\rv{#1}^{-1} (#2)} % The invecrse CDF function
\newcommand{\icdfn}[2]{\mathbb{F}^{-1}_{#1}(#2)} % The inverse empirical CDF function
\newcommand{\pdf}[2]{p_{#1} (#2)} % The CDF function
\newcommand{\prob}[1]{P\left( #1 \right)} % the probability of an event
\newcommand{\dist}{P} % The proabaiblity distribution
\newcommand{\density}{p}
\newcommand{\entropy}{H} % entropy
\newcommand{\mutual}[2]{I\left(#1;#2\right)} % mutual information

\newcommand{\estim}[1]{\widehat{#1}} % An estimator
\newcommand{\estimII}[1]{\tilde{#1}} % Some other estimator

\newcommand{\norm}[1]{\Vert #1 \Vert} % The norm operator
\newcommand{\normII}[1]{\norm{#1}_2} % The norm operator
\newcommand{\normI}[1]{\norm{#1}_1} % The norm operator
\newcommand{\normF}[1]{\norm{#1}_{Frob}} % The Frobenius matrix norm
\newcommand{\ones}{\textbf{1}} % Vector of ones.
\newcommand{\lik}{\mathcal{L}} % The likelihood function
\newcommand{\loglik}{L} % The log likelihood function
\newcommand{\loss}{l} % A loss function
\newcommand{\lossII}{\prescript{}{2}{l}} % A loss function
\newcommand{\risk}{R} % The risk function
\newcommand{\riskn}{\mathbb{R}} % The empirical risk
\newcommand{\riskII}{\prescript{}{2}{R}} % The empirical risk
\newcommand{\risknII}{\prescript{}{2}{\mathbb{R}} } % The empirical risk
\newcommand{\noisen}{\mathbb{G}} % The empirical noise process
\newcommand{\deriv}[2]{\frac{\partial #1}{\partial #2}} % A derivative
\newcommand{\argmin}[2]{\textstyle{\mathop{argmin}_{#1}}\set{#2}} % The argmin operator
\newcommand{\argmax}[2]{\textstyle{\mathop{argmax}_{#1}}\set{#2}} % The argmin operator
\newcommand{\hyp}{f} % A hypothesis
\newcommand{\hypclass}{\mathcal{F}} % A hypothesis class
\newcommand{\hilbert}{\mathcal{H}}
\newcommand{\rkhs}{\hilbert_\kernel} % A hypothesis class
\newcommand{\normrkhs}[1]{\norm{#1}_{\rkhs}} % the RKHS function norm

\newcommand{\plane}{\mathbb{L}} % A hypoerplane
\newcommand{\categories}{\mathcal{G}} % The categories set.
\newcommand{\positive}[1]{\left[ #1 \right]_+} % The positive part function
\newcommand{\kernel}{\mathcal{K}} % A kernel function
\newcommand{\featureS}{\mathcal{X}} % The feature space
\newcommand{\outcomeS}{\mathcal{Y}} % The feature space
\newcommand{\indicator}[1]{I_{\set{#1}}} % The indicator function.
\newcommand{\reals}{\mathbb{R}} % the set of real numbers

\newcommand{\latent}{\rv{s}} % latent variables matrix
\newcommand{\latentn}{S} % latent variables matrix
\newcommand{\loadings}{A} % factor loadings matrix
\newcommand{\rotation}{R}  % rotation matrix
\newcommand{\similaritys}{\mathfrak{S}} % a similarity graph
\newcommand{\similarity}{s} % A similarity measure.
\newcommand{\dissimilarity}{d} % A dissimilarity measure.
\newcommand{\dissimilaritys}{\mathfrak{D}} % a dissimilarity graph
\newcommand{\scalar}[2]{\left< #1,#2 \right>} % a scalar product

\newcommand{\manifold}{\mathcal{M}} % A manifold.
\newcommand{\project}{\hookrightarrow} % The orthogonal projection operator.
\newcommand{\projectMat}{H} % A projection matrix.
\newcommand{\rank}{q} % A subspace rank.
\newcommand{\dimy}{K} % The dimension of the output.
\newcommand{\encode}{E} % a linear encoding matrix
\newcommand{\decode}{D} % a linear decoding matrix
\DeclareMathOperator{\Tr}{Tr}
\newcommand{\ensembleSize}{M} % Size of a hypothesis ensemble.
\newcommand{\ensembleInd}{m} % Index of a hypothesis in an ensemble.

\newcommand{\sample}{\mathcal{S}} % A data sample.
\newcommand{\test}{\risk(\hyp)} % The test error (risk)
\newcommand{\train}{\riskn(\hyp)} % The train error (empirical risk)
\newcommand{\insample}{\bar{\risk}(\hyp)} % The in-sample test error.
\newcommand{\EPE}{\risk(\hat{\hyp}_n)} % The out-of-sample test error.
\newcommand{\folds}{K} % Cross validation folds
\newcommand{\fold}{k} % Index of a fold
\newcommand{\bootstraps}{B} % Bootstrap samples
\newcommand{\bootstrap}{{b^*}} % Index of a bootstrap replication

\newcommand{\rankings}{\mathcal{R}} % Rankings, for colaborative filtering.
\newcommand{\ranking}{\mathcal{R}} % Rankings, for colaborative filtering.
\newcommand{\KL}[2]{D_{KL}\left(#1 \Vert #2 \right)}
\newcommand{\ortho}{\mathbb{O}} % space of orthogonal matrices

\newcommand{\id}[6]{
	\begin{tabular}{|p{2cm}|p{2cm}|p{2cm}|p{2cm}|p{2cm}|p{2cm}|}
	\hline Task & Type & Input & Output & Concept & Remark \\
	\hline
	\hline #1 & #2 & #3 & #4 & #5 & #6 \\
	\hline
	\end{tabular}
	\newline
	\newline
}

\newcommand{\union}{\cup}
\newcommand{\intersect}{\cap}
\newcommand{\supp}[1]{\mathop{support}(#1)}
\newcommand{\conf}[2]{\mathop{confidence}(#1 \Rightarrow #2)}
\newcommand{\lift}[2]{\mathop{lift}(#1 \Rightarrow #2)}
\newcommand{\convic}[2]{\mathop{conviction}(#1 \Rightarrow #2)}

\newcommand{\machine}[1]{\estim{\theta}_n^{(#1)}}
\newcommand{\minimizer}{\theta^*}
\newcommand{\generative}{\theta_0}
\newcommand{\parallelized}{\bar{\theta}_{N,m}}
\newcommand{\parallelizedII}{\mathring{\theta}_{N,m}}
\newcommand{\parallelizedIII}{\prescript{}{2}{\widehat{\theta}}_{N,m}}
\newcommand{\centralized}{\estim{\theta}_N}
\newcommand{\parallelKL}{\estim{\theta}_{KL}}
\newcommand{\penalize}{J}
\newcommand{\bigO}{\mathcal{O}}
\newcommand{\bigOprob}{\mathcal{O}_P}
\newcommand{\smallO}{o}
\newcommand{\smallOprob}{o_P}

\newcommand{\citeJR}[1]{\citeauthor{#1} \citep{#1}}
\newcommand{\citeJRfull}[1]{\citeauthor*{#1} \citep{#1}}
\newcommand{\error}{\mathcal{E}}

\newcommand{\M}{$M$}
\newcommand{\MII}{$\prescript{}{2}{M}$}

\newcommand{\biasSecond}[1]{B_2(#1)}
\newcommand{\MSESecond}[1]{M_2(#1)}

\newcommand{\rate}{r}

\newcommand{\emptyfigure}[1]{\missingfigure[figwidth=6cm]{#1}}

% % Time line
%\usepackage[paperwidth=210mm,%
%    paperheight=297mm,%
%    tmargin=7.5mm,%
%    rmargin=7.5mm,%
%    bmargin=7.5mm,%
%    lmargin=7.5mm,
%    vscale=1,%
%    hscale=1]{geometry}
%
%\usepackage[utf8]{inputenc}
%\usepackage[T1]{fontenc}

\usepackage{tikz}
\usetikzlibrary{arrows, calc, decorations.markings, positioning}

\makeatletter
\newenvironment{timeline}[6]{%
    % #1 is startyear
    % #2 is tlendyear
    % #3 is yearcolumnwidth
    % #4 is rulecolumnwidth
    % #5 is entrycolumnwidth
    % #6 is timelineheight

    \newcommand{\startyear}{#1}
    \newcommand{\tlendyear}{#2}

    \newcommand{\yearcolumnwidth}{#3}
    \newcommand{\rulecolumnwidth}{#4}
    \newcommand{\entrycolumnwidth}{#5}
    \newcommand{\timelineheight}{#6}

    \newcommand{\templength}{}

    \newcommand{\entrycounter}{0}

    % http://tex.stackexchange.com/questions/85528/checking-whether-or-not-a-node-has-been-previously-defined
    % http://tex.stackexchange.com/questions/37709/how-can-i-know-if-a-node-is-already-defined
    \long\def\ifnodedefined##1##2##3{%
        \@ifundefined{pgf@sh@ns@##1}{##3}{##2}%
    }

    \newcommand{\ifnodeundefined}[2]{%
        \ifnodedefined{##1}{}{##2}
    }

    \newcommand{\drawtimeline}{%
        \draw[timelinerule] (\yearcolumnwidth+5pt, 0pt) -- (\yearcolumnwidth+5pt, -\timelineheight);
        \draw (\yearcolumnwidth+0pt, -10pt) -- (\yearcolumnwidth+10pt, -10pt);
        \draw (\yearcolumnwidth+0pt, -\timelineheight+15pt) -- (\yearcolumnwidth+10pt, -\timelineheight+15pt);

        \pgfmathsetlengthmacro{\templength}{neg(add(multiply(subtract(\startyear, \startyear), divide(subtract(\timelineheight, 25), subtract(\tlendyear, \startyear))), 10))}
        \node[year] (year-\startyear) at (\yearcolumnwidth, \templength) {\startyear};

        \pgfmathsetlengthmacro{\templength}{neg(add(multiply(subtract(\tlendyear, \startyear), divide(subtract(\timelineheight, 25), subtract(\tlendyear, \startyear))), 10))}
        \node[year] (year-\tlendyear) at (\yearcolumnwidth, \templength) {\tlendyear};
    }

    \newcommand{\entry}[2]{%
        % #1 is the year
        % #2 is the entry text

        \pgfmathtruncatemacro{\lastentrycount}{\entrycounter}
        \pgfmathtruncatemacro{\entrycounter}{\entrycounter + 1}

        \ifdim \lastentrycount pt > 0 pt%
            \node[entry] (entry-\entrycounter) [below of=entry-\lastentrycount] {##2};
        \else%
            \pgfmathsetlengthmacro{\templength}{neg(add(multiply(subtract(\startyear, \startyear), divide(subtract(\timelineheight, 25), subtract(\tlendyear, \startyear))), 10))}
            \node[entry] (entry-\entrycounter) at (\yearcolumnwidth+\rulecolumnwidth+10pt, \templength) {##2};
        \fi

        \ifnodeundefined{year-##1}{%
            \pgfmathsetlengthmacro{\templength}{neg(add(multiply(subtract(##1, \startyear), divide(subtract(\timelineheight, 25), subtract(\tlendyear, \startyear))), 10))}
            \draw (\yearcolumnwidth+2.5pt, \templength) -- (\yearcolumnwidth+7.5pt, \templength);
            \node[year] (year-##1) at (\yearcolumnwidth, \templength) {##1};
        }

        \draw ($(year-##1.east)+(2.5pt, 0pt)$) -- ($(year-##1.east)+(7.5pt, 0pt)$) -- ($(entry-\entrycounter.west)-(5pt,0)$) -- (entry-\entrycounter.west);
    }

    \newcommand{\plainentry}[2]{% plainentry won't print date in the timeline
        % #1 is the year
        % #2 is the entry text

        \pgfmathtruncatemacro{\lastentrycount}{\entrycounter}
        \pgfmathtruncatemacro{\entrycounter}{\entrycounter + 1}

        \ifdim \lastentrycount pt > 0 pt%
            \node[entry] (entry-\entrycounter) [below of=entry-\lastentrycount] {##2};
        \else%
            \pgfmathsetlengthmacro{\templength}{neg(add(multiply(subtract(\startyear, \startyear), divide(subtract(\timelineheight, 25), subtract(\tlendyear, \startyear))), 10))}
            \node[entry] (entry-\entrycounter) at (\yearcolumnwidth+\rulecolumnwidth+10pt, \templength) {##2};
        \fi

        \ifnodeundefined{invisible-year-##1}{%
            \pgfmathsetlengthmacro{\templength}{neg(add(multiply(subtract(##1, \startyear), divide(subtract(\timelineheight, 25), subtract(\tlendyear, \startyear))), 10))}
            \draw (\yearcolumnwidth+2.5pt, \templength) -- (\yearcolumnwidth+7.5pt, \templength);
            \node[year] (invisible-year-##1) at (\yearcolumnwidth, \templength) {};
        }

        \draw ($(invisible-year-##1.east)+(2.5pt, 0pt)$) -- ($(invisible-year-##1.east)+(7.5pt, 0pt)$) -- ($(entry-\entrycounter.west)-(5pt,0)$) -- (entry-\entrycounter.west);
    }

    \begin{tikzpicture}
        \tikzstyle{entry} = [%
            align=left,%
            text width=\entrycolumnwidth,%
            node distance=10mm,%
            anchor=west]
        \tikzstyle{year} = [anchor=east]
        \tikzstyle{timelinerule} = [%
            draw,%
            decoration={markings, mark=at position 1 with {\arrow[scale=1.5]{latex'}}},%
            postaction={decorate},%
            shorten >=0.4pt]

        \drawtimeline
}
{
    \end{tikzpicture}
    \let\startyear\@undefined
    \let\tlendyear\@undefined
    \let\yearcolumnwidth\@undefined
    \let\rulecolumnwidth\@undefined
    \let\entrycolumnwidth\@undefined
    \let\timelineheight\@undefined
    \let\entrycounter\@undefined
    \let\ifnodedefined\@undefined
    \let\ifnodeundefined\@undefined
    \let\drawtimeline\@undefined
    \let\entry\@undefined
}
\makeatother
% % % % %

\newcommand{\R}{\textnormal{\sffamily\bfseries R }}

% Process capability notation
\newcommand{\targetValue}{T}% target value
\newcommand{\cp}{C_p}% c_p
\newcommand{\cpHat}{\hat{C}_p}% c_p
\newcommand{\ctqExpect}{\mu}
\newcommand{\pnc}{p_{NC}}
\newcommand{\cpu}{C_{pu}}
\newcommand{\cpl}{C_{pl}}
\newcommand{\cpk}{C_{pk}}
\newcommand{\cpkHat}{\hat{C}_{pk}}
\newcommand{\cpm}{C_{pm}}
\newcommand{\cpmHat}{\hat{C}_{pm}}
\newcommand{\cpq}{C_p(q)}
\newcommand{\pp}{P_{p}}
\newcommand{\ppk}{P_{pk}}

\newcommand{\barxChart}{$\bar{x}$-chart}
\newcommand{\sigmabar}{\sigma_{\bar{x}}}
\newcommand{\aka}{{a.k.a.\ }}
\newcommand{\Aka}{{A.k.a.\ }}
\newcommand{\rcode}[1]{\texttt{#1}}
\newcommand{\arm}{L}

\newcommand{\tsq}{$T^2$ }
\newcommand{\struct}{\Phi}
\newcommand{\exppdf}[2]{#1 e^{-#1 #2}}
\newcommand{\expcdf}[2]{e^{-#1 #2}}

\newcommand{\conv}{\ast}
\newcommand{\range}[1]{Range(#1)}

\newcommand{\dif}{\mathrm{d}}


\section{Simulation extractability of $\plonk$, omitted proofs}
\label{sec:plonkse_proofs}

%\oursubsub{Proof of \cref{lem:plonkprot_ur}}

\begin{lemma}[\cref{lem:plonkprot_ur} restated]
	\label{lem:app:plonkprot_ur}
	Let $\PCOMp$ be a polynomial commitment that is $\epsbind(\secpar)$-binding and has unique opening property with loss $\epsop (\secpar)$, let $(\noofc + 5, 1)$-$\udlog$ problem be $\epsudlog (\secpar)$ hard. Then $\plonkprotfs$ is $\ur{3}$ against algebraic adversaries, who makes up to $q$ random oracle queries, with security loss $8  \cdot \epsbinding (\secpar) + \epsudlog (\secpar) + 2 \infrac{q}{p}$.
\end{lemma}

\begin{proof}
    Let $\adv$ be an algebraic adversary tasked to break the $\ur{3}$-ness of
      $\plonkprotfs$. We show that the first three prover's messages determine, along with 	the verifiers challenges, the rest of it. We denote by $\zkproof^0$ and $\zkproof^1$ the two proofs that the adversary outputs. To distinguish polynomials and commitments which an honest prover would send in the proof from the polynomials and commitments computed by the adversary we write the latter using indices $0$ and $1$ (two indices as we have two transcripts), e.g.~to describe the quotient polynomial provided by the adversary we write $\p{t}^0$ and $\p{t}^1$ instead of $\p{t}$ as in the description of the protocol.

    We note that since the unique response property requires from $\zkproof^{0}$ and $\zkproof^{1}$ that the first place they possibly differ is the $4$-th prover's message, then the challenge $\chz$, that is picked by the adversary after the $3$-rd message is the same in both transcripts. This challenge determines the evaluation point of polynomials $\p{a}(X), \p{b}(X), \p{c}(X), \p{t}(X), \p{z}(X)$ which commitments are already sent.

    In its fourth message, the prover provides evaluations of the aforementioned polynomials, along with evaluations of publicly known polynomials $
    \p{S_{\sigma 1}} (\chz), \p{S_{\sigma 2}} (\chz)$, and evaluation of a linearization polynomial $\p{r}(\chz)$.

    Note that the adversary can output two accepting proofs that differ on their fourth message only if it either manages to break evaluation binding of one of the opening, or provides an incorrect opening which is accepted due to a batching error. Since the commitment scheme is evaluation binding with security loss $\epsbinding (\secpar)$, %and the batched verification equation accepts an incorrect opening with probability at most $\infrac{q}{p}$, cf.~\cite{EPRINT:GabWilCio19},
	the adversary can make $\zkproof^{0}$ and $\zkproof^{1}$ differ on the fourth message with the same probability. % at most $8  \cdot \epsbinding (\secpar) + \infrac{q}{p}$.

    Next, assume that the transcripts are the same up to the fourth message, but differ at the fifth. In that message, the adversary provides openings of the evaluations. Since the unique opening property, the adversary can open the valid evaluation of a polynomial to two different values with probability at most $\epsop (\secpar)$. (We note that for the KZG polynomial commitment scheme, as used in \cite{EPRINT:GabWilCio19}, $\epsop (\secpar) \leq \epsudlog (\secpar) + \infrac{q}{p}$, cf.~\cref{lem:pcomp_op}.)
    % , which is upper-bounded by $\epsudlog (\secpar) + \infrac{q}{p}$, cf.~\cref{lem:pcomp_op}.

    By the union bound, the adversary is able to break the unique response property with probability upper bounded by $\epsbinding (\secpar) + \epsop (\secpar)$.
    \qed
    \end{proof}

%\oursubsub{Proof of \cref{lem:plonkprot_ss}}

\begin{lemma}[\cref{lem:plonkprot_ss} restated]
	\label{lem:app:plonkprot_ss}
	$\plonkprotfs$ is $(3, 3 \noofc + 6)$-rewinding-based knowledge sound against algebraic adversaries who make up to $q$ random oracle queries with security loss
	\[
	\epscss(\secpar,\accProb, q) \leq \left(1 - \frac{\accProb - (q + 1) \left(\frac{3 \noofc + 5}{p} \right)}{1 - \frac{3 \noofc + 5}{p}}\right) + (3 \noofc + 6) \cdot \epsudlog (\secpar)\,,
	\]

	Here $\accProb$ is a probability that the adversary outputs an accepting proof, and $\epsudlog(\secpar)$ is security of $(\numberofconstrains + 5, 1)$-$\udlog$.
\end{lemma}

\begin{proof}
	Let $\adv^{\ro, \initU}(\secparam; r)$ be the adversary who outputs $(\inp, \zkproof)$ such that $\plonkprotfs.\verifier$ accepts the proof. Let $\tdv$ be a tree-building algorithm of \cref{lem:attema} that outputs a tree $\tree$, and let $\extcss$ be an extractor that given the tree output by $\tdv$ reveals the witness for $\inp$. The main idea of the proof is to show that an adversary who breaks rewinding-based knowledge soundness can be used to break a $\udlog$-problem instance. The proof goes by game hops. Note that since the tree branches after $\adv$'s $3$-rd message, the instance $\inp$, commitments $\gone{\p{a} (\chi), \p{b} (\chi), \p{c} (\chi), \p{z} (\chi), \p{t_{lo}} (\chi), \p{t_{mid}} (\chi), \p{t_{hi}} (\chi)}$, and challenges $\alpha, \beta, \gamma$ are the same in all the transcripts. Also, the tree branches after the third adversary's message where the challenge $\chz$ is presented, thus tree $\tree$ is built using different values of $\chz$.	We consider the following games.

  \ncase{Game 0} %
  In this game the adversary wins if it outputs a valid instance--proof pair $(\inp, \zkproof)$, and the extractor $\extcss$ does not manage to output a witness $\wit$ such that $\REL (\inp, \wit)$ holds.

  \ncase{Game 1} %
  In this game the environment aborts the game if the tree building algorithm $\tdv$ fails in building a tree of accepting transcripts $\tree$.

  \ncase{Game 0 to Game 1} %
  By \cref{lem:attema} probability that Game 1 is aborted, while Game 0 is not, is at most
  %\hamid{2.5}{Should this not be "1 minus the following"?}
  \[
    1 - \frac{\accProb - (q + 1) \left(\frac{3 \noofc + 5}{p} \right)} {1 - \frac{3 \noofc + 5}{p}} \,.
  \]

  \ncase{Game 2} %
  In this game the environment additionally aborts if at least one of its proofs in $\tree$ is not accepting by an ideal verifier.

  \ncase{Game 1 to Game 2} %
  As usual, we show a reduction that breaks an instance of a $\udlog$ assumption when Game 2 is aborted, while Game 1 is not.

  Let $\rdvudlog$ be a reduction that gets as input an $(\noofc + 5, 1)$-$\udlog$ instance $\gone{1, \ldots, \chi^{\noofc + 5}}, \gtwo{\chi}$. Then it can update the instance to another one $\gone{1, \ldots, {\chi'}^{\noofc + 5}}, \gtwo{\chi'}$. Eventually, the reduction outputs $\chi'$.
	%
	The reduction $\rdvudlog$ proceeds as follows.
	First, it builds $\adv$'s SRS $\srs$ using the input $\udlog$ instance. Then it processes the adversary's update query by adding it to the list $\Qsrs$ and passing it to its own update oracle getting instance $\gone{1, \ldots, {\chi'}^{\noofc + 5}}, \gtwo{\chi'}$. The updated SRS $\srs'$ is then computed and given to $\adv$. $\rdvdulog$ also takes care of the random oracle queries made by $\adv$. It picks their answers honestly and write them in $\Qro$. The reduction then starts $\tdv(\srs, \adv, r, \Qro, \Qsrs)$.

  Let $(1, \tree)$ be the output returned by $\tdv$. Let $\inp$ be a relation proven in $\tree$.  Consider a transcript $\zkproof \in \tree$ such that $\vereq_{\inp, \zkproof}(X) \neq 0$, but $\vereq_{\inp, \zkproof}(\chi') = 0$. Since $\adv$ is algebraic, all group elements included in $\tree$ are extended by their representation as a combination of the input $\GRP_1$-elements. Hence, all coefficients of the verification equation polynomial $\vereq_{\inp, \zkproof}(X)$ are known.
  Eventually, the reduction finds $\vereq_{\inp, \zkproof}(X)$ zero points and returns $\chi'$ which is one of them.

  Hence, the probability that the adversary wins in Game 2 but does not win in Game 1 is upper-bounded by $(3 \noofc + 6) \cdot \epsudlog (\secpar)$.

  \ncase{Conclusion}

  Note that the adversary can win in Game 2 only if $\tdv$ manages to produce a tree of accepting transcripts $\tree$, such that each of the transcripts in $\tree$ is accepting by an ideal verifier. Note that since $\tdv$ produces $(3 \noofc + 6)$ accepting transcripts for different challenges $\chz$, it obtains the same number of different evaluations of polynomials $\p{a} (X), \p{b} (X), \p{c} (X), \p{z} (X), \p{t} (X)$. Since all the transcripts are accepting by an idealized verifier, the equality between polynomial $\p{t} (X)$ and combination of polynomials $\p{a} (X), \p{b} (X), \p{c} (X), \p{z} (X)$ defined in prover's $3$-rd message description holds. Hence, $\p{a} (X), \p{b} (X), \p{c} (X)$ encodes the valid witness for the proven statement. $\extcss$ can recreate polynomials' coefficients by interpolation and reveal the witness given $(3 \noofc + 6)$ evaluations.
  % Thus, the probability that extraction fails in that case is upper-bounded by $(3 \noofc + 6) \cdot \epsid(\secpar)$.

  Hence, the probability that the adversary wins in Game 0 is upper-bounded by
  \[
    \epscss(\secpar,\accProb, q) \leq \left(1 - \frac{\accProb - (q + 1) \left(\frac{3 \noofc + 5}{p} \right)}{1 - \frac{3 \noofc + 5}{p}}\right) + (3 \noofc + 6) \cdot \epsudlog (\secpar)\,.
  \]
  \qed
 \end{proof}

%\oursubsub{Proof of \cref{lem:plonk_tlzk}}
\begin{lemma}[\cref{lem:plonk_tlzk} restated]
	\label{lem:app:plonk_tlzk}
	$\plonkprotfs$ is 3-programmable trapdoor-less zero-knowledge.
\end{lemma}

\begin{proof}
    As noted in \cref{def:upd-scheme}, subvertible zero-knowledge implies updatable zero-knowledge. Hence, here we show that Plonk is TLZK even against adversaries who picks
    the SRS on its own.

  The adversary $\adv(\secparam)$ picks an SRS $\srs$ and instance--witness pair
  $(\inp, \wit)$ and gets a proof $\zkproof$ simulated by the simulator
  $\simulator$ which proceeds as follows.

  For its $1$-st message the simulator  picks randomly both the randomizers $b_1, \ldots, b_6$ and
  sets $\wit_i = 0$ for $i \in \range{1}{3\noofc}$. Then $\simulator$
  outputs $\gone{\p{a}(\chi), \p{b}(\chi), \p{c}(\chi)}$. For the first
  challenge, the simulator picks permutation argument challenges $\beta, \gamma$
  randomly.

  For its $2$-nd message, the simulator computes $\p{z}(X)$ from
  the newly picked randomizers $b_7, b_8, b_9$ and coefficients of polynomials
  $\p{a}(X), \p{b}(X), \p{c}(X)$. Then it evaluates $\p{z}(X)$ honestly and outputs
  $\gone{\p{z}(\chi)}$. Challenge $\alpha$ that should be sent by the verifier
  after the simulator's $2$ message is picked by the simulator at random.

  In its $3$-rd message the simulator starts by picking at random a challenge $\chz$, which
  in the real proof comes as a challenge from the verifier sent \emph{after} the prover
  sends its $3$-rd message. Then $\simulator$ computes evaluations
  \(\p{a}(\chz), \p{b}(\chz), \p{c}(\chz), \p{S_{\sigma 1}}(\chz), \p{S_{\sigma
      2}}(\chz), \pubinppoly(\chz), \lag_1(\chz), \p{Z_H}(\chz),\allowbreak
  \p{z}(\chz\omega)\) and computes $\p{t}(X)$ honestly. Since for a random
  $\p{a}(X), \p{b}(X), \p{c}(X), \p{z}(X)$ the constraint system is (with
  overwhelming probability) not satisfied and the constraints-related polynomials
  are not divisible by $\p{Z_H}(X)$, hence $\p{t}(X)$ is a rational function
  rather than a polynomial. Then, the simulator evaluates $\p{t}(X)$ at $\chz$ and
  picks randomly a degree-$(3 \noofc + 15)$ polynomial $\p{\tilde{t}}(X)$ such that
  $\p{t}(\chz) = \p{\tilde{t}}(\chz)$ and publishes a commitment
  $\gone{\p{\tilde{t}_{lo}}(\chi), \p{\tilde{t}_{mid}}(\chi),
    \p{\tilde{t}_{hi}}(\chi)}$. After that the simulator outputs $\chz$ as a
  challenge.

  For the next message, the simulator computes polynomial $\p{r}(X)$ as an honest
  prover would, cf.~\cref{sec:plonk_explained} and evaluates $\p{r}(X)$ at $\chz$.

  The rest of the evaluations are already computed, thus $\simulator$ simply outputs
  \( \p{a}(\chz), \p{b}(\chz), \p{c}(\chz), \p{S_{\sigma 1}}(\chz), \p{S_{\sigma
      2}}(\chz), \p{t}(\chz), \p{z}(\chz \omega)\,.  \) After that it picks randomly
  the challenge $v$, and prepares the the last message as an honest prover
  would. Eventually, $\simulator$ and outputs the final challenge, $u$, by picking it
  at random as well.

  We argue about zero-knowledge as usual. The property holds since the polynomials that has witness elements at their coefficients are randomized by at least two randomizers and are evaluated at at most two points; and the simulator computes all polynomials as an honest prover would.
  \qed
  \end{proof}


% mainfile: ../Refinement.tex
\chapter{Appendix}
\pagestyle{scrheadings}
\setcounter{page}{0}
\pagenumbering{arabic}
\label{chp_appendix}
\section{Addition}
\lstinputlisting[backgroundcolor=\color{white},caption={0,1,2,3 as \picalc{} processes.},captionpos=b]{listings/values.abc}

\lstinputlisting[backgroundcolor=\color{white},caption={Gates.},captionpos=b]{appendix/gates.abc}

\lstinputlisting[backgroundcolor=\color{white},caption={Adder.},captionpos=b]{appendix/adder.abc}

\lstinputlisting[backgroundcolor=\color{white},caption={Subtractor.},captionpos=b]{appendix/subtractor.abc}

\lstinputlisting[backgroundcolor=\color{white},caption={Comparator.},captionpos=b]{appendix/comparator.abc}

\lstinputlisting[backgroundcolor=\color{white},caption={Set union.},captionpos=b]{appendix/set_union.abc}

\lstinputlisting[backgroundcolor=\color{white},caption={Set subtraction.},captionpos=b]{appendix/set_subtraction.abc}


%This is test for LaTeX syntax
\documentclass[a4paper,12pt]{article}
\begin{document}

%Title
\title{My First Document}
\author{My Name}
\date{\today}
\maketitle

%Sections
\section{Introduction}
This is the introduction.

%Labelling
Referring to section \ref{sec1} on page \pageref{sec1}

%Table of Contents
\pagenumbering{roman}
\tableofcontents
\newpage
\pagenumbering{arabic}

%Font Effects
\textit{words in italics}
\textsl{words slanted}
\textsc{words in smallcaps}
\textbf{words in bold}
\texttt{words in teletype}
\textsf{sans serif words}
\textrm{roman words}
\underline{underlined words}

%Coloured Text
{\color{colour_name}text}

%Font Sizes
{\tiny tiny words}
{\scriptsize scriptsize words}
{\footnotesize footnotesize words}
{\small small words}
{\normalsize normalsize words}
{\large large words}
{\Large Large words}
{\LARGE LARGE words}
{\huge huge words}

%Lists
\begin{itemize}
\item[-] First thing
\item[+] Second thing
\begin{itemize}
\item[Fish] A sub-thing
\item[Plants] Another sub-thing
\end{itemize}
\item[Q] Third thing
\end{itemize}

%Tables
\begin{tabular}{|l|l|}
Apples & Green \\
Strawberries & Red \\
Oranges & Orange \\
\end{tabular}

%Figures
\begin{figure}[h]
\centering
\includegraphics[width=1\textwidth]{image}
\caption{Here is image}
\label{image}
\end{figure}

%Mathematical
$\sin(x)$
$$\sin(x)$$
\[\sin(x)\]
\(\sin(x)\)

\begin{equation}1+2=3\end{equation}
\begin{eqnarray}
  a & = & b + c \\
    & = & y - z
\end{eqnarray}
$\alpha$ = α
$\beta$ = β
$\delta, \Delta$ = δ, ∆
$\theta, \Theta$ = θ, Θ

%Comments
\begin{comment}
This is a comment.
\end{comment}

%Lstlistings|Minted
\lstdefinelanguage{JavaScript}{
    morestring=[b]`
}

\lstset{language=JavaScript}
\begin{lstlisting}
    let x = `this is a ${string}`
\end{lstlisting}

\begin{minted}{python}
import numpy as np

def incmatrix(genl1,genl2):
    m = len(genl1)
    n = len(genl2)
    M = None #to become the incidence matrix
    VT = np.zeros((n*m,1), int)  #dummy variable

    #compute the bitwise xor matrix
    M1 = bitxormatrix(genl1)
    M2 = np.triu(bitxormatrix(genl2),1)

    for i in range(m-1):
        for j in range(i+1, m):
            [r,c] = np.where(M2 == M1[i,j])
            for k in range(len(r)):
                VT[(i)*n + r[k]] = 1
                VT[(i)*n + c[k]] = 1
                VT[(j)*n + r[k]] = 1
                VT[(j)*n + c[k]] = 1

                if M is None:
                    M = np.copy(VT)
                else:
                    M = np.concatenate((M, VT), 1)

                VT = np.zeros((n*m,1), int)

    return M
\end{minted}

\begin{VerbatimOut}{ex-scala-logstage.tmp}
    class ExampleService(log: IzLogger) {
      val justAnArg = "example"
      val justAList = List[Any](10, "green", "bottles")
      val msec = Random.nextInt(1000)
      log.trace(s"Argument: $justAnArg, another arg: $justAList")
      log.info(s"Expr: ${Random.nextInt() -> "number"}")
      log.warn(s"Hidden: ${Random.nextInt() -> "number" -> null}")
      val ctxLog = log("userId" -> "user@google.com"
        , "company" -> "acme")
      ctxLog.info(s"Processing time: $msec")
    }
\end{VerbatimOut}

\end{document}
\documentclass{article}


\chapter*{Resonators}
<<<<<<< HEAD
Though the physical models described in the previous part are also considered resonators, they are \textit{ideal} cases. In other words, you would not be able to find these ``in the wild'' as they do not includes effects such as losses or frequency dispersion.

This part presents the different resonators used over the course of the project and is structured as follows: Chapter \ref{ch:stiffString} introduces the stiff string, a model which has been used a lot over the course of this project, Chapter \ref{ch:brass} talks about brass instruments, or more generally, 1D systems of varying geometry along their spatial dimension. Finally, Chapter \ref{ch:2Dsyst} will introduces 2D systems which, in this project, have been used to simulate (simplified) instrument bodies.
=======
Although the physical models described in the previous part -- the simple mass-spring system and the 1D wave equation -- are also considered resonators, they are \textit{ideal} cases. In other words, these can not be found in the real world as effects such as losses or frequency dispersion are not included.

This part presents the different resonators used over the course of the project that better include these non-ideal physical processes and is structured as follows: Chapter \ref{ch:stiffString} introduces the stiff string, an extension of the 1D wave equation, % and is the single most-used model in this project.
Chapter \ref{ch:brass} introduces acoustic tubes, used to model brass instruments, and finally, Chapter \ref{ch:2Dsyst} introduces 2D systems which, in this project, have been used to simulate (simplified) instrument bodies. The analysis techniques introduced in the previous part will be applied to all models and described in detail.
>>>>>>> master


%% Journal of Open Research Software Latex template -- Created By Stephen
%% Bonner and John Brennan, Durham University, UK.
%% see http://openresearchsoftware.metajnl.com

% \documentclass{../jors}

% {\bf Software paper for submission to the Journal of Open Research Software} \\
%
% To complete this template, please replace the blue text with your own. The
% paper has three main sections: (1) Overview; (2) Availability; (3) Reuse
% potential.
%
% Please submit the completed paper to: editor.jors@ubiquitypress.com
%
% \rule{\textwidth}{1pt}
%
\section{Overview}
%
% \vspace{0.5cm}
%
% \subsection{Title}
%
% % \textcolor{blue}{The title of the software paper should focus on the software,
% % e.g. “Text mining software from the X project”. If the software is closely
% % linked to a specific research paper, then “Software from Paper Title” is
% % appropriate. The title should be factual, relating to the functionality of the
% % software and the area it relates to rather than making claims about the
% % software, e.g. “Easy-to-use”.}
%
% FluidFFT: common API (C++ and Python) for Fast Fourier Transform HPC libraries
%
% \subsection{Paper Authors}
%
% % \textcolor{blue}{1. Last name, first name; (Lead/corresponding author first) \\
% % 2. Last name, first name; etc.}
%
% 1. MOHANAN Ashwin Vishnu$^a$\\
% 2. BONAMY Cyrille$^b$\\
% 3. AUGIER Pierre$^b$\\
%
% \smallskip
%
% $^a$ Linn\'e Flow Centre, Department of Mechanics, KTH, 10044 Stockholm, Sweden.
% $^b$ Univ. Grenoble Alpes, CNRS, Grenoble INP\footnote{Institute of Engineering
% Univ. Grenoble Alpes}, LEGI, 38000 Grenoble, France.\\
%
% \subsection{Paper Author Roles and Affiliations}
% % \textcolor{blue}{1. First author role and affiliation \\
% % 2. Second author role and affiliation etc.}
%
% 1. Ph.D. student, Linn\'e Flow Centre, KTH Royal Institute of Technology,
% Sweden; \\
% 2. Research Engineer, LEGI, Universit\'e Grenoble Alpes, CNRS, France; \\
% 3. Researcher, LEGI, Universit\'e Grenoble Alpes, CNRS, France

% \subsection{Abstract}

% \textcolor{blue}{A short (ca. 100 word) summary of the software being
% described: what problem the software addresses, how it was implemented and
% architected, where it is stored, and its reuse potential.}

% The Python package \fluidpack{fft} provides a common Python API for performing
% Fast Fourier Transforms (FFT) in sequential, in parallel and on GPU with different
% FFT libraries (FFTW, P3DFFT, PFFT, cuFFT). \fluidpack{fft} is a comprehensive FFT
% framework which allows Python users to easily and efficiently perform FFT and the
% associated tasks, such as as computing linear operators and energy spectra.
% %
% We describe the architecture of the package composed of C++ and Cython FFT
% classes, Python ``operator'' classes and Pythran functions.
% %
% The package supplies utilities to easily test itself and benchmark the different
% FFT solutions for a particular case and on a particular machine.
% %
% We present a performance scaling analysis on three different computing clusters
% and a microbenchmark showing that \fluidpack{fft} is an interesting solution to
% write efficient Python applications using FFT.
%
% \subsection{Keywords}
%
% % \textcolor{blue}{keyword 1; keyword 2; etc. \\
% % Keywords should make it easy to identify who and what the software will be
% % useful for.}
%
% Free and open-source library; Python; Fast Fourier Transform; Distributed; MPI;
% GPU; High performance computing%
%
\subsection{Introduction}

% \textcolor{blue}{An overview of the software, how it was produced, and the
% research for which it has been used, including references to relevant research
% articles. A short comparison with software which implements similar
% functionality should be included in this section. }

Fast Fourier Transform (FFT) is a class of algorithms used to calculate the
discrete Fourier transform, which traces back its origin to the groundbreaking
work by \citet{cooley_tukey}.
%
Ever since then, FFT as a computational tool has been applied in multiple
facets of science and technology, including digital signal processing, image
compression, spectroscopy, numerical simulations and scientific computing in
general. There are many good libraries to perform FFT, in particular the
\emph{de-facto} standard \libpack{FFTW} \citep{frigo2005design}.\@ A challenge
is to efficiently scale FFT on clusters with the memory distributed over a
large number of cores using Message Passing Interface (MPI). This is imperative
to solve big problems faster and when the arrays do not fit in the memory of
single computational node.
%
A problem is that for one-dimensional FFT, all the data have to be located in the
memory of the process that perform the FFT, so a lot of communications between
processes are needed for 2D and 3D FFT.

To elaborate, there is only one way to apply domain decomposition for 2D FFT,
which is to split them into narrow strips across one dimension. However for 3D
FFT, there are two strategies to distribute an array in the memory, the 1D (or
\emph{slab}) decomposition and the 2D (or \emph{pencil}) decomposition. The 1D
decomposition is more efficient when only few processes are used but suffers
from an important limitation in terms of number of MPI processes that can be
used. Utilizing 2D decomposition overcomes this limitation.

Some of the well-known libraries are written in C, C++ and Fortran. The classical
\libpack{FFTW} library supports MPI using 1D decomposition and hybrid parallelism
using MPI and OpenMP. Other libraries, now implement the 2D decomposition for
FFT over 3D arrays: \libpack{PFFT} \citep{pippig_pfft2013}, \libpack{P3DFFT}
\citep{pekurovsky2012p3dfft}, \libpack{2decomp\&FFT} and so on. These libraries
rely on MPI for the communications between processes, are optimized for
supercomputers and scales well to hundreds of thousands of cores. However, since
there is no common API, it is not simple to write applications that are able to
use these libraries and to compare their performances. As a result, developers are
met with a hard decision, which is to choose a library before the code is
implemented.

Apart from CPU-based parallelism, General Purpose computing on Graphical
Processing Units (GPGPU) is also gaining traction in scientific computing.
Scalable libraries written for GPGPU such as OpenCL and CUDA have emerged, with
their own FFT implementations, namely \libpack{clFFT} and \libpack{cuFFT}
respectively.

% As explained in the companion paper \citet{fluiddyn},
Python can easily link these libraries through compiled extensions. For a Python
developer, the following packages leverage this approach to perform FFT:

\begin{outline}
  \1 sequential FFT, using:
    \2 \pack{numpy.fft} and \pack{scipy.fftpack} which are essentially
    C and Fortran extensions for \libpack{FFTPACK} library.
    \2 \pack{pyFFTW} which wraps \libpack{FFTW} library and provides interfaces similar to
    the \pack{numpy.fft} and \pack{scipy.fftpack} implementations.
    \2 \pack{mkl\_fft}, which wraps Intel's \libpack{MKL} library and exposes python
    interfaces to act as drop-in replacements for \pack{numpy.fft} and
    \pack{scipy.fftpack}.
  \1 FFT with MPI, using:
    \2 \pack{mpiFFT4py} and \pack{mpi4py-fft} built on top of \pack{pyFFTW} and
    \pack{numpy.fft}.
    \2 \pack{pfft-python} which provides extensions for
    PFFT library.
  \1 FFT with GPGPU, using:
    \2 \pack{Reikna}, a pure python package which depends on \pack{PyCUDA}
    and \pack{PyOpenCL}
    \2 \pack{pytorch-fft}: provides C extensions for cuFFT, meant to work with
    PyTorch, a tensor library similar to NumPy.
\end{outline}

Although these Python packages are under active development, they suffer from
certain drawbacks:

\begin{itemize}
  \item No effort so far to consolidate sequential, MPI and GPGPU based FFT
  libraries under a single package with similar syntax.

  \item Quite complicated even for the simplest use case scenarios. To
  understand how to use them, a novice user has to, at least, read the
  \libpack{FFTW} documentation.

  \item No benchmarks between libraries and between the Python
  solutions and solutions based only on a compiled language (as C, C++ or
  Fortran).

  \item Provides just the FFT and inverse FFT functions, no associated
  mathematical operators.

\end{itemize}

The Python package \fluidpack{fft} fills this gap by providing C++ classes and
their Python wrapper classes for performing simple and common tasks with different
FFT libraries. It has been written to make things easy while being as efficient as
possible. It provides:

\begin{itemize}
\item tests,

\item documentation and tutorials,

\item benchmarks,

\item operators for simple tasks (for example, compute the energy or the
gradient of a field).

\end{itemize}

In the present article, we shall start by describing the implementation of
\fluidpack{fft} including its design aspects and the code organization. Thereafter,
we shall compare the performance of different classes in \fluidpack{fft} in
three computing clusters, and also describe, using microbenchmarks, how a Python
function can be optimized to be as fast as a Fortran implementation. Finally,
we show how we test and maintain the quality of the code base through
continuous integration and mention some possible applications of
\fluidpack{fft}.

\subsection{Implementation and architecture}

% \textcolor{blue}{How the software was implemented, with details of the
% architecture where relevant. Use of relevant diagrams is appropriate. Please
% also describe any variants and associated implementation differences.}
The two major design goals of \fluidpack{fft} are:
\begin{itemize}
 \item to support multiple FFT libraries under the same umbrella and expose the
 interface for both C++ and Python code development.
 \item to keep the design of the interfaces as human-centric and easy to use as
 possible, without sacrificing performance.
\end{itemize}

Both C++ and Python APIs provided by \fluidpack{fft} currently support linking
with \libpack{FFTW} (with and without MPI and OpenMP support enabled),
\libpack{MKL}, \libpack{PFFT}, \libpack{P3DFFT}, \libpack{cuFFT} libraries. The
classes in \fluidpack{fft} offers API for performing
double-precision\footnote{Most C++ classes also support single-precision.}
computation with real-to-complex FFT, complex-to-real inverse FFT, and additional
helper functions.

\subsubsection{C++ API}

\begin{figure}[htp]
  \centering
  \includegraphics[width=\linewidth]{Pyfig/fig_classes}
  \caption{Class hierarchy demonstrating object-oriented approach. The
    sequential classes are shown in red, the CUDA-based classes in magenta and
    the MPI-based classes in green. The arrows represent inheritance from
    parent to child class.
  }\label{fig:classes}
\end{figure}

The C++ API is implemented as a hierarchy of classes as shown in
Fig.~\ref{fig:classes}.
%
The naming convention used for the classes (\codeinline{<Type of FFT>With<Name of
Library>}) is a cue for how these are functioning internally.
%
By utilizing inheritance, the classes share the same function names and syntax
defined in the \emph{base} classes, shown in white boxes in
Fig.~\ref{fig:classes}. Some examples of such functions are:

\begin{itemize}
  \item \codeinline{alloc\_array\_X}: Allocates array to store a physical array
    with real datatype for the current process.
  \item \codeinline{alloc\_array\_K}: Allocates array to store a spectral array
    with complex datatype  for the current process.
  \item \codeinline{init\_array\_X\_random}: Allocates and initializes a physical
    array with random values.
  \item \codeinline{test}: Run tests for a class by comparing mean and mean energy
    values in an array before and after a set of \codeinline{fft} and
    \codeinline{ifft} calls.
  \item \codeinline{bench}: Benchmark the \codeinline{fft} and
    \codeinline{ifft} methods for certain number of iterations.
\end{itemize}

Remaining methods which are specific to a library are defined in the
corresponding child classes, depicted in coloured boxes in
Fig.~\ref{fig:classes}, for example:

\begin{itemize}
  \item \codeinline{are\_parameters\_bad}: Verifies whether the global array
    shape can be decomposed with the number of MPI processes available or not.
    If the parameters are compatible, the method returns \codeinline{false}.
    This method is called prior to initializing the class.
  \item \codeinline{fft} and \codeinline{ifft}: Forward and inverse FFT
    methods.
\end{itemize}

Let us illustrate with a trivial example, wherein we initialize the FFT with a
random physical array, and perform a set of \codeinline{fft} and \codeinline{ifft}
operations.
\begin{minted}[fontsize=\footnotesize]{cpp}
#include <iostream>
using namespace std;

#include <fft3dmpi_with_fftwmpi3d.h>
// #include <fft3dmpi_with_p3dfft.h>

int main(int argc, char **argv) {
  int N0 = N1 = N2 = 32;
  // MPI-related
  int nb_procs = 4;
  MPI_Init(&argc, &argv);
  MPI_Comm_size(MPI_COMM_WORLD, &(nb_procs));

  myreal* array_X;
  mycomplex* array_K;

  FFT3DMPIWithFFTWMPI3D o(N0, N1, N2);
  // FFT3DMPIWithP3DFFT o(N0, N1, N2);

  o.init_array_X_random(array_X);
  o.alloc_array_K(array_K);
  o.fft(array_X, array_K);
  o.ifft(array_K, array_X);
  MPI_Finalize();
  return 0;
}
\end{minted}

As suggested through comments above, in order to switch the FFT library, the
user only needs to change the header file and the class name. An added
advantage is that, the user does not need to bother about the domain
decomposition while declaring and allocating the arrays. A few more helper
functions are available with the FFT classes, such as functions to compute the
mean value and energies in the array. These are demonstrated with examples in
the documentation.\footnote{%
\url{https://fluidfft.readthedocs.io/en/latest/examples/cpp.html}.}
%
Detailed information regarding the C++ classes and its member functions are
also included in the online documentation\footnote{%
\url{https://fluidfft.readthedocs.io/en/latest/doxygen/index.html}.}.

\subsubsection{Python API} Similar to other packages in the FluidDyn project,
\fluidpack{fft} also uses an object-oriented approach, providing FFT classes.
%
This is in contrast with the approach adopted by \pack{numpy.fft} and \pack{%
scipy.fftpack} which provides functions instead, with which the user has to
figure out the procedure to design the input values and to use the return
values, from the documentation.
%
In \fluidpack{fft}, the Python API wraps all the functionalities of its C++
counterpart and offers a richer experience through an accompanying
operator class.

As a short example, let us try to calculate the gradient of a plane sine-wave
using spectral methods, mathematically described as follows:

\begin{align*}
  u(x,y) &=
    \sin(x + y) &\forall x,y \in \left[0, L \right] \\
  \hat u(k_x,k_y) &=
    \frac{1}{L^2}
    \int_0^{L}\int_0^{L}
    u(x,y) \exp(ik_x x + ik_y y) dx dy \\
  \nabla u(x,y) &=
    \sum_{k_x} \sum_{k_y}
    i\mathbf{k}
    \hat u(k_x,k_y) \exp(-ik_x x - ik_y y)
\end{align*}
%
where $k_x$, $k_y$ represent the wavenumber corresponding to $x$ and $y$ directions,
and $\mathbf{k}$ is the wavenumber vector.

The equivalent pseudo-spectral implementation in \fluidpack{fft} is as follows:
\begin{minted}[fontsize=\footnotesize]{python}
  from fluidfft.fft2d.operators import OperatorsPseudoSpectral2D, pi
  from numpy import sin

  nx = ny = 100
  lx = ly = 2 * pi

  oper = OperatorsPseudoSpectral2D(nx, ny, lx, ly, fft="fft2d.with_fftw2d")

  u = sin(oper.XX + oper.YY)
  u_fft = oper.fft(u)
  px_u_fft, py_u_fft = oper.gradfft_from_fft(u_fft)
  px_u = oper.ifft(px_u_fft)
  py_u = oper.ifft(py_u_fft)
  grad_u = (px_u, py_u)
\end{minted}

A parallelized version of the code above will work out of the box, simply by
replacing the FFT class with an MPI-based FFT class, for instance
\codeinline{fft2d.with\_fftwmpi2d}. One can also let \fluidpack{fft} automatically
choose an appropriate FFT class by instantiating the operator class with
\codeinline{fft=None} or \codeinline{fft="default"}. Even if one finds the methods
in the operator class to be lacking, one can inherit the class and easily create a
new method, for instance using the wavenumber arrays, \codeinline{oper.KX} and
\codeinline{oper.KY}.  Arguably, a similar implementation with other available
packages would require the know-how on how FFT arrays are allocated in the memory,
normalized, decomposed in parallel and so on.
%
Moreover, the FFT and the operator classes contain objects describing the shapes
of the real and complex arrays and how the data is shared between processes.
%
A more detailed introduction on how
to use \fluidpack{fft} and available functions can be found in the
tutorials\footnote{%
\url{https://fluidfft.readthedocs.io/en/latest/tutorials.html}.}.

Thus, we have demonstrated how, by using \fluidpack{fft}, a developer can
easily switch between FFT libraries.
%
Let us now turn our attention to how the code is organized. We shall also describe
how the source code is built, and linked with the supported libraries.

\subsubsection{Code organization}
\begin{figure}[htp]
  \centering
  \includegraphics[width=0.96\linewidth]{Pyfig/fig_build_use}
  \caption{Flowchart illustrating how the C++ and Python API are built and used
  for one particular class, viz. \codeinline{FFT2DMPIWithFFTWMPI2D}. The dotted
  arrows in C++ part stand for include statements, demonstrating the class
  hierarchy and in the Python part indicate how different codes are imported. On
  the bottom, a smaller flowchart demonstrates how to use the API by writing user
  code.  }\label{fig:build_use}
\end{figure}

The internal architecture of \fluidpack{fft} can be visualized as layers.  Through
Fig.~\ref{fig:build_use}, we can see how these layers are linked together forming
the API for C++ and Python development. For simplicity, only one FFT class is
depicted in the figure, namely \codeinline{FFT2DMPIWithFFTWMPI2D}, which wraps
\libpack{FFTW}'s parallelized 2D FFT implementation. The C++ API is accessed by
importing the appropriate header file and building the user code with a Makefile,
an example of which is available \href{%
https://fluidfft.readthedocs.io/en/latest/examples/cpp.html}{%
in the documentation}.

The Python API is built automatically when \fluidpack{fft} is
installed\footnote{%
\href{https://fluidfft.readthedocs.io/en/latest/install.html}{Detailed steps
for installation} are provided in the documentation.}.
%
It first generates the Cython source code as a pair of \codeinline{.pyx} and
\codeinline{.pxd} files containing a class wrapping its C++
counterpart\footnote{Uses an approach similar to guidelines \href{%
    https://cython.readthedocs.io/en/latest/src/userguide/wrapping_CPlusPlus.html}{%
``Using C++ in Cython''} in the Cython documentation.}.
%
The Cython files are produced from template files (specialized for the 2D and
3D cases) using the template library \mako.
%
Thereafter, \pack{Cython} \citep{behnel_cython2011} generates C++ code with
necessary Python bindings, which are then built in the form of extensions or
dynamic libraries importable in Python code. All the built extensions are then
installed as a Python package named \fluidpack{fft}.

A helper function \codeinline{fluidfft.import\_fft\_class} is provided with the
package to simply import the FFT class. However, it is more convenient and
recommended to use an operator class, as described in the example for Python
API.\@ Although the operator classes can function as pure Python code, some of
its critical methods can be compiled, if \pack{Pythran}
\citep{guelton2018pythran} is available during installation of
\fluidpack{fft}. We will show towards the end of this section that by using
\pack{Pythran}, we reach the performance of the equivalent Fortran code.

To summarize, \fluidpack{fft} consists of the following layers:
\begin{itemize}

\item One C++ class per FFT library derived from a hierarchy of C++ classes
as shown in Fig.~\ref{fig:classes}.

\item \pack{Cython} wrappers of the C++ classes with their unit test cases.

\item Python operator classes (2D and 3D) to write code independently of the
library used for the computation of the FFT and with some mathematical helper
methods. These classes are accompanied by unit test cases.

\item \pack{Pythran} functions to speedup critical methods in the Python
operator classes.

\end{itemize}

Command-line utilities (\codeinline{fluidfft-bench} and
\codeinline{fluidfft-bench-analysis}) are also provided with the \fluidpack{fft}
installation to run benchmarks and plot the results. In the next subsection, we
shall look at some results by making use of these utilities on three computing
clusters.

\subsubsection{Performance}

\paragraphbf{Scalability tests using \codeinline{fluidfft-bench}}

% Simple!! Few cases. Few clusters. Figures obtained with
% fluidfft-bench-analysis

Scalability of \fluidpack{fft} is measured in the form of strong scaling speedup,
defined in the present context as:
\begin{equation*}
S_\alpha(n_p) = \frac
{[\mathrm{Time\ elapsed\ for\ } N \mathrm{\ iterations\ with\ }n_{p,\min}\mathrm{\ processes}]_{\mathrm{fastest}}
\times n_{p,\min}}
{[\mathrm{Time\ elapsed\ for\ } N \mathrm{\ iterations\ with\ } n_p \mathrm{\
processes}]_\alpha}
\label{eq:speedup}
\end{equation*}

where $n_{p,\min}$ is the minimum number of processes employed for a specific
array size and hardware. The subscripts, $\alpha$ denotes the FFT class used and
``fastest'' corresponds to the fastest result among various FFT classes.

To compute strong scaling the utility \codeinline{fluidfft-bench} is launched
as scheduled jobs on HPC clusters, ensuring no interference from background
processes. No hyperthreading was used.
%
We have used $N=20$ iterations for each run, with which we obtain sufficiently
repeatable results.
%
For a particular choice of array size, every FFT class available are
benchmarked for the two tasks, forward and inverse FFT. Three different function
variants are compared (see the legend in subsequent figures):

\begin{itemize}

\item \codeinline{fft\_cpp}, \codeinline{ifft\_cpp} (continuous lines): benchmark
of the C++ function from the C++ code. An array is passed as an argument to store
the result. No memory allocation is performed inside these functions.

\item \codeinline{fft\_as\_arg}, \codeinline{ifft\_as\_arg} (dashed lines):
benchmark of a Python method from Python. Similar to the C++ code, the second
argument of this method is an array to contain the result of the transform, so no
memory allocation is needed.

\item \codeinline{fft\_return}, \codeinline{ifft\_return} (dotted lines):
benchmark of a Python method from Python. No array is provided to the function to
contain the result, and therefore a numpy array is created and then returned by
the function.

\end{itemize}

On big HPC clusters, we have only focussed on 3D array transforms as benchmark
problems, since these are notoriously expensive to compute and require massive
parallelization.  The physical arrays used in all four 3D MPI based FFT classes
are identical in structure.  However, there are subtle differences, in terms of
how the domain decomposition and the allocation of the transformed array in the
memory are handled\footnote{Detailed discussion on \href{%
https://fluidfft.readthedocs.io/en/latest/ipynb/executed/tuto_fft3d_mpi_domain_decomp.html}{%
``FFT 3D parallel (MPI): Domain decomposition''} tutorial}.

Hereafter, for the sake of brevity, the FFT classes will be named in terms of the
associated library (For example, the class \codeinline{FFT3DMPIWithFFTW1D} is
named \codeinline{fftw1d}).  Let us go through the results\footnote{Saved at
\url{%
https://bitbucket.org/fluiddyn/fluidfft-bench-results}} plotted using
\codeinline{fluidfft-bench-analysis}.

\paragraph{Benchmarks on Occigen}

\href{https://www.top500.org/system/178465}{Occigen} is a GENCI-CINES HPC
cluster which uses Intel Xeon CPU E5--2690 v3 (2.6 GHz) processors with 24 cores
per node. The installation was performed using Intel C++ 17.2 compiler, Python
3.6.5, and OpenMPI 2.0.2.

\begin{figure}[htp!]
\centering
\includegraphics[width=\linewidth]{tmp/fig_occigen_384x1152x1152}
\caption{Speedup computed from the median of the elapsed times for 3D fft
(384$\times$1152$\times$1152, left: fft and right: ifft) on Occigen.}%
\label{fig:occigen384x1152x1152}
\end{figure}

Fig.~\ref{fig:occigen384x1152x1152} demonstrates the strong scaling performance
of a cuboid array sized $384\times1152\times1152$. This case is particularly
interesting since for FFT classes implementing 1D domain decomposition
(\codeinline{fftw1d} and \codeinline{fftwmpi3d}), the processes are spread on
the first index for the physical input array. This restriction is as a result
of some \libpack{FFTW} library internals and design choices adopted in
\fluidpack{fft}. This limits \codeinline{fftw1d} (our own MPI implementation
using MPI types and 1D transforms from FFTW) to 192 cores and
\codeinline{fftwmpi3d} to 384 cores. The latter can utilize more cores since it
is capable of working with empty arrays, while sharing some of the
computational load.
%
The fastest methods for relatively
low and high number of processes are \codeinline{fftw1d} and
\codeinline{p3dfft} respectively for the present case.

The benchmark is not sufficiently accurate to measure the cost of calling the
functions from Python (difference between continuous and dashed lines,
i.e. between pure C++ and the \codeinline{as\_arg} Python method) and even the
creation of the numpy array (difference between the dashed and the dotted line,
i.e. between the \codeinline{as\_arg} and the \codeinline{return} Python
methods).

\begin{figure}[htp!]
\centering
\includegraphics[width=\linewidth]{tmp/fig_occigen_1152x1152x1152}
\caption{Speedup computed from the median of the elapsed times for 3D fft
(1152$\times$1152$\times$1152, left: fft and right: ifft) on Occigen.}
\label{fig:occigen1152x1152x1152}
\end{figure}

Fig.~\ref{fig:occigen1152x1152x1152} demonstrates the strong scaling
performance of a cubical array sized $1152\times1152\times1152$. For this
resolution as well, \codeinline{fftw1d} is the fastest method when using only
few cores and it can not be used for more that 192 cores. The faster library
when using more cores is also \codeinline{p3dfft}. This also shows that
\fluidpack{fft} can effectively scale for over 10,000 cores with a significant
increase in speedup.

\paragraph{Benchmarks on Beskow}

\href{ https://www.pdc.kth.se/hpc-services/computing-systems}{Beskow} is a Cray
machine maintained by SNIC at PDC, Stockholm. It runs on Intel(R) Xeon(R) CPU
E5-2695 v4 (2.1 GHz) processors with 36 cores per node. The installation was
done using Intel C++ 18 compiler, Python 3.6.5 and CRAY-MPICH 7.0.4.

\begin{figure}[htp!]
\centering
\includegraphics[width=\linewidth]{tmp/fig_beskow_384x1152x1152}
\caption{Speedup computed from the median of the elapsed times for 3D fft
(384$\times$1152$\times$1152, left: fft and right: ifft) on Beskow.}
\label{fig:beskow384x1152x1152}
\end{figure}

In Fig.~\ref{fig:beskow384x1152x1152}, the strong scaling results of the cuboid
array can be observed. In this set of results we have also included intra-node
scaling, wherein there is no latency introduced due to typically slower
node-to-node communication. The fastest library for very low (below 16) and
very high (above 384) number of processes in this configuration is
\codeinline{p3dfft}. For moderately high number of processes (16 and above) the
fastest library is \codeinline{fftwmpi3d}. Here too, we notice that
\codeinline{fftw1d} is limited to 192 cores and \codeinline{fftwmpi3d} to 384
cores, for reasons mentioned earlier.

A striking difference when compared with Fig.~\ref{fig:occigen384x1152x1152} is
that \codeinline{fftw1d} is not the fastest of the four classes in this machine.
One can only speculate that this could be a consequence of the differences in MPI
library and hardware which has been employed. This also emphasises the need to
perform benchmarks when using an entirely new configuration.

\begin{figure}[htp!]
\centering
\includegraphics[width=\linewidth]{tmp/fig_beskow_1152x1152x1152}
\caption{Speedup computed from the median of the elapsed times for 3D fft
(1152$\times$1152$\times$1152, left: fft and right: ifft) on Beskow.}
\label{fig:beskow1152x1152x1152}
\end{figure}

The strong scaling results of the cubical array on Beskow are displayed on
Fig.~\ref{fig:beskow1152x1152x1152}, wherein we restrict to inter-node
computation.  We observe that the fastest method for low number of processes is
again, \codeinline{fftwmpi3d}. When high number of processes (above 1000)
are utilized, initially \codeinline{p3dfft} is the faster methods as before,
but with 3000 and above processes, \codeinline{pfft} is comparable in speed and
sometimes faster.

\paragraph{Benchmarks on a LEGI cluster}

Let us also analyse how \fluidpack{fft} scales on a computing cluster
maintained at an institutional level, named Cluster8 at \href{%
http://www.legi.grenoble-inp.fr}{LEGI}, Grenoble. This cluster functions using
Intel Xeon CPU E5-2650 v3 (2.3 GHz) with 20 cores per node and \fluidpack{fft}
was installed using a toolchain which comprises of gcc 4.9.2, Python 3.6.4 and
OpenMPI 1.6.5 as key software components.

\begin{figure}[htp!]
\centering
\includegraphics[width=\linewidth]{tmp/fig_legi_cluster8_320x640x640}
\caption{Speedup computed from the median of the elapsed times for 3D fft
(320$\times$640$\times$640) at LEGI on cluster8.}
\label{fig:cluster8:320x640x640}
\end{figure}

In Fig.~\ref{fig:cluster8:320x640x640} we observe that the strong scaling for an
array shape of $320\times640\times640$ is not far from the ideal linear trend. The
fastest library is \codeinline{fftwmpi3d} for this case.  As expected from FFT
algorithms, there is a slight drop in speedup when the array size is not exactly
divisible by the number of processes, i.e.\ with 12 processes. The speedup
declines rapidly when more than one node is employed (above 20 processes). This
effect can be attributed to the latency introduced by inter-node communications, a
hardware limitation of this cluster (10 Gb/s).

\begin{figure}[htp!]
\centering
\includegraphics[width=\linewidth]{tmp/fig_legi_cluster8_2160x2160}
\caption{Speedup computed from the median of the elapsed times for 2D fft
(2160$\times$2160) at LEGI on cluster8.}
\label{fig:cluster8:2160x2160}
\end{figure}

We have also analysed the performance of 2D MPI enabled FFT classes on the same
machine using an array shaped $2160\times2160$ in
Fig.~\ref{fig:cluster8:2160x2160}. The fastest library is
\codeinline{fftwmpi2d}. Both \codeinline{fftw1d} and \codeinline{fftwmpi2d}
libraries display near-linear scaling, except when more than one node is used
and the performance tapers off.

As a conclusive remark on scalability, a general rule of thumb should be to use
1D domain decomposition when only very few processors are employed. For massive
parallelization, 2D decomposition is required to achieve good speedup without
being limited by the number of processors at disposal. We have thus shown that
overall performance of the libraries interfaced by \fluidpack{fft} are quite
good, and there is no noticeable drop in speedup when the Python API is used.
%
This benchmark analysis also shows that the fastest FFT implementation depends
on the size of the arrays and on the hardware.
%
Therefore, an application build upon \fluidpack{fft} can be efficient for
different sizes and machines.

\paragraphbf{Microbenchmark of critical ``operator'' functions}

As already mentioned, we use \pack{Pythran} \citep{guelton2018pythran} to
compile some critical ``operator'' functions.  In this subsection, we present a
microbenchmark for one simple task used in pseudo-spectral codes: projecting a
velocity field on a non-divergent velocity field.  It is performed in spectral
space, where it can simply be written as
\begin{minted}[fontsize=\footnotesize]{python}
# pythran export proj_out_of_place(
#     complex128[][][], complex128[][][], complex128[][][],
#     float64[][][], float64[][][], float64[][][], float64[][][])

def proj_out_of_place(vx, vy, vz, kx, ky, kz, inv_k_square_nozero):
    tmp = (kx * vx + ky * vy + kz * vz) * inv_k_square_nozero
    return vx - kx * tmp, vy - ky * tmp, vz - kz * tmp
\end{minted}
Note that, this implementation is ``out-of-place'', meaning that the result is
returned by the function and that the input velocity field (\codeinline{vx, vy,
vz}) is unmodified.
%
The comment above the function definition is a \pack{Pythran} annotation, which
serves as a type-hint for the variables used within the functions --- all
arguments being \pack{Numpy} arrays in this case.
%
\pack{Pythran} needs such annotation to be able to compile this code into
efficient machine instructions \emph{via} a C++ code.
%
Without \pack{Pythran} the annotation has no effect, and
of course, the function defaults to using Python with \pack{Numpy} to execute.

The array notation is well adapted and less verbose to express this simple
vector calculus.
%
Since explicit loops with indexing is not required, the computation with Python
and \pack{Numpy} is not extremely slow. Despite this being quite a favourable
case for \pack{Numpy}, the computation with \pack{Numpy} is not optimized
because, internally, it involves many loops (one per arithmetic operator) and
creation of temporary arrays.
%av: Have I understood correctly here with the clarifications: "internally" &
%   "arithmetic operator"?

\begin{figure}[htp]
\centering
\includegraphics[width=\linewidth]{tmp/fig_microbench}
\caption{Elapsed time (smaller is better) for the projection function for
different implementations and tools.  The shape of the arrays is
$(128,\ 128,\ 65)$. The dotted lines indicate the times for Fortran for better
comparison.}
\label{fig:microbench}
\end{figure}

In the top axis of Fig.~\ref{fig:microbench}, we compare the elapsed times for
different implementations of this function.
%
For this out-of-place version, we used three different codes:
\begin{enumerate}
\item a Fortran code (not shown\footnote{The codes and a Makefile used for this
benchmark study are available in \href{%
https://bitbucket.org/fluiddyn/fluiddyn_paper/src/default/fluidfft/microbench/}{%
the repository of the article}.}) written with three nested explicit loops (one
per dimension). Note that as in the Python version we also allocate the memory
where the result is stored.
\item the simplest Python version shown above.
\item a Python version with three nested explicit loops:
% (code not shown).
\begin{minted}[fontsize=\footnotesize]{python}
# pythran export proj_out_of_place_loop(
#     complex128[][][], complex128[][][], complex128[][][],
#     float64[][][], float64[][][], float64[][][], float64[][][])

def proj_out_of_place_loop(vx, vy, vz, kx, ky, kz, inv_k_square_nozero):

    rx = np.empty_like(vx)
    ry = np.empty_like(vx)
    rz = np.empty_like(vx)

    n0, n1, n2 = kx.shape

    for i0 in range(n0):
        for i1 in range(n1):
            for i2 in range(n2):
                tmp = (kx[i0, i1, i2] * vx[i0, i1, i2]
                       + ky[i0, i1, i2] * vy[i0, i1, i2]
                       + kz[i0, i1, i2] * vz[i0, i1, i2]
                ) * inv_k_square_nozero[i0, i1, i2]

                rx[i0, i1, i2] = vx[i0, i1, i2] - kx[i0, i1, i2] * tmp
                ry[i0, i1, i2] = vz[i0, i1, i2] - kx[i0, i1, i2] * tmp
                rz[i0, i1, i2] = vy[i0, i1, i2] - kx[i0, i1, i2] * tmp

    return rx, ry, rz
\end{minted}
\end{enumerate}
For the version without explicit loops, we present the elapsed time for two
cases: (i) simply using Python (yellow bar) and (ii) using the Pythranized
function (first cyan bar).
%
For the Python version with explicit loops, we only present the results for (i)
the Pythranized function (second cyan bar) and (ii) the result of \pack{Numba}
(blue bar).
%
We do not show the result for \pack{Numba} for the code without explicit loops
because it is slower than \pack{Numpy}. We have also omitted the result for
\pack{Numpy} for the code with explicit loops because it is very inefficient.
%
The timing is performed upon tuning the computer using the package
\href{https://pypi.org/project/perf/}{\pack{perf}}.

We see that \pack{Numpy} is approximately three time slower than the Fortran
implementation (which as already mentioned contains the memory allocation).
%
Just using \pack{Pythran} without changing the code (first cyan bar), we save
nearly 50\% of the execution time but we are still significantly slower than
the Fortran implementation.
%
We reach the Fortran performance (even slightly faster) only by using
\pack{Pythran} with the code with explicit loops.
%
With this code, \pack{Numba} is nearly as fast (but still slower) without
requiring any type annotation.

Note that the exact performance differences depend on the hardware, the software
versions\footnote{Here, we use Python~3.6.4 (packaged by conda-forge),
\pack{Numpy}~1.13.3, \pack{Pythran}~0.8.5, \pack{Numba}~0.38, gfortran~6.3 and
clang~6.0.}, the compilers and the compilation options.
%
We use \codeinline{gfortran -O3 -march=native} for Fortran and
\codeinline{clang++ -O3 -march=native} for \pack{Pythran}\footnote{The results
with \codeinline{g++ -O3 -march=native} are very similar but tend to be slightly
slower.}.
%

Since allocating memory is expensive and we do not need the non-projected
velocity field after the call of the function, an evident optimization is to
put the output in the input arrays.  Such an ``in-place'' version can be written
with \pack{Numpy} as:
\begin{minted}[fontsize=\footnotesize]{python}
# pythran export proj_in_place(
#     complex128[][][], complex128[][][], complex128[][][],
#     float64[][][], float64[][][], float64[][][], float64[][][])

def proj_in_place(vx, vy, vz, kx, ky, kz, inv_k_square_nozero):
    tmp = (kx * vx + ky * vy + kz * vz) * inv_k_square_nozero
    vx -= kx * tmp
    vy -= ky * tmp
    vz -= kz * tmp
\end{minted}

As in the first version, we have included the \pack{Pythran} annotation.
%
We also consider an ``in-place'' version with explicit loops:
\begin{minted}[fontsize=\footnotesize]{python}
# pythran export proj_in_place_loop(
#     complex128[][][], complex128[][][], complex128[][][],
#     float64[][][], float64[][][], float64[][][], float64[][][])

def proj_in_place_loop(vx, vy, vz, kx, ky, kz, inv_k_square_nozero):

    n0, n1, n2 = kx.shape

    for i0 in range(n0):
        for i1 in range(n1):
            for i2 in range(n2):
                tmp = (kx[i0, i1, i2] * vx[i0, i1, i2]
                       + ky[i0, i1, i2] * vy[i0, i1, i2]
                       + kz[i0, i1, i2] * vz[i0, i1, i2]
                ) * inv_k_square_nozero[i0, i1, i2]

                vx[i0, i1, i2] -= kx[i0, i1, i2] * tmp
                vy[i0, i1, i2] -= ky[i0, i1, i2] * tmp
                vz[i0, i1, i2] -= kz[i0, i1, i2] * tmp

\end{minted}
Note that this code is much longer and clearly less readable than the version
without explicit loops.  This is however the version which is used in
\pack{fluidfft} since it leads to faster execution.

The elapsed time for these in-place versions and for an equivalent Fortran
implementation are displayed in the bottom axis of Fig.~\ref{fig:microbench}.
%
The ranking is the same as for the out-of-place versions and \pack{Pythran} is also
the faster solution.
%
However, \pack{Numpy} is even more slower (7.8 times slower than \pack{Pythran}
with the explicit loops) than for the out-of-place versions.

From this short and simple microbenchmark, we can infer four main points:
\begin{itemize}
\item Memory allocation takes time!  In Python, memory management is automatic
and we tend to forget it.  An important rule to write efficient code is to
reuse the buffers already allocated as much as possible.

\item Even for this very simple case quite favorable for \pack{Numpy} (no indexing
or slicing), \pack{Numpy} is three to eight time slower than the Fortran
implementations. As long as the execution time is small or that the
function represents a small part of the total execution time, this is not an
issue. However, in other cases, Python-\pack{Numpy} users need to consider
other solutions.

\item \pack{Pythran} is able to speedup the \pack{Numpy} code without explicit
loops and is as fast as Fortran (even slightly faster in our case) for the
codes with explicit loops.

\item \pack{Numba} is unable to speedup the \pack{Numpy} code.
%
It gives very interesting performance for the version with explicit loops
without any type annotation but the result is significantly slower than with
\pack{Pythran} and Fortran.
\end{itemize}

For the aforementioned reasons, we have preferred \pack{Pythran} to compile
optimized ``operator'' functions that complement the FFT classes. Although with
this we obtain remarkable performance, there is still room for some
improvement, in terms of logical implementation and allocation of arrays. For
example, applications such as CFD simulations often deals with non-linear terms
which require dealiasing. The FFT classes of \fluidpack{fft}, currently
allocates the same number of modes in the spectral array so as to transform the
physical array. Thereafter, we apply dealiasing by setting zeros to wavenumbers
which are larger than, say, two-thirds of the maximum wavenumber. Instead, we
could take into account dealiasing in the FFT classes to save some memory and
computation time\footnote{See
\href{https://bitbucket.org/fluiddyn/fluidfft/issues/21/}{fluidfft issue 21}.}.

\subsection{Quality control}

% \textcolor{blue}{Detail the level of testing that has been carried out on the
% code (e.g. unit, functional, load etc.), and in which environments. If not
% already included in the software documentation, provide details of how a user
% could quickly understand if the software is working (e.g. providing examples of
% running the software with sample input and output data). }

The package \fluidpack{fft} currently supplies unit tests covering 90\% of its
code.  These unit tests are run regularly through continuous integration on Travis
CI with the most recent releases of \fluidpack{fft}'s dependencies and on
Bitbucket Pipelines inside a static
\href{https://hub.docker.com/u/fluiddyn}{Docker container}.  The tests are run
using standard Python interpreter with all supported versions.

For \fluidpack{fft}, the code coverage results are displayed at
\href{https://codecov.io/bb/fluiddyn/fluidfft}{Codecov}.  Using third-party
packages \pack{coverage} and \pack{tox}, it is straightforward to bootstrap the
installation with dependencies, test with multiple Python versions and combine the
code coverage report, ready for upload. It is also possible to run similar
isolated tests using \pack{tox} or coverage analysis using \pack{coverage} in a
local machine.  Up-to-date build status and coverage status are displayed on the
landing page of the Bitbucket repository.  Instructions on how to run unit tests,
coverage and lint tests are included in the documentation.

We also try to follow a consistent code style as recommended by PEP (Python
enhancement proposals) 8 and 257. This is also inspected using lint checkers such
as \codeinline{flake8} and \codeinline{pylint} among the developers.  The Python
code is regularly cleaned up using the code formatter \codeinline{black}.

\section{Availability}
\vspace{0.5cm}
\subsection{Operating system}

% \textcolor{blue}{Please include minimum version compatibility.}

Windows and any POSIX based OS, such as GNU/Linux and macOS.

\subsection{Programming language}

% \textcolor{blue}{Please include minimum version compatibility.}

Python 2.7, 3.5 or above. For the next versions, we will
\href{https://python3statement.org/}{drop Python 2.7 support and Python $>=$
3.6 will be required}.
%
Note that while Cython and Pythran both use the C API of CPython, \fluidpack{fft}
has been successfully tested on PyPy 6.0.
%
A C++11 supporting compiler, while not mandatory for the C++ API or Cython
extensions of \fluidpack{fft}, is recommended to be able to use Pythran extensions.

\subsection{Dependencies}

% \textcolor{blue}{E.g. libraries, frameworks, incl. minimum version
% compatibility.}
\paragraph{C++ API:}
\begin{itemize}
  \item{\bf Optional:} \pack{OpenMPI} or equivalent, \libpack{FFTW},
    \libpack{P3DFFT}, \libpack{PFFT} and \libpack{cuFFT} libraries.
\end{itemize}

Python API:

\begin{itemize}
\item {\bf Minimum:} \fluidpack{dyn}, \pack{Numpy}, \pack{Cython}, and
  \pack{mako}\ or \pack{Jinja2}; \libpack{FFTW} library.
\item {\bf Optional:} \pack{mpi4py} and \pack{Pythran}; \libpack{P3DFFT},
  \libpack{PFFT} and \libpack{cuFFT} libraries.
\end{itemize}

\subsection{List of contributors}

% \textcolor{blue}{Please list anyone who helped to create the software (who may
% also not be an author of this paper), including their roles and affiliations.}

\begin{itemize}
\item Pierre Augier (LEGI): creator of the FluidDyn project and of
\fluidpack{fft}.
\item Cyrille Bonamy (LEGI): C++ code and some methods in the operator classes.
\item Ashwin Vishnu Mohanan (KTH): command lines utilities, benchmarks, unit
  tests, continuous integration, and bug fixes.
\end{itemize}

\subsection{Software location}

\paragraph{\bf Archive}
% {\bf Archive} \textcolor{blue}{(e.g. institutional repository, general
% repository) (required – please see instructions on journal website for
% depositing archive copy of software in a suitable repository)}

\begin{description}[noitemsep,topsep=0pt]
\item[Name:] PyPI
\item[Persistent identifier:] https://pypi.org/project/fluidfft
\item[Licence:] CeCILL, a free software license adapted to both international
and French legal matters, in the spirit of and retaining compatibility with the
GNU General Public License (GPL).
\item[Publisher:] Pierre Augier
\item[Version published:] 0.2.4
\item[Date published:] 02/07/2018
\end{description}

{\bf Code repository}

\begin{description}[noitemsep,topsep=0pt]
\item[Name:] Bitbucket
\item[Persistent identifier:] https://bitbucket.org/fluiddyn/fluidfft
\item[Licence:] CeCILL
\item[Date published:] 2017
\end{description}

{\bf Emulation environment}

\begin{description}[noitemsep,topsep=0pt]
\item[Name:] Docker
\item[Persistent identifier:] https://hub.docker.com/r/fluiddyn/python3-stable
\item[Licence:] CeCILL-B, a BSD compatible French licence.
\item[Date published:] 02/10/2017
\end{description}

\subsection{Language}

% \textcolor{blue}{Language of repository, software and supporting files.}

English

\section{Reuse potential}

% \textcolor{blue}{Please describe in as much detail as possible the ways in
% which the software could be reused by other researchers both within and outside
% of your field. This should include the use cases for the software, and also
% details of how the software might be modified or extended (including how
% contributors should contact you) if appropriate. Also you must include details
% of what support mechanisms are in place for this software (even if there is no
% support).}

\fluidpack{fft} is used by the Computational Fluid Mechanics framework
\fluidpack{sim} \citep{fluidsim}. It could be used by any C++ or Python project
where real-to-complex 2D or 3D FFTs are performed.

There is no formal support mechanism. However, bug reports can be submitted at
the \href{https://bitbucket.org/fluiddyn/fluidsim/issues}{Issues page on
Bitbucket}. Discussions and questions can be aired on instant messaging
channels in Riot (or equivalent with Matrix protocol)\footnote{
\url{%
  https://matrix.to/\#/\#fluiddyn-users:matrix.org}}
or via IRC protocol on Freenode at \codeinline{\#fluiddyn-users}. Discussions
can also be exchanged via the official mailing list\footnote{
\url{https://www.freelists.org/list/fluiddyn}}.

\subsection*{Acknowledgements}

% \textcolor{blue}{Please add any relevant acknowledgements to anyone else who
% supported the project in which the software was created, but did not work
% directly on the software itself.}

Ashwin Vishnu Mohanan could not have been as involved in this project without the
kindness of Erik Lindborg.
%
We are grateful to Bitbucket for providing us with a high quality forge
compatible with Mercurial, free of cost.

\subsection*{Funding statement}

% \textcolor{blue}{If the software resulted from funded research please give the
% funder and grant number.}

This project has indirectly benefited from funding from the foundation Simone et
Cino Del Duca de l'Institut de France, the European Research Council (ERC)
under the European Union's Horizon 2020 research and innovation program (grant
agreement No 647018-WATU and Euhit consortium) and the Swedish Research Council
(Vetenskapsr{\aa}det): 2013--5191.
%
We have also been able to use supercomputers of CIMENT/GRICAD, CINES/GENCI
(grant 2018-A0040107567) and the Swedish National Infrastructure for Computing
(SNIC).

\subsection*{Competing interests}

% \textcolor{blue}{If any of the authors have any competing interests then these
% must be declared. The authors’ initials should be used to denote differing
% competing interests. For example: “BH has minority shares in [company name],
% which part funded the research grant for this project. All other authors have
% no competing interests."
% %
% If there are no competing interests, please add the statement: “The authors
% declare that they have no competing interests.” }

The authors declare that they have no competing interests.

% \subsection{References}

% \textcolor{blue}{Please enter references in the Harvard style and include a DOI
% where available, citing them in the text with a number in square brackets,
% e.g.}

% \rule{\textwidth}{1pt}
\vspace{10pt}
\hrule
\vspace{10pt}

\paragraphbf{Copyright Notice}

Authors who publish with this journal agree to the following terms:

Authors retain copyright and grant the journal right of first publication with
the work simultaneously licensed under a
\href{http://creativecommons.org/licenses/by/3.0/}{Creative Commons Attribution
License} that allows others to share the work with an acknowledgement of the
work's authorship and initial publication in this journal.

Authors are able to enter into separate, additional contractual arrangements
for the non-exclusive distribution of the journal's published version of the
work (e.g., post it to an institutional repository or publish it in a book),
with an acknowledgement of its initial publication in this journal.

By submitting this paper you agree to the terms of this Copyright Notice, which
will apply to this submission if and when it is published by this journal.