\chapter{The Cubic Nonlinear Schr\"{o}dinger Equation}

%%%%%%%
%Section
%%%%%%%
\section{Background}

The cubic nonlinear Schr\"{o}dinger equation occurs in a variety of areas, including, quantum mechanics, nonlinear optics and surface water waves. A general introduction can be found at \url{http://en.wikipedia.org/wiki/Schrodinger_equation} and \url{http://en.wikipedia.org/wiki/Nonlinear_Schrodinger_equation}. A mathematical introduction to Schr\"{o}dinger equations can be found in Sulem and Sulem~\cite{SulSul99} and Yang~\cite{Yan10}. In this section we will introduce the idea of operator splitting and then go on to explain how this can be applied to the nonlinear Schr\"{o}dinger equation in one, two and three dimensions. In one dimension, one can show that the cubic nonlinear Schr\"{o}dinger equation is subcritical, and hence one has solutions which exist for all time. In two dimensions, it is $H^1$ critical, and so solutions may exhibit blow-up of the $H^1$ norm, that is the integral of the square of the gradient of the solution can become infinite in finite time.  Finally, in three dimensions, the nonlinear Schr\"{o}dinger equation is $L^2$ supercritical, and so the integral of the square of the solution can also become infinite in finite time. For an introduction to norms and Hilbert spaces, see a textbook on partial differential equations or analysis, such as Evans~\cite{Eva10}, Linares and Ponce~\cite{LinPon09}, Lieb and Loss~\cite{LieLos03} or Renardy and Rogers~\cite{RenRog04}. A question of interest is how this blow-up occurs and numerical simulations are often used to understand this; see Sulem and Sulem~\cite{SulSul99} for examples of this. The cubic nonlinear Schr\"{o}dinger equation\footnote{To simplify the presentation, we primarily consider the focusing cubic nonlinear Schr\"{o}dinger equation.} is given by
\begin{equation}
i\psi_t + \Delta \psi \pm\lvert \psi \rvert^2\psi =0,
\end{equation}
where $\psi$ is the wave function and $\Delta$ is the Laplacian operator, so in one dimension it is $\partial_{xx}$, in two dimensions, $\partial_{xx}+\partial_{yy}$ and in three dimensions it is $\partial_{xx}+\partial_{yy}+\partial_{zz}$. The $+$ corresponds to the focusing cubic nonlinear Schr\"{o}dinger equation and the $-$ corresponds to the defocusing cubic nonlinear Schr\"{o}dinger equation. This equation has many conserved quantities, including the ``mass'',
\begin{equation}
\int_{\Omega}\lvert\psi\rvert^2\mathrm{d}^n\bm x
\end{equation}
and the ``energy'',
\begin{equation}
\int_{\Omega}\frac{1}{2}\lvert\nabla \psi\rvert^2\mp\frac{1}{4}\lvert\psi\rvert^4\mathrm{d}^n\bm x
\end{equation}
where $n$ is the dimension and $\Omega$ is the domain of the solution. As explained by Klein~\cite{Kle08}, these two quantities can provide useful checks on the accuracy of numerically generated solutions.

%%%%%%%
%Section
%%%%%%%
\section{Splitting}

We will consider a numerical method to solve this equation known as splitting. This method occurs in several applications, and is a useful numerical method when the equation can be split into two separate equations, each of which can either be solved exactly, or each part is best solved by a different numerical method. Introductions to splitting can be found in Holden et al.~\cite{HolKarLieRis10}, McLachlan and Quispel~\cite{McLQui02}, Thalhammer~\cite{Tha08}, Shen, Tang and Wang~\cite{SheTanWan11}, Weideman and Herbst~\cite{WeiHer86} and Yang~\cite{Yan10}, and also at \url{http://en.wikipedia.org/wiki/Split-step_method}. For those interested in a comparison of time stepping methods for the nonlinear Schr\"{o}dinger equation, see Klein~\cite{Kle08}. To describe the basic idea of the method, we consider an example given in Holden et al.~\cite{HolKarRisTao11}, which is the ordinary differential equation,
\begin{equation}\label{eq:SplitOde}
u_t=u(u-1),\quad u(t=0)=0.8.
\end{equation}
We can solve this equation relatively simply by separation of variables to find that
\begin{equation}
u(t)=\frac{4}{4+\exp(t)}.
\end{equation}
Now, an interesting observation is that we can also solve the equations $u_t=u^2$ and $u_t=-u$ individually. For the first we get that $u(t)=\frac{u(0)}{1-tu(0)}$ and for the second we get that $u(t)=u(0)\exp(-t)$. The principle behind splitting is to solve these two separate equations alternately for short periods of time. We will describe Strang splitting, although there are other forms of splitting, such as Godunov splitting and also additive splittings.  We will not describe these here, but refer you to the previously mentioned references, in particular Holden et al.~\cite{HolKarLieRis10}. To understand how we can solve the differential equation using splitting, consider the linear ordinary differential equation
\begin{equation}
u_t=u+2u,\quad u(0)=1.
\end{equation}
We can first solve $p_t=p$ for a time $\delta t/2$ and then using $q(0)=p(\delta t/2)$, we solve $q_t=2q$ also for a time $\delta t$ to get $q(\delta t)$ and finally solve $r_t=r$ for a time $\delta t/2$ with initial data $r(0)=q(\delta t)$. Thus in this case $p(\delta t)=\exp(\delta t/2)$, $q(\delta t)=p(\delta t/2)\exp(2\delta t)=\exp(5\delta t/2)$ and $u(\delta t)\approx r(\delta t/2)=q(\delta t)\exp(\delta t/2)=\exp(3\delta t)$, which in this case is the exact solution. One can perform a similar splitting for matrix differential equations. Consider solving $\bm u_t = (\bm A + \bm B)\bm u$, where $\bm A$ and $\bm B$ are $n\times n$ matrices, the exact solution is $\bm u=\exp\left((\bm A + \bm B) t\right)\bm u(t=0)$, and an approximate solution produced after one time step of splitting is $u(\delta t)\approx u(0)\exp(\bm A \delta t)\exp(\bm B \delta t)$, which is not in general equal to $u(t=0)\exp\left((\bm A + \bm B) \delta t\right)$ unless the matrices $\bm A$ and $\bm B$ commute\footnote{That is$\bm A\bm B=\bm B\bm A$.}, and so the error in doing splitting in this case is of the form $(\bm A \bm B - \bm B \bm A)\delta t$\footnote{One can derive this by using the series expansion of the exponential function, $\exp(\bm A t)=\sum_{n=0}^{\infty}\frac{(\bm A t)^n}{n!}$, and subtracting $\exp((\bm A+\bm B)\delta t)$ from $\exp(\bm A \delta t)\exp(\bm B \delta t).$}. Listing \ref{lst:OdeStrangMatlab} uses Matlab to demonstrate how to do splitting for eq.\ \eqref{eq:SplitOde}.

\lstinputlisting[style=matlab_style,label=lst:OdeStrangMatlab,caption={A Matlab program which uses Strang splitting to solve an ODE.}]{./CubicNonlinearSchrodinger/Programs/ODEsplittingStrang.m}

%%%%%%%
%Section
%%%%%%%
\section{Exercises}

\begin{enumerate}
\item[1)] Modify the Matlab code to calculate the error at time 1 for several different choices of timestep. Numerically verify that Strang splitting is second order accurate.
\item[2)] Modify the Matlab code to use Godunov splitting where one solves $u1_t=u1$ for a time $\delta t$ and then using $u1(\delta t)$ as initial data solves $u2_t=2u2$ also for a time $\delta t$ to get the approximation to $u(\delta t)$. Calculate the error at time 1 for several different choices of timestep. Numerically verify that Godunov splitting is first order accurate.
\end{enumerate}
%%%%%%%
%Section
%%%%%%%
\section{Serial}

For the nonlinear Schr\"{o}dinger equation
\begin{equation}
i\psi_t\pm\lvert\psi\rvert^2\psi+\Delta\psi=0, \label{eq:NLS}
\end{equation}
we first solve
\begin{equation}
i\psi_t+\Delta\psi=0 \label{eq:NLSsplit1}
\end{equation}
exactly using the Fourier transform to get $\psi(\delta{t}/2,\cdot)$. We then solve
\begin{equation}
i\psi_t\pm\lvert\psi\rvert^2\psi=0  \label{eq:NLSsplit2}
\end{equation}
with $\psi(\delta{t}/2,\cdot)$ as initial data for a time step of $\delta t$. As explained by Klein~\cite{Kle08} and Thalhammer~\cite{Tha08}, this can be solved exactly in real space because in eq.\ \eqref{eq:NLSsplit2}, $\lvert \psi \rvert^2$ is a conserved quantity at every point in space and time. To show this, let $\psi^*$ denote the complex conjugate of $\psi$, so that
\begin{align}
\frac{\mathrm{d}\lvert \psi \rvert^2}{\mathrm{d}t} &{} = \psi^*\frac{\mathrm{d}\psi}{\mathrm{d}t} +\frac{\mathrm{d}\psi^*}{\mathrm{d}t}\psi = \psi^*\left(\pm i\lvert\psi\rvert^2\psi\right)+\left(\pm i\lvert\psi\rvert^2\psi\right)^*\psi = 0.
\end{align}
Another half step using eq.\ \eqref{eq:NLSsplit1} is then computed using the solution produced by solving eq.\ \eqref{eq:NLSsplit2} to obtain the approximate solution at time $\delta t$.  Example Matlab codes demonstrating splitting follow.

\subsection{Example Matlab Programs for the Nonlinear Schr\"{o}dinger Equation}

The program in listing \ref{lst:NlsSplit1DMatlab} computes an approximation to an explicitly known exact solution to the focusing nonlinear Schr\"{o}dinger equation.

\lstinputlisting[style=matlab_style,label=lst:NlsSplit1DMatlab,caption={A Matlab program which uses Strang splitting to solve the one dimensional nonlinear Schr\"{o}dinger equation.}]{./CubicNonlinearSchrodinger/Programs/NLSsplitting1D.m}

\lstinputlisting[style=matlab_style,label=lst:NlsSplit2DMatlab,caption={A Matlab program which uses Strang splitting to solve the two dimensional nonlinear Schr\"{o}dinger equation.}]{./CubicNonlinearSchrodinger/Programs/NLSsplitting2D.m}

\lstinputlisting[style=matlab_style,label=lst:NlsSplit3DMatlab,caption={A Matlab program which uses Strang splitting to solve the three dimensional nonlinear Schr\"{o}dinger equation.}]{./CubicNonlinearSchrodinger/Programs/NLSsplitting3D.m}

%%%%%%%
%Section
%%%%%%%
\section{Example One-Dimensional Fortran Program for the Nonlinear Schr\"{o}dinger Equation}

Before considering parallel programs, we need to understand how to write a Fortran code for the one-dimensional nonlinear Schr\"{o}dinger equation. Below is an example Fortran program followed by a Matlab plotting script to visualize the results. In compiling the Fortran program a standard Fortran compiler and the FFTW library are required. Since the commands required for this are similar to those in the makefile for the heat equation, we do not include them here.

\lstinputlisting[style=fortran_style,language=Fortran,label=lst:For1dNLS,caption={A Fortran program to solve the 1D nonlinear Schr\"{o}dinger equation using splitting.}]{./CubicNonlinearSchrodinger/Programs/NLS1dFortran/NLSsplitting.f90}

\lstinputlisting[style=matlab_style,label=lst:NlsSplit1DMatlabPlot,caption={A Matlab program which plots a numerical solution to a 1D nonlinear Schr\"{o}dinger equation generated by listing \ref{lst:For1dNLS}.}]{./CubicNonlinearSchrodinger/Programs/NLS1dFortran/plotcreate.m}

%%%%%%%
%Section
%%%%%%%
\section{Shared Memory Parallel: OpenMP}

We recall that OpenMP is a set of compiler directives that can allow one to easily make a Fortran, C or C++ program run on a shared memory machine -- that is a computer for which all compute processes can access the same globally addressed memory space. It allows for easy parallelization of serial programs which have already been written in one of the aforementioned languages.

We will demonstrate one form of parallelizm for the two dimensional nonlinear Schr\"{o}dinger equation in which we will parallelize the loops using OpenMP commands, but will use the threaded FFTW library to parallelize the transforms for us. The example programs are in listing \ref{lst:For2dNlsOmp1},   A second method to parallelize the loops and Fast Fourier transforms explicitly using OpenMP commands is outlined in the exercises.

\lstinputlisting[style=fortran_style,language=Fortran,label=lst:For2dNlsOmp1,caption={An OpenMP Fortran program to solve the 2D nonlinear Schr\"{o}dinger equation using splitting and threaded FFTW.}]{./CubicNonlinearSchrodinger/Programs/NLS2dFortranThreadFFT/NLSsplitting.f90}

\lstinputlisting[style=make_style,language=make,label=lst:Makefile2dNLSomp2,caption={An example makefile for compiling the OpenMP program in listing \ref{lst:For2dNlsOmp1}. The example assumes one is using Flux and has loaded environments for the GCC compiler as well as the GCC compiled version of FFTW.  To use the Intel compiler to with this code, the OMP stack size needs to be explicitly set to be large enough.  If one is using the the PGI compilers instead of the GCC compilers, change the flag $-fopenmp$ to $-mp$.}]{./CubicNonlinearSchrodinger/Programs/NLS2dFortranThreadFFT/makefile}

\lstinputlisting[style=matlab_style,label=lst:NlsSplit2DMatlabPlot,caption={A Matlab program which plots a numerical solution to a 2D nonlinear Schr\"{o}dinger equation generated by listing \ref{lst:For2dNlsOmp1} or \ref{lst:For2dNlsOmp2}.}]{./CubicNonlinearSchrodinger/Programs/NLS2dFortran/plotcreate.m}

\lstinputlisting[style=bash_style,language=bash,label=lst:Fluxsub2dNLSomp,caption={An example submission script for use on Flux. Change \texttt{your\_username} appropriately.}]{./CubicNonlinearSchrodinger/Programs/NLS2dFortran/fluxsubscript}

%%%%%%%
%Section
%%%%%%%
\section{Exercises}
\begin{enumerate}
\item[1)] Download the example Matlab programs which accompany the pre-print by Klein, Muite and Roidot~\cite{KleMuiRoi11}. Examine how the mass and energy for these Schr\"{o}dinger like equations are computed. Add code to check conservation of mass and energy to the Matlab programs for the nonlinear Schr\"{o}dinger equation.
\item[2)] The Gross-Pitaevskii equation\footnote{\url{http://en.wikipedia.org/wiki/Gross\%E2\%80\%93Pitaevskii\_equation}}  is given by
\begin{equation}
i\psi_t+\lvert\psi\rvert^2\psi +V(\bm x)\psi=0
\end{equation}
where we will take
\begin{equation}
V(\bm x)=\lVert \bm x \rVert^2_{l^2}=\sum_{k=1}^Nx_k^2
\end{equation}
in which $N$ is the space dimension. Show that this equation can be solved by splitting it into
\begin{equation}
i\psi_t+\Delta\psi=0 \label{eq:GPsplit1}
\end{equation}
and
\begin{equation}
i\psi_t+\lvert\psi\rvert^2\psi+V(\bm x)\psi=0.  \label{eq:GPsplit2}
\end{equation}
Be sure to explain how eqs.\ \eqref{eq:GPsplit1},\eqref{eq:GPsplit2} are solved.
\item[3)] Modify the Matlab codes to solve the Gross-Pitaevskii equation in one, two and three dimensions.
\item[4)] Modify the serial Fortran codes to solve the Gross-Pitaevskii equation in one, two and three dimensions.
\item[5)] Listings \ref{lst:For2dNlsOmp2} and \ref{lst:Makefile2dNLSomp2} give an alternate method of parallelizing an OpenMP program. Make the program in listing \ref{lst:For2dNlsOmp1} as efficient as possible and as similar to that in \ref{lst:For2dNlsOmp2}, but without changing the parallelization strategy. Compare the speed of the two different programs. Try to vary the number of grid points and cores used. Which code is faster on your system? Why do you think this is?

\lstinputlisting[style=fortran_style,language=Fortran,label=lst:For2dNlsOmp2,caption={An OpenMP Fortran program to solve the 2D nonlinear Schr\"{o}dinger equation using splitting.}]{./CubicNonlinearSchrodinger/Programs/NLS2dFortran/NLSsplitting.f90}

\lstinputlisting[style=make_style,language=make,label=lst:Makefile2dNLSomp2,caption={An example makefile for compiling the OpenMP program in listing \ref{lst:For2dNlsOmp2}.  The example assumes one is using Flux and has loaded environments for the intel compiler as well as the Intel compiled version of FFTW.  If one is using the freely available GCC compilers instead of the Intel compilers, change the flag $-openmp$ to $-fopenmp$.}]{./CubicNonlinearSchrodinger/Programs/NLS2dFortran/makefile}

\item[6)] Modify the OpenMP Fortran codes to solve the Gross-Pitaevskii equation in two and three dimensions.
\item[7)] \footnote{This question is due to a project by Joshua Kirschenheiter.} Some quantum hydrodynamic models for plasmas are very similar to the nonlinear Schr\"{o}dinger equation and can also be numerically approximated using splitting methods.  A model for a plasma used by Eliasson and Shukla~\cite{EliShu09} is
$$i\Psi_t+\Delta \Psi + \phi\Psi - \lvert \Psi \rvert^{4/D}\Psi=0$$
and
$$ \Delta \phi =\lvert \Psi \rvert^2-1,$$
where $\Psi$ is the, $\phi$ the and $D$ the dimension, typically 1,2 or 3. This equation can be solved in a similar manner to the Davey-Stewartson equations in Klein, Muite and Roidot~\cite{KleMuiRoi11}. Specifically, first solve
$$i\Psi_t+\Delta \Psi=0$$
using the Fourier transform so that
$$\Psi(\delta t)=\exp\left(-i\Delta^2 \delta t\right)\Psi(0)$$
Then solve
$$\phi=\Delta^{-1}\left(\lvert \Psi \rvert^2-1\right)$$
using the Fourier transform.  Finally, solve
$$i\Psi_t+ \phi\Psi - \lvert \Psi \rvert^{4/D}\Psi=0$$
using the fact that at each grid point $\phi\Psi - \lvert \Psi \rvert^{4/D}$ is a constant, so the solution is
$$\Psi=\exp\left[ i\left(\phi-\lvert \Phi \rvert^{4/D}\right)\delta t\right].$$
\item[8)] \footnote{This question is due to a project by Kohei Harada and Matt Warnez.}The operator splitting method can be used for equations other than the nonlinear Schr\"{o}dinger equation. Another equation for which operator splitting can be used is the complex Ginzburg-Landau equation
$$\frac{\partial A}{\partial t}=A+(1+i\alpha)\Delta A- (1+i\beta)|A|^2A,$$
where $A$ is a complex function, typically of one, two or three variables. An example one dimensional code is provided in listing \ref{lst:Nls16thOrderMatlab}, based on an earlier finite difference code by Blanes, Casa, Chartier and Miura, using the methods described in Blanes et al.~\cite{BlaCasChaMur12}. By using complex coefficients,  Blanes et al.~\cite{BlaCasChaMur12} can create high order splitting methods for parabolic equations. Previous attempts to do this have failed since if only real coefficients are used, a backward step which is required for methods higher than second order leads to numerical instability. Modify the example code to solve the complex Ginzburg-Landau equation in one, two and then in three spatial dimensions. The linear part
$$\frac{\partial A}{\partial t}=A+(1+i\alpha)\Delta A$$
can be solved explicitly using the Fourier transform. To solve the nonlinear part,
$$\frac{\partial A}{\partial t}=- (1+i\beta)|A|^2A$$
consider
$$\frac{\partial |A|^2}{\partial t}=\frac{\partial A}{\partial t}A^*+\frac{\partial A^*}{\partial t}A=2|A|^4$$
and solve this exactly for $|A|^2$. To recover the phase, observe that
$$\frac{\partial \log(A)}{\partial t}=- (1+i\beta)|A|^2$$
which can also be integrated explicitly since $|A|^2(t)$ is known.

\lstinputlisting[style=matlab_style,label=lst:Nls16thOrderMatlab,caption={A Matlab program which uses 16th order splitting to solve the cubic nonlinear Schr\"{o}dinger equation.}]{./CubicNonlinearSchrodinger/Programs/NLSsplitting1d16Order.m}
\end{enumerate}

%%%%%%%
%Section
%%%%%%%
\section{Distributed Memory Parallel: MPI}

For this section, we will use the library 2DECOMP{\&}FFT available from \url{http://www.2decomp.org/index.html}. The website includes some examples which indicate how this library should be used, in particular the sample code at \url{http://www.2decomp.org/case_study1.html} is a very helpful indication of how one converts a code that uses FFTW to one that uses MPI and the aforementioned library.

Before creating a parallel MPI code using 2DECOMP{\&}FFT, we will generate  a serial Fortran code that uses splitting to solve the 3D nonlinear Schr\"{o}dinger equation. Rather than using loop-based parallelization to do a sequence of one dimensional fast Fourier transforms, we will use FFTW's three dimensional FFT, so that the serial version and MPI parallel version have the same structure. The serial version is in listing \ref{lst:For3dNls}. This file can be compiled in a similar manner to that in \ref{lst:MakefileHeat}.

\lstinputlisting[style=fortran_style,language=Fortran,label=lst:For3dNls,caption={A Fortran program to solve the 3D nonlinear Schr\"{o}dinger equation using splitting and FFTW.}]{./CubicNonlinearSchrodinger/Programs/NLS3dFortran/NLSsplitting.f90}

In comparison to the previous programs, the program in listing \ref{lst:For3dNls} writes out its final data as a binary file. This is often significantly faster than writing out a text file, and the resulting file is usually much smaller in size. This is important when many such files are written and/or if individual files are large. Due to the formatting change, the binary file also needs to be read in slightly differently. The Matlab script in listing \ref{lst:NlsSplit3DMatlabPlot} shows how to do this.

\lstinputlisting[style=matlab_style,label=lst:NlsSplit3DMatlabPlot,caption={A Matlab program which plots a numerical solution to a 3D nonlinear Schr\"{o}dinger equation generated by listings \ref{lst:For3dNls} or \ref{lst:For3dNlsMPI}.}]{./CubicNonlinearSchrodinger/Programs/NLS3dFortran/plotcreate.m}

We now modify the above code to use MPI and the library 2DECOMP{\&}FFT.  The library 2DECOMP{\&}FFT hides most of the details of MPI although there are a few commands which it is useful for the user to understand. These commands are:
\begin{itemize}
\item \texttt{USE mpi} or \texttt{INCLUDE 'mpif.h'}
\item \texttt{MPI\_INIT}
\item \texttt{MPI\_COMM\_SIZE}
\item \texttt{MPI\_COMM\_RANK}
\item \texttt{MPI\_FINALIZE}
\end{itemize}

The program is listed in listing \ref{lst:For3dNlsMPI}, please compare this to the serial code in \ref{lst:For3dNls}. The library 2DECOMP{\&}FFT does a domain decomposition of the arrays so that separate parts of the arrays are on separate processors.  The library can also perform a Fourier transform on the arrays even though they are stored on different processors -- the library does all the necessary message passing and transpositions required to perform the Fourier transform. It should be noted that the order of the entries in the arrays after the Fourier transform is not necessarily the same as the order used by FFTW. However, the correct ordering of the entries is returned by the structure \texttt{decomp} and so this structure is used to obtain starting and stopping entries for the loops. We assume that the library 2DECOMP{\&}FFT has been installed in an appropriate location.

\lstinputlisting[style=fortran_style,language=Fortran,label=lst:For3dNlsMPI,caption={A Fortran program to solve the 3D nonlinear Schr\"{o}dinger equation using splitting and 2DECOMP{\&}FFT.}]{./CubicNonlinearSchrodinger/Programs/NLS3dFortranMPI/NLSsplitting.f90}

%%%%%%%
%Section
%%%%%%%
\section{Exercises}

\begin{enumerate}
\item[1)] Write an MPI  code using 2DECOMP{\&}FFT to solve the Gross-Pitaevskii equation in three dimensions.
\item[2)] Learn to use either VisIt (\url{https://wci.llnl.gov/codes/visit/}) or Paraview (\url{http://www.paraview.org/}) and write a script to visualize two and three dimensional output in a manner that is similar to the Matlab codes.
\end{enumerate}


\section{Computational routines}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%      DENSE MATRIX SUM
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\clearpage\subsection{psb\_geaxpby --- General Dense Matrix Sum}

This subroutine is an interface to the computational kernel for
dense matrix sum:
\[ y \leftarrow  \alpha\> x+ \beta y \]
%% where:
%% \begin{description}
%% \item[$x$] represents the global dense submatrix $x_{:, :1}$
%% \item[$y$] represents the global dense submatrix $y_{:, :}$
%% \end{description}

\fortinline| call psb_geaxpby(alpha, x, beta, y, desc_a, info)|
%% \syntax*{call psb\_geaxpby}{alpha, x, beta, y, desc\_a, info, n, jx, jy}

%( calculating y <- alpha*x+beta*y )
\begin{table}[h]
\begin{center}
\begin{tabular}{ll}
\hline
$x$, $y$, $\alpha$, $\beta$ & {\bf Subroutine}\\
\hline
Short Precision Real & psb\_geaxpby \\
Long Precision Real & psb\_geaxpby \\
Short Precision Complex & psb\_geaxpby \\
Long Precision Complex & psb\_geaxpby \\
\hline
\end{tabular}
\end{center}
\caption{Data types\label{tab:f90axpby}}
\end{table}

\begin{description}
\item[Type:] Synchronous.
\item[\bf On Entry]
\item[alpha] the scalar $\alpha$.\\ Scope: {\bf global} \\ Type: {\bf
required} \\ Intent: {\bf in}.\\ Specified as: a number of the data
type indicated in Table~\ref{tab:f90axpby}.
\item[x] the local portion of global dense matrix
$x$.\\
Scope: {\bf local} \\
Type: {\bf required} \\
Intent: {\bf in}.\\
Specified as: a rank one or two array or an object of type \vdata\
containing numbers of type
specified in Table~\ref{tab:f90axpby}.  The rank of $x$ must be the same of $y$.
\item[beta] the scalar $\beta$.\\
Scope: {\bf global} \\
Type: {\bf required} \\
Intent: {\bf in}.\\
Specified as: a number of the data type indicated in Table~\ref{tab:f90axpby}.
\item[y] the local portion of the global dense matrix
$y$. \\
Scope: {\bf local} \\
Type: {\bf required} \\
Intent: {\bf inout}.\\
Specified as:  a rank one or two array or an object of type \vdata\  containing numbers of the type
indicated in Table~\ref{tab:f90axpby}.  The rank of $y$ must be the same of $x$.
\item[desc\_a] contains data structures for communications.\\
Scope: {\bf local} \\
Type: {\bf required}\\
Intent: {\bf in}.\\
Specified as: an object of type \descdata.
%% \item[n] number of columns in dense submatrices $x$ and $y$.\\
%% Scope: {\bf global} \\
%% Type: {\bf optional}; can only be present if $x$ and $y$ are of rank 2.\\
%% Default: \fortinline|min(size(x,2),size(y,2))|.\\
%% Specified as: an integer variable $n\ge 0$.
%% \item[jx]  the column index of the global dense matrix $x$,
%% identifying the first column of the submatrix $x$.\\
%% Scope: {\bf global} \\
%% Type: {\bf optional}; can only be present if $x$ and $y$ are of rank 2.\\
%% Default: $jx = 1$.\\
%% Specified as: an integer variable $jx\ge 1$.
%% \item[jy]  the column index of the global dense matrix $y$,
%% identifying the first column of the submatrix $y$.\\
%% Scope: {\bf global} \\
%% Type: {\bf optional}; can only be present if $x$ and $y$ are of rank 2.\\
%% Default: $jy = 1$.\\
%% Specified as: an integer variable $jy\ge 1$.

\end{description}

\begin{description}
\item[\bf On Return]
\item[y] the local portion of result submatrix $y$.\\
Scope: {\bf local} \\
Type: {\bf required} \\
Intent: {\bf inout}.\\
Specified as: a rank one or two array or an object of type \vdata\ containing numbers of the type
indicated in Table~\ref{tab:f90axpby}.
\item[info] Error code.\\
Scope: {\bf local} \\
Type: {\bf required} \\
Intent: {\bf out}.\\
An integer value; 0 means no error has been detected.
\end{description}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%       F90DOT PRODUCT
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\clearpage\subsection{psb\_gedot --- Dot Product}

This function computes dot product between two vectors $x$ and
$y$.\\
If $x$ and $y$ are real vectors
it computes dot-product as:
\[dot \leftarrow x^T y\]
Else if $x$ and $y$ are complex vectors then it computes dot-product as:
\[dot \leftarrow x^H y\]
%% where:
%% \begin{description}
%% \item[$x$] represents the global vector $x_{:,jx}$
%% \item[$y$] represents the global vector $y_{:,jy}$
%% \end{description}

\fortinline|psb_gedot(x, y, desc_a, info [,global])|
%% \syntax*{psb\_gedot}{x, y, desc\_a, info, jx, jy}
\begin{table}[h]
\begin{center}
\begin{tabular}{ll}
\hline
$dot$, $x$, $y$ & {\bf Function}\\
\hline
Short Precision Real & psb\_gedot \\
Long Precision Real & psb\_gedot \\
Short Precision Complex & psb\_gedot \\
Long Precision Complex & psb\_gedot \\
\hline
\end{tabular}
\end{center}
\caption{Data types\label{tab:f90dot}}
\end{table}

\begin{description}
\item[Type:] Synchronous.
\item[\bf On Entry]
\item[x] the local portion of global dense matrix
$x$.\\
%%  This function computes the location of the first element of
%% local subarray used, based on $jx$ and the field $matrix\_data$ of $desc\_a$ . \\
Scope: {\bf local} \\
Type: {\bf required} \\
Intent: {\bf in}.\\
Specified as:  a rank one or two array or an object of type \vdata\
containing numbers of type specified in
Table~\ref{tab:f90dot}. The rank of $x$ must be the same of $y$.
\item[y] the local portion of global dense matrix
$y$. \\
%% This function computes the location of the first element of
%% local subarray used, based on $iy, jy$ and the field $matrix\_data$ of $desc\_a$ . \\
Scope: {\bf local} \\
Type: {\bf required} \\
Intent: {\bf in}.\\
Specified as:  a rank one or two array or an object of type \vdata\
containing numbers of type specified in
Table~\ref{tab:f90dot}. The rank of $y$ must be the same of $x$.
\item[desc\_a] contains data structures for communications.\\
Scope: {\bf local} \\
Type: {\bf required}\\
Intent: {\bf in}.\\
Specified as: an object of type \descdata.
\item[global]  Specifies whether the computation should include the
  global reduction across all processes.\\
Scope: {\bf global} \\
Type: {\bf optional}.\\
Intent: {\bf in}.\\
Specified as: a logical scalar.
Default: \fortinline|global=.true.|\\
%% \item[jx]  the column index of global dense matrix $x$,
%% identifying the column of vector $x$.\\
%% Scope: {\bf global} \\
%% Type: {\bf optional}; can only be present if $x$ and $y$ are of rank 2.\\
%% Default: $jx = 1$.\\

%% \item[jy]  the column index of global dense matrix $y$,
%% identifying the column of vector $y$.\\
%% Scope: {\bf global} \\
%% Type: {\bf optional}; can only be present if $x$ and $y$ are of rank 2.\\
%% Default: $jy = 1$.\\
%% Specified as: an integer variable $jy\ge 1$.
\item[\bf On Return]
\item[Function value] is the dot product of vectors $x$ and $y$.\\
Scope: {\bf global}  unless the optional variable
\fortinline|global=.false.| has been specified\\
Specified as: a number of the data type indicated in Table~\ref{tab:f90dot}.
\item[info] Error code.\\
Scope: {\bf local} \\
Type: {\bf required} \\
Intent: {\bf out}.\\
An integer value; 0 means no error has been detected.
\end{description}

{\par\noindent\large\bfseries Notes}
\begin{enumerate}
\item The computation of a global result requires a global
  communication, which entails a significant overhead. It may be
  necessary and/or advisable to compute multiple dot products at the same
  time; in this case, it is possible to improve the runtime efficiency
  by using the following scheme:
  \ifpdf
  \begin{minted}{fortran}
  	vres(1) = psb_gedot(x1,y1,desc_a,info,global=.false.)
  	vres(2) = psb_gedot(x2,y2,desc_a,info,global=.false.)
  	vres(3) = psb_gedot(x3,y3,desc_a,info,global=.false.)
  	call psb_sum(ctxt,vres(1:3))
  \end{minted}
  \else
  \begin{lstlisting}
    vres(1) = psb_gedot(x1,y1,desc_a,info,global=.false.)
    vres(2) = psb_gedot(x2,y2,desc_a,info,global=.false.)
    vres(3) = psb_gedot(x3,y3,desc_a,info,global=.false.)
    call psb_sum(ctxt,vres(1:3))
  \end{lstlisting}
  \fi
  In this way the global communication, which for small sizes is a
  latency-bound operation, is invoked only once.
\end{enumerate}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%       F90DOT PRODUCT
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\clearpage\subsection{psb\_gedots --- Generalized Dot Product}

This subroutine computes a series of  dot products among the columns of
two dense matrices  $x$ and $y$:
\[ res(i) \leftarrow x(:,i)^T y(:,i)\]
If the matrices are complex, then the
usual convention applies, i.e. the conjugate transpose of $x$ is
used. If $x$ and $y$ are of rank one, then $res$ is a scalar, else it
is a rank one array.

\fortinline| call psb_gedots(res, x, y, desc_a, info)|

\begin{table}[h]
\begin{center}
\begin{tabular}{ll}
\hline
$res$, $x$, $y$ & {\bf Subroutine}\\
\hline
Short Precision Real & psb\_gedots \\
Long Precision Real & psb\_gedots \\
Short Precision Complex & psb\_gedots \\
Long Precision Complex & psb\_gedots \\
\hline
\end{tabular}
\end{center}
\caption{Data types\label{tab:f90mdot}}
\end{table}

\begin{description}
\item[Type:] Synchronous.
\item[\bf On Entry]
\item[x] the local portion of global dense matrix
$x$. \\
Scope: {\bf local} \\
Type: {\bf required} \\
Intent: {\bf in}.\\
Specified as:  a rank one or two array or an object of type \vdata\
containing numbers of type specified in
Table~\ref{tab:f90mdot}. The rank of $x$ must be the same of $y$.
\item[y] the local portion of global dense matrix
$y$. \\
Scope: {\bf local} \\
Type: {\bf required} \\
Intent: {\bf in}.\\
Specified as:  a rank one or two array or an object of type \vdata\
containing numbers of type specified in
Table~\ref{tab:f90mdot}. The rank of $y$ must be the same of $x$.
\item[desc\_a] contains data structures for communications.\\
Scope: {\bf local} \\
Type: {\bf required}\\
Intent: {\bf in}.\\
Specified as: an object of type \descdata.
\item[\bf On Return]
\item[res] is the dot product of vectors $x$ and $y$.\\
Scope: {\bf global} \\
Intent: {\bf out}.\\
Specified as: a number or a rank-one array  of the data type indicated
in Table~\ref{tab:f90dot}.
\item[info] Error code.\\
Scope: {\bf local} \\
Type: {\bf required} \\
Intent: {\bf out}.\\
An integer value; 0 means no error has been detected.
\end{description}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%       VECTOR INFINITY-NORM
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\clearpage\subsection{psb\_normi --- Infinity-Norm of Vector}

This function computes
 the infinity-norm of a vector $x$.\\
If $x$ is a real  vector
it computes infinity norm as:
\[ amax \leftarrow \max_i |x_i|\]
else if $x$ is a complex vector then it computes the infinity-norm  as:
\[ amax \leftarrow \max_i {(|re(x_i)| + |im(x_i)|)}\]
%% where:
%% \begin{description}
%% \item[$x$] represents the global vector $x_{:,jx}$
%% \end{description}

\fortinline|psb_geamax(x, desc_a, info [,global])|\\
\fortinline|psb_normi(x, desc_a, info [,global])|
%% \syntax*{psb\_geamax}{x, desc\_a, info, jx}

\begin{table}[h]
\begin{center}
\begin{tabular}{lll}
\hline
$amax$ & $x$ & {\bf Function}\\
\hline
Short Precision Real& Short Precision Real & psb\_geamax \\
Long Precision Real&Long Precision Real & psb\_geamax \\
Short Precision Real&Short Precision Complex & psb\_geamax \\
Long Precision Real&Long Precision Complex & psb\_geamax \\
\hline
\end{tabular}
\end{center}
\caption{Data types\label{tab:f90amax}}
\end{table}

\begin{description}
\item[Type:] Synchronous.
\item[\bf On Entry]
\item[x] the local portion of global dense matrix
$x$. %% This function computes the location of the first element of
%% local subarray used, based on $jx$ and the field $matrix\_data$ of $desc\_a$ .
\\
Scope: {\bf local} \\
Type: {\bf required} \\
Intent: {\bf in}.\\
Specified as:  a rank one or two array or an object of type \vdata\
containing numbers of type specified in
Table~\ref{tab:f90amax}.
\item[desc\_a] contains data structures for communications.\\
Scope: {\bf local} \\
Type: {\bf required}\\
Intent: {\bf in}.\\
Specified as: an object of type \descdata.
\item[global]  Specifies whether the computation should include the
  global reduction across all processes.\\
Scope: {\bf global} \\
Type: {\bf optional}.\\
Intent: {\bf in}.\\
Specified as: a logical scalar.
Default: \fortinline|global=.true.|\\%% \item[jx]  the column index of global dense matrix $x$,
%% identifying the column of vector $x$.\\
%% Scope: {\bf global} \\
%% Type: {\bf optional}; can only be present if $x$ is of rank 2.\\
%% Default: $jx = 1$\\
%% Specified as: an integer variable $jx\ge 1$.

\item[\bf On Return]
\item[Function value] is the infinity norm of vector $x$.\\
Scope: {\bf global} unless the optional variable
\fortinline|global=.false.| has been specified\\
Specified as: a long precision real number.
\item[info] Error code.\\
Scope: {\bf local} \\
Type: {\bf required} \\
Intent: {\bf out}.\\
An integer value; 0 means no error has been detected.
\end{description}

{\par\noindent\large\bfseries Notes}
\begin{enumerate}
\item The computation of a global result requires a global
  communication, which entails a significant overhead. It may be
  necessary and/or advisable to compute multiple norms at the same
  time; in this case, it is possible to improve the runtime efficiency
  by using the following scheme:
  \ifpdf
  \begin{minted}{fortran}
  	vres(1) = psb_geamax(x1,desc_a,info,global=.false.)
  	vres(2) = psb_geamax(x2,desc_a,info,global=.false.)
  	vres(3) = psb_geamax(x3,desc_a,info,global=.false.)
  	call psb_amx(ctxt,vres(1:3))
  \end{minted}
  \else
  \begin{lstlisting}
    vres(1) = psb_geamax(x1,desc_a,info,global=.false.)
    vres(2) = psb_geamax(x2,desc_a,info,global=.false.)
    vres(3) = psb_geamax(x3,desc_a,info,global=.false.)
    call psb_amx(ctxt,vres(1:3))
  \end{lstlisting}
  \fi
  In this way the global communication, which for small sizes is a
  latency-bound operation, is invoked only once.
\end{enumerate}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%       Infinity norm
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\clearpage\subsection{psb\_geamaxs --- Generalized Infinity Norm}

This subroutine computes a series of  infinity norms on the columns of
a  dense matrix  $x$:
\[ res(i) \leftarrow \max_k |x(k,i)| \]

\fortinline| call psb_geamaxs(res, x, desc_a, info)|

\begin{table}[h]
\begin{center}
\begin{tabular}{lll}
\hline
$res$&  $x$& {\bf Subroutine}\\
\hline
Short Precision Real    &Short Precision Real    & psb\_geamaxs\\
Long Precision Real    &Long Precision Real    & psb\_geamaxs\\
Short Precision Real &Short Precision Complex & psb\_geamaxs\\
Long Precision Real &Long Precision Complex & psb\_geamaxs\\
\hline
\end{tabular}
\end{center}
\caption{Data types\label{tab:f90mamax}}
\end{table}

\begin{description}
\item[Type:] Synchronous.
\item[\bf On Entry]
\item[x] the local portion of global dense matrix
$x$. \\
Scope: {\bf local} \\
Type: {\bf required} \\
Intent: {\bf in}.\\
Specified as: a rank one or two array or an object of type \vdata\
containing numbers of type specified in
Table~\ref{tab:f90mamax}.
\item[desc\_a] contains data structures for communications.\\
Scope: {\bf local} \\
Type: {\bf required}\\
Intent: {\bf in}.\\
Specified as: an object of type \descdata.
\item[\bf On Return]
\item[res] is the infinity norm of the columns of $x$.\\
Scope: {\bf global} \\
Intent: {\bf out}.\\
Specified as: a number or a rank-one array  of long precision real numbers.
\item[info] Error code.\\
Scope: {\bf local} \\
Type: {\bf required} \\
Intent: {\bf out}.\\
An integer value; 0 means no error has been detected.
\end{description}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%       1-NORM OF A VECTOR
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\clearpage\subsection{psb\_norm1 --- 1-Norm of Vector}

This function computes the 1-norm of a vector $x$.\\
If $x$ is a real vector
it computes 1-norm as:
\[ asum \leftarrow  \|x_i\|\]
else if $x$ is a complex vector then it computes 1-norm  as:
\[ asum \leftarrow \|re(x)\|_1 + \|im(x)\|_1\]

\fortinline|psb_geasum(x, desc_a, info [,global])|
\fortinline|psb_norm1(x, desc_a, info [,global])|

\begin{table}[h]
\begin{center}
\begin{tabular}{lll}
\hline
$asum$ & $x$ & {\bf Function}\\
\hline
Short Precision Real&Short Precision Real & psb\_geasum \\
Long Precision Real&Long Precision Real & psb\_geasum \\
Short Precision Real&Short Precision Complex & psb\_geasum \\
Long Precision Real&Long Precision Complex & psb\_geasum \\
\hline
\end{tabular}
\end{center}
\caption{Data types\label{tab:f90asum}}
\end{table}

\begin{description}
\item[Type:] Synchronous.
\item[\bf On Entry]
\item[x] the local portion of global dense matrix
$x$. %% This function computes the location of the first element of
%% local subarray used, based on the field $matrix\_data$ of $desc\_a$ .
\\
Scope: {\bf local} \\
Type: {\bf required} \\
Intent: {\bf in}.\\
Specified as: a rank one or two array or an object of type \vdata\
containing numbers of type specified in
Table~\ref{tab:f90asum}.
\item[desc\_a] contains data structures for communications.\\
Scope: {\bf local} \\
Type: {\bf required}\\
Intent: {\bf in}.\\
Specified as: an object of type \descdata.
\item[global]  Specifies whether the computation should include the
  global reduction across all processes.\\
Scope: {\bf global} \\
Type: {\bf optional}.\\
Intent: {\bf in}.\\
Specified as: a logical scalar.
Default: \fortinline|global=.true.|\\

\item[\bf On Return]
\item[Function value] is the 1-norm of vector $x$.\\
Scope: {\bf global} unless the optional variable
\fortinline|global=.false.| has been specified\\
Specified as: a long precision real  number.
\item[info] Error code.\\
Scope: {\bf local} \\
Type: {\bf required} \\
Intent: {\bf out}.\\
An integer value; 0 means no error has been detected.
\end{description}

{\par\noindent\large\bfseries Notes}
\begin{enumerate}
\item The computation of a global result requires a global
  communication, which entails a significant overhead. It may be
  necessary and/or advisable to compute multiple norms at the same
  time; in this case, it is possible to improve the runtime efficiency
  by using the following scheme:
  \ifpdf
  \begin{minted}{fortran}
    vres(1) = psb_geasum(x1,desc_a,info,global=.false.)
  	vres(2) = psb_geasum(x2,desc_a,info,global=.false.)
  	vres(3) = psb_geasum(x3,desc_a,info,global=.false.)
  	call psb_sum(ctxt,vres(1:3))
  \end{minted}
  \else
  \begin{lstlisting}
    vres(1) = psb_geasum(x1,desc_a,info,global=.false.)
    vres(2) = psb_geasum(x2,desc_a,info,global=.false.)
    vres(3) = psb_geasum(x3,desc_a,info,global=.false.)
    call psb_sum(ctxt,vres(1:3))
  \end{lstlisting}
  \fi
  In this way the global communication, which for small sizes is a
  latency-bound operation, is invoked only once.
\end{enumerate}

\clearpage\subsection{psb\_geasums --- Generalized 1-Norm of Vector}

This subroutine computes a series of  1-norms on the columns of
a  dense matrix  $x$:
\[ res(i) \leftarrow \max_k |x(k,i)| \]
This function computes the 1-norm of a vector $x$.\\
If $x$ is a real vector
it computes 1-norm as:
\[ res(i) \leftarrow  \|x_i\|\]
else if $x$ is a complex vector then it computes 1-norm  as:
\[ res(i) \leftarrow \|re(x)\|_1 + \|im(x)\|_1\]

\fortinline| call psb_geasums(res, x, desc_a, info)|

\begin{table}[h]
\begin{center}
\begin{tabular}{lll}
\hline
$res$ & $x$ & {\bf Subroutine}\\
\hline
Short Precision Real&Short Precision Real & psb\_geasums \\
Long Precision Real&Long Precision Real & psb\_geasums \\
Short Precision Real&Short Precision Complex & psb\_geasums \\
Long Precision Real&Long Precision Complex & psb\_geasums \\
\hline
\end{tabular}
\end{center}
\caption{Data types\label{tab:f90asums}}
\end{table}

\begin{description}
\item[Type:] Synchronous.
\item[\bf On Entry]
\item[x] the local portion of global dense matrix
$x$. %% This function computes the location of the first element of
%% local subarray used, based on the field $matrix\_data$ of $desc\_a$ .
\\
Scope: {\bf local} \\
Type: {\bf required} \\
Intent: {\bf in}.\\
Specified as: a rank one or two array or an object of type \vdata\
containing numbers of type specified in
Table~\ref{tab:f90asums}.
\item[desc\_a] contains data structures for communications.\\
Scope: {\bf local} \\
Type: {\bf required}\\
Intent: {\bf in}.\\
Specified as: an object of type \descdata.

\item[\bf On Return]
\item[res] contains the 1-norm of (the columns of) $x$.\\
Scope: {\bf global} \\
Intent: {\bf out}.\\
Short as: a long precision real  number.
Specified as: a long precision real  number.
\item[info] Error code.\\
Scope: {\bf local} \\
Type: {\bf required} \\
Intent: {\bf out}.\\
An integer value; 0 means no error has been detected.
\end{description}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%       2-NORM OF A VECTOR
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\clearpage\subsection{psb\_norm2 --- 2-Norm of Vector}

This function computes the 2-norm of a vector $x$.\\
If $x$ is a  real  vector
it computes 2-norm as:
\[ nrm2 \leftarrow \sqrt{x^T x}\]
else if $x$ is a complex vector then it computes 2-norm  as:
\[ nrm2 \leftarrow \sqrt{x^H x}\]
%% where:
%% \begin{description}
%% \item[$x$] represents the global vector $x_{:,jx}$
%% \end{description}

\begin{table}[h]
\begin{center}
\begin{tabular}{lll}
\hline
$nrm2$ & $x$ & {\bf Function}\\
\hline
Short Precision Real&Short Precision Real & psb\_genrm2 \\
Long Precision Real&Long Precision Real & psb\_genrm2 \\
Short Precision Real&Short Precision Complex & psb\_genrm2 \\
Long Precision Real&Long Precision Complex & psb\_genrm2 \\
\hline
\end{tabular}
\end{center}
\caption{Data types\label{tab:f90nrm2}}
\end{table}

\fortinline|psb_genrm2(x, desc_a, info [,global])|\\
\fortinline|psb_norm2(x, desc_a, info [,global])|\\
%% \syntax*{psb\_genrm2}{x, desc\_a, info, jx}

\begin{description}
\item[Type:] Synchronous.
\item[\bf On Entry]
\item[x] the local portion of global dense matrix
$x$.%%  This function computes the location of the first element of
%% local subarray used, based on $jx$ and the field $matrix\_data$ of $desc\_a$ .
\\
Scope: {\bf local} \\
Type: {\bf required} \\
Intent: {\bf in}.\\
Specified as:  a rank one or two array or an object of type \vdata\
containing numbers of type specified in
Table~\ref{tab:f90nrm2}.
\item[desc\_a] contains data structures for communications.\\
Scope: {\bf local} \\
Type: {\bf required}\\
Intent: {\bf in}.\\
Specified as: an object of type \descdata.
\item[global]  Specifies whether the computation should include the
  global reduction across all processes.\\
Scope: {\bf global} \\
Type: {\bf optional}.\\
Intent: {\bf in}.\\
Specified as: a logical scalar.
Default: \fortinline|global=.true.|\\%% \item[jx]  the column index of global dense matrix $x$,
%% identifying the column of vector $x$.\\
%% Scope: {\bf global} \\
%% Type: {\bf optional}; can only be present if $x$ is of rank 2.\\
%% Default: $jx = 1$\\
%% Specified as: an integer variable $jx\ge 1$.

\item[\bf On Return]
\item[Function Value] is the 2-norm of vector $x$.\\
Scope: {\bf global} unless the optional variable
\fortinline|global=.false.| has been specified\\
Type: {\bf required} \\
Specified as: a long precision real number.
\item[info] Error code.\\
Scope: {\bf local} \\
Type: {\bf required} \\
Intent: {\bf out}.\\
An integer value; 0 means no error has been detected.
\end{description}

{\par\noindent\large\bfseries Notes}
\begin{enumerate}
\item The computation of a global result requires a global
  communication, which entails a significant overhead. It may be
  necessary and/or advisable to compute multiple norms at the same
  time; in this case, it is possible to improve the runtime efficiency
  by using the following scheme:
  \begin{lstlisting}
    vres(1) = psb_genrm2(x1,desc_a,info,global=.false.)
    vres(2) = psb_genrm2(x2,desc_a,info,global=.false.)
    vres(3) = psb_genrm2(x3,desc_a,info,global=.false.)
    call psb_nrm2(ctxt,vres(1:3))
  \end{lstlisting}
  In this way the global communication, which for small sizes is a
  latency-bound operation, is invoked only once.
\end{enumerate}

\clearpage\subsection{psb\_genrm2s --- Generalized 2-Norm of Vector}

This subroutine computes a series of  2-norms on the columns of
a  dense matrix  $x$:
\[ res(i) \leftarrow \|x(:,i)\|_2 \]

\fortinline| call psb_genrm2s(res, x, desc_a, info)|

\begin{table}[h]
\begin{center}
\begin{tabular}{lll}
\hline
$res$ & $x$ & {\bf Subroutine}\\
\hline
Short Precision Real&Short Precision Real & psb\_genrm2s \\
Long Precision Real&Long Precision Real & psb\_genrm2s \\
Short Precision Real&Short Precision Complex & psb\_genrm2s \\
Long Precision Real&Long Precision Complex & psb\_genrm2s \\
\hline
\end{tabular}
\end{center}
\caption{Data types\label{tab:f90nrm2s}}
\end{table}

\begin{description}
\item[Type:] Synchronous.
\item[\bf On Entry]
\item[x] the local portion of global dense matrix
$x$. %% This function computes the location of the first element of
%% local subarray used, based on the field $matrix\_data$ of $desc\_a$ .
\\
Scope: {\bf local} \\
Type: {\bf required} \\
Intent: {\bf in}.\\
Specified as: a rank one or two array or an object of type \vdata\
containing numbers of type specified in
Table~\ref{tab:f90nrm2s}.
\item[desc\_a] contains data structures for communications.\\
Scope: {\bf local} \\
Type: {\bf required}\\
Intent: {\bf in}.\\
Specified as: an object of type \descdata.

\item[\bf On Return]
\item[res] contains the 1-norm of (the columns of) $x$.\\
Scope: {\bf global} \\
Intent: {\bf out}.\\
Specified as: a long precision real  number.
\item[info] Error code.\\
Scope: {\bf local} \\
Type: {\bf required} \\
Intent: {\bf out}.\\
An integer value; 0 means no error has been detected.
\end{description}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%       1-NORM OF A MATRIX
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\clearpage\subsection{psb\_norm1 --- 1-Norm of Sparse Matrix}

This function computes the 1-norm of a matrix $A$:\\

\[ nrm1 \leftarrow \|A\|_1 \]
where:
\begin{description}
\item[$A$] represents the global matrix $A$
\end{description}

\begin{table}[h]
\begin{center}
\begin{tabular}{ll}
\hline
$A$ & {\bf Function}\\
\hline
Short Precision Real & psb\_spnrm1 \\
Long Precision Real & psb\_spnrm1 \\
Short Precision Complex & psb\_spnrm1 \\
Long Precision Complex & psb\_spnrm1 \\
\hline
\end{tabular}
\end{center}
\caption{Data types\label{tab:f90nrm1}}
\end{table}

\begin{verbatim}
psb_spnrm1(A, desc_a, info)
psb_norm1(A, desc_a, info)
\end{verbatim}

\begin{description}
\item[Type:] Synchronous.
\item[\bf On Entry]
\item[a] the local  portion of the global sparse matrix
$A$. \\
Scope: {\bf local} \\
Type: {\bf required}\\
Intent: {\bf in}.\\
Specified as: an object of type \spdata.
\item[desc\_a] contains data structures for communications.\\
Scope: {\bf local} \\
Type: {\bf required}\\
Intent: {\bf in}.\\
Specified as: an object of type \descdata.
\item[\bf On Return]
\item[Function value] is the 1-norm of sparse submatrix $A$.\\
Scope: {\bf global} \\
Specified as: a long precision real number.
\item[info] Error code.\\
Scope: {\bf local} \\
Type: {\bf required} \\
Intent: {\bf out}.\\
An integer value; 0 means no error has been detected.
\end{description}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%       INFINITY-NORM OF A MATRIX
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\clearpage\subsection{psb\_normi --- Infinity Norm of Sparse Matrix}

This function computes the infinity-norm of a matrix $A$:\\

\[ nrmi \leftarrow \|A\|_\infty \]
where:
\begin{description}
\item[$A$] represents the global matrix $A$
\end{description}

\begin{table}[h]
\begin{center}
\begin{tabular}{ll}
\hline
$A$ & {\bf Function}\\
\hline
Short Precision Real & psb\_spnrmi \\
Long Precision Real & psb\_spnrmi \\
Short Precision Complex & psb\_spnrmi \\
Long Precision Complex & psb\_spnrmi \\
\hline
\end{tabular}
\end{center}
\caption{Data types\label{tab:f90nrmi}}
\end{table}

\begin{verbatim}
psb_spnrmi(A, desc_a, info)
psb_normi(A, desc_a, info)
\end{verbatim}

\begin{description}
\item[Type:] Synchronous.
\item[\bf On Entry]
\item[a] the local  portion of the global sparse matrix
$A$. \\
Scope: {\bf local} \\
Type: {\bf required}\\
Intent: {\bf in}.\\
Specified as: an object of type \spdata.
\item[desc\_a] contains data structures for communications.\\
Scope: {\bf local} \\
Type: {\bf required}\\
Intent: {\bf in}.\\
Specified as: an object of type \descdata.
\item[\bf On Return]
\item[Function value] is the infinity-norm of sparse submatrix $A$.\\
Scope: {\bf global} \\
Specified as: a long precision real number.
\item[info] Error code.\\
Scope: {\bf local} \\
Type: {\bf required} \\
Intent: {\bf out}.\\
An integer value; 0 means no error has been detected.
\end{description}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%       SPARSE MATRIX by DENSE MATRIX PRODUCT
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\clearpage\subsection{psb\_spmm --- Sparse Matrix by Dense Matrix
  Product}

This subroutine computes the Sparse Matrix by Dense Matrix Product:

\begin{equation}
y \leftarrow \alpha  A  x + \beta y
\label{eq:f90spmm_no_tra}
\end{equation}
\begin{equation}
y \leftarrow \alpha  A^T x + \beta y
\label{eq:f90spmm_tra}
\end{equation}
\begin{equation}
y \leftarrow \alpha  A^H  x + \beta y
\label{eq:f90spmm_con}
\end{equation}

where:
\begin{description}
\item[$x$] is the global dense matrix $x_{:, :}$
\item[$y$] is the global dense matrix $y_{:, :}$
\item[$A$] is the global sparse matrix $A$
\end{description}

\begin{table}[h]
\begin{center}
\begin{tabular}{ll}
\hline
$A$, $x$, $y$, $\alpha$, $\beta$ & {\bf Subroutine}\\
\hline
Short Precision Real & psb\_spmm \\
Long Precision Real & psb\_spmm \\
Short Precision Complex & psb\_spmm \\
Long Precision Complex & psb\_spmm \\
\hline
\end{tabular}
\end{center}
\caption{Data types\label{tab:f90spmm}}
\end{table}

\fortinline| call psb_spmm(alpha, a, x, beta, y, desc_a, info)|\\
\fortinline| call psb_spmm(alpha, a, x, beta, y,desc_a, info, trans, work)|

\begin{description}
\item[Type:] Synchronous.
\item[\bf On Entry]
\item[alpha] the scalar $\alpha$.\\
Scope: {\bf global} \\
Type: {\bf required}\\
Intent: {\bf in}.\\
Specified as: a number of the data type indicated in
Table~\ref{tab:f90spmm}.
\item[a] the local portion of the sparse matrix
$A$. \\
Scope: {\bf local} \\
Type: {\bf required}\\
Intent: {\bf in}.\\
Specified as: an object of type \spdata.
\item[x] the local portion of global dense matrix
$x$. %% This subroutine computes the location of the first element of
%% local subarray used, based on $jx$ and the field $matrix\_data$ of $desc\_a$ .
\\
Scope: {\bf local} \\
Type: {\bf required} \\
Intent: {\bf in}.\\
Specified as:  a rank one or two array or an object of type \vdata\
containing numbers of type specified in
Table~\ref{tab:f90spmm}.  The rank of $x$ must be the same of $y$.
\item[beta] the scalar $\beta$.\\
Scope: {\bf global} \\
Type: {\bf required} \\
Intent: {\bf in}.\\
Specified as: a number of the data type indicated in Table~\ref{tab:f90spmm}.
\item[y] the local portion of global dense matrix
$y$. %% This subroutine computes the location of the first element of
%% local subarray used, based on $jy$ and the field $matrix\_data$ of $desc\_a$ .
\\
Scope: {\bf local} \\
Type: {\bf required} \\
Intent: {\bf inout}.\\
Specified as:  a rank one or two array or an object of type \vdata\
containing numbers of type specified in
Table~\ref{tab:f90spmm}. The rank of $y$ must be the same of $x$.
\item[desc\_a] contains data structures for communications.\\
Scope: {\bf local} \\
Type: {\bf required}\\
Intent: {\bf in}.\\
Specified as: an object of type \descdata.
\item[trans] indicates what kind of operation to perform.
\begin{description}
\item[trans = N] the operation is specified by equation \ref{eq:f90spmm_no_tra}
\item[trans = T] the operation is specified by equation
\ref{eq:f90spmm_tra}
\item[trans = C] the operation is specified by equation
\ref{eq:f90spmm_con}
\end{description}
Scope: {\bf global} \\
Type: {\bf optional}\\
Intent: {\bf in}.\\
Default: $trans = N$\\
Specified as: a character variable.
%% \item[k] number of columns in dense submatrices $x$ and $y$. \\
%% Scope: {\bf global} \\
%% Type: {\bf optional}\\
%% Default: \fortinline|min(size(x,2)-jx+1,size(y,2)-jy+1)|\\
%% Specified as: an integer variable $ k \ge 1$.
%% \item[jx]  the column index of global dense matrix $x$,
%% identifying the column of vector $x$.\\
%% Scope: {\bf global} \\
%% Type: {\bf optional}; can only be present if $x$ is of rank 2.\\
%% Default: $iy = 1$\\
%% Specified as: an integer variable $jx\ge 1$.
%% \item[jy]  the column index of global dense matrix $y$,
%% identifying the column of vector $y$.\\
%% Scope: {\bf global} \\
%% Type: {\bf optional}; can only be present if $y$ is of rank 2.\\
%% Default: $jy = 1$\\
%% Specified as: an integer variable $jy\ge 1$.

\item[work]  work array.\\
Scope: {\bf local} \\
Type: {\bf optional}\\
Intent: {\bf inout}.\\
Specified as: a rank one array of the same type of $x$ and $y$ with
the TARGET attribute.

\item[\bf On Return]
\item[y] the local portion of result matrix $y$.\\
Scope: {\bf local} \\
Type: {\bf required} \\
Intent: {\bf inout}.\\
Specified as: an array of rank one or two
containing numbers of type specified in
Table~\ref{tab:f90spmm}.
\item[info] Error code.\\
Scope: {\bf local} \\
Type: {\bf required} \\
Intent: {\bf out}.\\
An integer value; 0 means no error has been detected.
\end{description}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%       TRIANGULAR SYSTEM SOLVE
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\clearpage\subsection{psb\_spsm --- Triangular System Solve}

This subroutine computes the Triangular System Solve:

\begin{eqnarray*}
y &\leftarrow& \alpha  T^{-1}  x + \beta y\\
y &\leftarrow& \alpha D  T^{-1}  x + \beta y\\
y &\leftarrow& \alpha  T^{-1}  D x + \beta y\\
y &\leftarrow& \alpha  T^{-T}  x + \beta y\\
y &\leftarrow& \alpha D  T^{-T}  x + \beta y\\
y &\leftarrow& \alpha  T^{-T}  D x + \beta y\\
y &\leftarrow& \alpha  T^{-H}  x + \beta y\\
y &\leftarrow& \alpha D  T^{-H}  x + \beta y\\
y &\leftarrow& \alpha  T^{-H}  D x + \beta y\\
\end{eqnarray*}

where:
\begin{description}
\item[$x$] is the global dense matrix $x_{:, :}$
\item[$y$] is the global dense matrix $y_{:, :}$
\item[$T$] is the global sparse block triangular submatrix $T$
\item[$D$] is the scaling diagonal matrix.
\end{description}

\fortinline| call psb_spsm(alpha, t, x, beta, y, desc_a, info)|\\
\fortinline| call psb_spsm(alpha, t, x, beta, y, desc_a, info, trans, unit, choice, diag, work)|\\

\begin{table}[h]
\begin{center}
\begin{tabular}{ll}
\hline
$T$, $x$, $y$, $D$, $\alpha$, $\beta$ & {\bf Subroutine}\\
\hline
Short Precision Real & psb\_spsm \\
Long Precision Real & psb\_spsm \\
Short Precision Complex & psb\_spsm \\
Long Precision Complex & psb\_spsm \\
\hline
\end{tabular}
\end{center}
\caption{Data types\label{tab:f90spsm}}
\end{table}

\begin{description}
\item[Type:] Synchronous.
\item[\bf On Entry]
\item[alpha] the scalar $\alpha$.\\
Scope: {\bf global} \\
Type: {\bf required}\\
Intent: {\bf in}.\\
Specified as: a number of the data type indicated in
Table~\ref{tab:f90spsm}.
\item[t] the global portion of the sparse matrix
$T$.  \\
Scope: {\bf local} \\
Type: {\bf required}\\
Intent: {\bf in}.\\
Specified as: an object type specified in
\S~\ref{sec:datastruct}.
\item[x] the local portion of global dense matrix
$x$. %% This subroutine computes the location of the first element of
%% local subarray used, based on $jx$ and the field $matrix\_data$ of $desc\_a$ .
\\
Scope: {\bf local} \\
Type: {\bf required} \\
Intent: {\bf in}.\\
Specified as:  a rank one or two array or an object of type \vdata\
containing numbers of type specified in
Table~\ref{tab:f90spsm}.  The rank of $x$ must be the same of $y$.
\item[beta] the scalar $\beta$.\\
Scope: {\bf global} \\
Type: {\bf required} \\
Intent: {\bf in}.\\
Specified as: a number of the data type indicated in Table~\ref{tab:f90spsm}.
\item[y] the local portion of global dense matrix
$y$. %% This subroutine computes the location of the first element of
%% local subarray used, based on $jy$ and the field $matrix\_data$ of $desc\_a$ .
\\
Scope: {\bf local} \\
Type: {\bf required} \\
Intent: {\bf inout}.\\
Specified as:  a rank one or two array or an object of type \vdata\
containing numbers of type specified in
Table~\ref{tab:f90spsm}. The rank of $y$ must be the same of $x$.
\item[desc\_a] contains data structures for communications.\\
Scope: {\bf local} \\
Type: {\bf required}\\
Intent: {\bf in}.\\
Specified as: an object of type \descdata.
\item[trans] specify with {\em unitd} the operation to perform.
\begin{description}
\item[trans = 'N'] the operation is with no transposed matrix
\item[trans = 'T'] the operation is with transposed matrix.
\item[trans = 'C'] the operation is with conjugate transposed matrix.
\end{description}
Scope: {\bf global} \\
Type: {\bf optional}\\
Intent: {\bf in}.\\
Default: $trans = N$\\
Specified as: a character variable.
\item[unitd] specify with {\em trans} the operation to perform.
\begin{description}
\item[unitd = 'U'] the operation is with no scaling
\item[unitd = 'L'] the operation is with left scaling
\item[unitd = 'R'] the operation is with right scaling.
\end{description}
Scope: {\bf global} \\
Type: {\bf optional}\\
Intent: {\bf in}.\\
Default: $unitd = U$\\
Specified as: a character variable.
\item[choice] specifies the update of overlap elements to be performed
  on exit:
\begin{description}
\item \fortinline|psb_none_|
\item \fortinline|psb_sum_|
\item \fortinline|psb_avg_|
\item \fortinline|psb_square_root_|
\end{description}
Scope: {\bf global} \\
Type: {\bf optional}\\
Intent: {\bf in}.\\
Default: \fortinline|psb_avg_|\\
Specified as: an integer variable.
\item[diag] the diagonal scaling matrix.\\
Scope: {\bf local} \\
Type: {\bf optional}\\
Intent: {\bf in}.\\
Default: $diag(1) = 1 (no scaling)$\\
Specified as: a rank one  array containing numbers of the type
indicated in Table~\ref{tab:f90spsm}.
\item[work] a work array. \\
Scope: {\bf local} \\
Type: {\bf optional}\\
Intent: {\bf inout}.\\
Specified as: a rank one array of the same type of $x$ with the
TARGET attribute.

\item[\bf On Return]
\item[y] the local portion of global dense matrix
$y$. %% This subroutine computes the location of the first element of
%% local subarray used, based on $jy$ and the field $matrix\_data$ of $desc\_a$ .
\\
Scope: {\bf local} \\
Type: {\bf required} \\
Intent: {\bf inout}.\\
Specified as: an array of rank one or two
containing numbers of type specified in
Table~\ref{tab:f90spsm}.
\item[info] Error code.\\
Scope: {\bf local} \\
Type: {\bf required} \\
Intent: {\bf out}.\\
An integer value; 0 means no error has been detected.
\end{description}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%       VECTOR VECTOR OPERATIONS
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\clearpage\subsection{psb\_gemlt --- Entrywise Product}

This function computes the entrywise product between two vectors $x$ and
$y$
\[dot \leftarrow x(i) y(i).\]

\fortinline|psb_gemlt(x, y, desc_a, info)|

%% \syntax*{psb\_gedot}{x, y, desc\_a, info, jx, jy}
\begin{table}[h]
	\begin{center}
		\begin{tabular}{ll}
			\hline
			$dot$, $x$, $y$ & {\bf Function}\\
			\hline
			Short Precision Real & psb\_gemlt \\
			Long Precision Real & psb\_gemlt \\
			Short Precision Complex & psb\_gemlt \\
			Long Precision Complex & psb\_gemlt \\
			\hline
		\end{tabular}
	\end{center}
	\caption{Data types\label{tab:f90mlt}}
\end{table}

\begin{description}
	\item[Type:] Synchronous.
	\item[\bf On Entry]
	\item[x] the local portion of global dense vector
	$x$.\\
	%%  This function computes the location of the first element of
	%% local subarray used, based on $jx$ and the field $matrix\_data$ of $desc\_a$ . \\
	Scope: {\bf local} \\
	Type: {\bf required} \\
	Intent: {\bf in}.\\
	Specified as:  an object of type \vdata\
	containing numbers of type specified in
	Table~\ref{tab:f90dot}.
	\item[y] the local portion of global dense vector
	$y$. \\
	%% This function computes the location of the first element of
	%% local subarray used, based on $iy, jy$ and the field $matrix\_data$ of $desc\_a$ . \\
	Scope: {\bf local} \\
	Type: {\bf required} \\
	Intent: {\bf in}.\\
	Specified as:  an object of type \vdata\
	containing numbers of type specified in
	Table~\ref{tab:f90dot}.
	\item[desc\_a] contains data structures for communications.\\
	Scope: {\bf local} \\
	Type: {\bf required}\\
	Intent: {\bf in}.\\
	Specified as: an object of type \descdata.
	\item[\bf On Return]
	\item[y] the local portion of result submatrix $y$.\\
	Scope: {\bf local} \\
	Type: {\bf required} \\
	Intent: {\bf inout}.\\
	Specified as: an object of type \vdata\ containing numbers of the type
	indicated in Table~\ref{tab:f90mlt}.
	\item[info] Error code.\\
	Scope: {\bf local} \\
	Type: {\bf required} \\
	Intent: {\bf out}.\\
	An integer value; 0 means no error has been detected.
\end{description}

\clearpage\subsection{psb\_gediv --- Entrywise Division}

This function computes the entrywise division between two vectors $x$ and
$y$
\[/ \leftarrow x(i)/y(i).\]

\fortinline|psb_gediv(x, y, desc_a, info, [flag)|

%% \syntax*{psb\_gedot}{x, y, desc\_a, info, jx, jy}
\begin{table}[h]
	\begin{center}
		\begin{tabular}{ll}
			\hline
			$/$, $x$, $y$ & {\bf Function}\\
			\hline
			Short Precision Real & psb\_gediv \\
			Long Precision Real & psb\_gediv \\
			Short Precision Complex & psb\_gediv \\
			Long Precision Complex & psb\_gediv \\
			\hline
		\end{tabular}
	\end{center}
	\caption{Data types\label{tab:f90div}}
\end{table}

\begin{description}
	\item[Type:] Synchronous.
	\item[\bf On Entry]
	\item[x] the local portion of global dense vector
	$x$.\\
	%%  This function computes the location of the first element of
	%% local subarray used, based on $jx$ and the field $matrix\_data$ of $desc\_a$ . \\
	Scope: {\bf local} \\
	Type: {\bf required} \\
	Intent: {\bf in}.\\
	Specified as:  an object of type \vdata\
	containing numbers of type specified in
	Table~\ref{tab:f90dot}.
	\item[y] the local portion of global dense vector
	$y$. \\
	%% This function computes the location of the first element of
	%% local subarray used, based on $iy, jy$ and the field $matrix\_data$ of $desc\_a$ . \\
	Scope: {\bf local} \\
	Type: {\bf required} \\
	Intent: {\bf in}.\\
	Specified as:  an object of type \vdata\
	containing numbers of type specified in
	Table~\ref{tab:f90dot}.
	\item[desc\_a] contains data structures for communications.\\
	Scope: {\bf local} \\
	Type: {\bf required}\\
	Intent: {\bf in}.\\
	Specified as: an object of type \descdata.
	\item[flag] check if any of the $y(i) = 0$, and in case returns error halting the computation.\\
	Scope: {\bf local} \\
	Type: {\bf optional}
	Intent: {\bf in}.\\
	Specified as: the logical value \fortinline|flag=.true.|
	\item[\bf On Return]
	\item[x] the local portion of result submatrix $x$.\\
	Scope: {\bf local} \\
	Type: {\bf required} \\
	Intent: {\bf inout}.\\
	Specified as: an object of type \vdata\ containing numbers of the type
	indicated in Table~\ref{tab:f90mlt}.
	\item[info] Error code.\\
	Scope: {\bf local} \\
	Type: {\bf required} \\
	Intent: {\bf out}.\\
	An integer value; 0 means no error has been detected.
\end{description}

\clearpage\subsection{psb\_geinv --- Entrywise Inversion}

This function computes the entrywise inverse of a vector $x$ and puts it into
$y$
\[/ \leftarrow 1/x(i).\]

\fortinline|psb_geinv(x, y, desc_a, info, [flag)|

%% \syntax*{psb\_gedot}{x, y, desc\_a, info, jx, jy}
\begin{table}[h]
	\begin{center}
		\begin{tabular}{ll}
			\hline
			$/$, $x$, $y$ & {\bf Function}\\
			\hline
			Short Precision Real & psb\_geinv \\
			Long Precision Real & psb\_geinv \\
			Short Precision Complex & psb\_geinv \\
			Long Precision Complex & psb\_geinv \\
			\hline
		\end{tabular}
	\end{center}
	\caption{Data types\label{tab:f90inv}}
\end{table}

\begin{description}
	\item[Type:] Synchronous.
	\item[\bf On Entry]
	\item[x] the local portion of global dense vector
	$x$.\\
	%%  This function computes the location of the first element of
	%% local subarray used, based on $jx$ and the field $matrix\_data$ of $desc\_a$ . \\
	Scope: {\bf local} \\
	Type: {\bf required} \\
	Intent: {\bf in}.\\
	Specified as:  an object of type \vdata\
	containing numbers of type specified in
	Table~\ref{tab:f90dot}.
	\item[desc\_a] contains data structures for communications.\\
	Scope: {\bf local} \\
	Type: {\bf required}\\
	Intent: {\bf in}.\\
	Specified as: an object of type \descdata.
	\item[flag] check if any of the $x(i) = 0$, and in case returns error halting the computation.\\
	Scope: {\bf local} \\
	Type: {\bf optional}
	Intent: {\bf in}.\\
	Specified as: the logical value \fortinline|flag=.true.|
	\item[\bf On Return]
	\item[y] the local portion of result submatrix $x$.\\
	Scope: {\bf local} \\
	Type: {\bf required} \\
	Intent: {\bf out}.\\
	Specified as: an object of type \vdata\ containing numbers of the type
	indicated in Table~\ref{tab:f90inv}.
	\item[info] Error code.\\
	Scope: {\bf local} \\
	Type: {\bf required} \\
	Intent: {\bf out}.\\
	An integer value; 0 means no error has been detected.
\end{description}

%%% Local Variables:
%%% mode: latex
%%% TeX-master: "userguide"
%%% End:


         %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
         % Information sheet for the Matlab lab - Maths 6111 %
         %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\documentclass[10pt]{article}
\input ma_no_html_header

\usepackage{color}
\usepackage{hyperref}
\hypersetup{breaklinks=true,colorlinks=true}
%\input ma_header
\setlength{\parindent}{0pt}
\pagestyle{myheadings}
% \markright{
% \protect {\protect \epsfxsize=0.2 true cm \protect \epsffile {dolph.line.eps}}
% \it Maths 3018/6111 - Numerical methods \hfill}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\begin{document}

\thispagestyle{empty}
\begin{center}
\textbf{\Large Maths 3018/6111 - Numerical Methods \\*[8mm]
Worksheet 4 - Solutions}\\*[.8cm]
\end{center}

\section*{Theory}

\begin{enumerate}
\item Convert the ODE
  \begin{equation*}
    y''' + x y'' + 3 y' + y = e^{-x}
  \end{equation*}
  into a first order system of ODEs.
  %
  \begin{center}
    \rule{0.9\textwidth}{.1pt}
  \end{center}
  %
  Step by step we introduce
  \begin{align*}
    u & = y' \\
    v & = u' \\
      & = y''.
  \end{align*}
  We can therefore write the ODE into a system of ODEs. The first
  order ODEs for $y$ and $u$ are given by the definitions above. The
  ODE for $v$ is given from the original equation, substituting in the
  definition of $u$ where appropriate, to get
  \begin{align*}
    \begin{pmatrix}
      y \\ u \\ v
    \end{pmatrix}' & =
    \begin{pmatrix}
      u \\ v \\ e^{-x} - x y'' - 3 y' - y
    \end{pmatrix} \\
    & =
    \begin{pmatrix}
      u \\ v \\ e^{-x} - x v - 3 u - y
    \end{pmatrix}.
  \end{align*}
  %
  \begin{center}
    \rule{0.9\textwidth}{.1pt}
  \end{center}
  %
\item Show by Taylor expansion that the backwards differencing
  estimate of $f'(x)$,
  \begin{equation*}
    f'(x) \simeq \frac{f(x) - f(x-h)}{h}
  \end{equation*}
  is first order accurate.
  %
  \begin{center}
    \rule{0.9\textwidth}{.1pt}
  \end{center}
  %
  We have the Taylor series expansion of $f(x-h)$ about $x$ is
  \begin{equation*}
    f(x-h) = f(x) - h f'(x) + \frac{h^2}{2!} f''(x) + {\cal O}(h^3).
  \end{equation*}
  Substituting this in to the backwards difference formula we find
  \begin{align*}
    \frac{f(x) - f(x-h)}{h} & = \frac{f(x) - f(x) + h f'(x) -
      \frac{h^2}{2!} f''(x) + {\cal O}(h^3)}{h} \\
    & = f'(x) - \frac{h}{2!} f''(x) + {\cal O}(h^2).
  \end{align*}
  Therefore the difference between the exact derivative $f'$ and the
  backwards difference estimate is $\propto h$ and hence the finite
  difference estimate is first order accurate.
  %
  \begin{center}
    \rule{0.9\textwidth}{.1pt}
  \end{center}
  %
\item Use Taylor expansion to derive a symmetric or central difference
  estimate of $f^{(4)}(x)$ on a grid with spacing $h$.
  %
  \begin{center}
    \rule{0.9\textwidth}{.1pt}
  \end{center}
  %
  For this we need the Taylor expansions
  \begin{align*}
    f(x + h) & = f(x) + h f^{(1)}(x) + \frac{h^2}{2!} f^{(2)}(x) +
    \frac{h^3}{3!} f^{(3)}(x) + \frac{h^4}{4!} f^{(4)}(x) +
    \frac{h^5}{5!} f^{(5)}(x) + \dots \\
    f(x - h) & = f(x) - h f^{(1)}(x) + \frac{h^2}{2!} f^{(2)}(x) -
    \frac{h^3}{3!} f^{(3)}(x) + \frac{h^4}{4!} f^{(4)}(x) -
    \frac{h^5}{5!} f^{(5)}(x) + \dots \\
    f(x + 2 h) & = f(x) + 2 h f^{(1)}(x) + \frac{4 h^2}{2!} f^{(2)}(x) +
    \frac{8 h^3}{3!} f^{(3)}(x) + \frac{16 h^4}{4!} f^{(4)}(x) +
    \frac{32 h^5}{5!} f^{(5)}(x) + \dots \\
    f(x - 2 h) & = f(x) - 2 h f^{(1)}(x) + \frac{4 h^2}{2!} f^{(2)}(x) -
    \frac{8 h^3}{3!} f^{(3)}(x) + \frac{16 h^4}{4!} f^{(4)}(x) -
    \frac{32 h^5}{5!} f^{(5)}(x) + \dots
  \end{align*}
  By a central or symmetric difference estimate we mean that the
  coefficient of $f(x \pm n h)$ should have the same magnitude. By
  comparison with central difference estimates for first and second
  derivatives we see that for odd order derivatives the coefficients
  should have opposite signs and for even order the same sign.

  So we write our estimate as
  \begin{equation*}
    f^{(4)}(x) \simeq A f(x) + B \left( f(x + h) + f(x - h) \right)
    + C \left( f(x + 2 h) +  f(x - 2 h) \right)
  \end{equation*}
  and we then need to constrain the coefficients $A, B, C$. By looking
  at terms proportional to $h^s$ we see
  \begin{align*}
    h^0: && 0 & = A + 2 B + 2 C \\
    h^1: && 0 & = 0 \\
    h^2: && 0 & = B + 4 C \\
    h^3: && 0 & = 0 \\
    h^4: && \frac{1}{h^4} & = \frac{B}{12} + \frac{16 C}{12}.
  \end{align*}
  This gives three constraints on our three unknowns so we cannot go
  to higher order. Solving the equations gives
  \begin{equation*}
    A = \frac{6}{h^4}, \qquad B = -\frac{4}{h^4}, \qquad C =
    \frac{1}{h^4}.
  \end{equation*}
  Writing it out in obvious notation we have
  \begin{equation*}
    f_1^{(4)} = \frac{1}{h^4} \left( 6 f_i - 4 (f_{i+1} + f_{i-1}) +
      (f_{i+2} + f_{i-2}) \right).
  \end{equation*}
  %
  \begin{center}
    \rule{0.9\textwidth}{.1pt}
  \end{center}
  %
\item State the convergence rate of Euler's method and the
  Euler predictor-corrector method.
  %
  \begin{center}
    \rule{0.9\textwidth}{.1pt}
  \end{center}
  %
  Euler's method converges as $h$ and the predictor-corrector method
  as $h^2$.
  %
  \begin{center}
    \rule{0.9\textwidth}{.1pt}
  \end{center}
  %
\item Explain when multistage methods such as Runge-Kutta methods are useful.
  %
  \begin{center}
    \rule{0.9\textwidth}{.1pt}
  \end{center}
  %
  Multistage methods require only one vector of initial data, which
  must be provided to completely specify the IVP; that is, the method
  is self-starting. It is also easy to adapt a multistage method to
  use variable step sizes; that is, to make the algorithm adaptive
  depending on local error estimates in order to keep the global error
  within some tolerance. Finally, it is relatively easy to
  theoretically show convergence. Combining this we see that
  multistage methods are useful as generic workhorse algorithms and in
  cases where the function defining the IVP may vary widely in
  behaviour, so that adaptive algorithms are required.
  %
  \begin{center}
    \rule{0.9\textwidth}{.1pt}
  \end{center}
  %
\item{} [3018 only] Explain the power method for finding the largest
  eigenvalue of a matrix. In particular, explain why it is simpler to
  find the absolute value, and how to find the phase information.
  %
  \begin{center}
    \rule{0.9\textwidth}{.1pt}
  \end{center}
  %
  The idea behind the power method is that most easily seen by writing
  out a generic vector ${\bf x}$ in terms of the eigenvectors of the
  matrix $A$ whose eigenvalues we wish to find,
  \begin{equation*}
    {\bf x} = \sum_{i=1}^N a_i {\bf e}_i,
  \end{equation*}
  where we assume that the eigenvectors are ordered such that the
  associated eigenvalues have the order $|\lambda_1| > |\lambda_2| \ge
  |\lambda_3| \ge \dots \ge |\lambda_N|$. Note that we always assume
  that there is a unique eigenvalue $\lambda_1$ with largest
  magnitude.

  We then note that multiplying this generic vector by the matrix $A$
  a number of times gives
  \begin{equation*}
    A^k {\bf x} = \lambda_1^k \sum_{i=1}^n a_i \left(
      \frac{\lambda_i}{\lambda_1} \right)^k {\bf e}_i.
  \end{equation*}
  We then note that, for $i \ne 1$, the ratio of the eigenvalues
  $(\lambda_i/\lambda_1)^k$ must tend to zero as $k \rightarrow
  \infty$. Therefore in the limit we will ``pick out'' $\lambda_1$.

  Of course, to actually get the eigenvalue itself we have to
  essentially divide two vectors. That is, we define a sequence ${\bf
    x}^{(k)}$ where the initial value ${\bf x}^{(0)}$ is arbitrary and
  at each step we multiply by $A$, so that
  \begin{equation*}
    {\bf x}^{(k)} = A^k {\bf x}^{(0)}.
  \end{equation*}
  It follows that we can straightforwardly get $\lambda_1$ by looking
  at ``the ratio of successive iterations''. E.g.,
  \begin{equation*}
    \lim_{k \rightarrow \infty} \frac{\| {\bf x}^{(k+1)} \|}{\| {\bf
        x}^{(k)} \|} = | \lambda_1 |.
  \end{equation*}

  This only gives information about the magnitude as we have used the
  simplest way of getting from a vector to a real number, the absolute
  value. To retain information about the phase we need to replace the
  absolute value of the vectors with some linear functional such as
  the sum of the coefficients.
  %
  \begin{center}
    \rule{0.9\textwidth}{.1pt}
  \end{center}
  %
\end{enumerate}

\end{document}


\chapter{Scientific Background}

This chapter can be used as your literature reveiw chapter and to include any
information on scientific theories that are particularly relevant to your
research. Here is an example of and equation.
%
\begin{equation}
    F_{es} = -\frac{1}{2} \int \epsilon(\mathbf{r}) \mathbf{E}^2(\mathbf{r}) dr
    \label{esfnrg}
\end{equation}
%
where $\epsilon(\mathbf{r})$ is the dielectric constant at position
$\mathbf{r}$ and $\mathbf{E}(\mathbf{r})$ is the electric field at the same
position. The equation can be referenced like this \ref{esfnrg}.


\documentclass[12pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage{makeidx}
\usepackage{graphicx}
\usepackage{lmodern}
\usepackage{url}
\usepackage{bm}
\usepackage{booktabs}
\usepackage[left=2cm,right=2cm,top=2cm,bottom=2cm]{geometry}
\author{Mudathir Mahgoub}
\title{Project proposal}
\begin{document}

\maketitle

\section{Solver for propositional dynamic logic formulas}
The idea of the project is to implement a solver for formulas in propositional dynamic logic (PDL). The input would be a formula in PDL and optionally a kripke frame for that formula. The output result is either \textit{unsat}, \textit{sat} or \textit{unknown}. To check the validity of a formula, the input would be its negation, and it is valid if the result is \textit{unsat}. If a kripke frame is given, the result scope would be restricted to this kripke frame. Otherwise, the result scope would be all kripke frames.

The project is primarily code and would use the SMT solver CVC4 as a back end and apply the relation theory to implement the semantics of PDL. The project would import CVC4 abstract syntax tree (AST) for relations from another project that I am working on (Alloy2SMT translator\footnote{\url{https://github.com/CVC4/org.alloytools.alloy/tree/cvc4/alloy2smt}}) which supports type checking and SMT models parsing, albeit it needs some refactoring to be more generic.  For this project I would write a translator from PDL AST to CVC4 AST and display back the SMT models returned from CVC4 as Kripke frames and dot files for visualization using software like graphvis.

\section{Progress so far}

Since CVC4 AST is written in Java, I am using Java for this project along with  gradle\footnote{\url{https://github.com/mudathirmahgoub/pdl}}. I have written an ANTLR4 grammar for PDL following the syntax in chapter 5 in \cite{dynamic}. The grammar also handles a kripke frame written using the set notation in chapter 5 with one difference ($m_{\mathfrak{K}}(a)$ would be written as $m(a)$). Lastly I  prepared classes for PDL AST for Kripke frames, formulas and programs. Next tasks would be parsing PDL input into PDL AST and translating this AST into CVC4 AST.

\section{Preferences for presentation day}

 April 30 is the most preferred date. May 2  is least preferred date because I have a project presentation for another class on this date.

\bibliographystyle{plain}

\bibliography{references}

\end{document}


\section{Output}

The simulation program gives the coefficients \gls{frrcfa} and \gls{frrcfb} of the Fourier transform of \gls{difint}.
It is then possible to calculate the latter for each harmonic \gls{hmc} and value of \gls{frrvar} by averaging the coefficients over all the simulation outputs from the same set of starting parameters.

\begin{equation}\label{eq:fourier-amplitude}
  \gls{frrtrf}(\gls{frrvar}) =
    \hat{\gls{expval}} \left( \gls{frrcfa}(\gls{frrvar}) \right) + i \times \hat{\gls{expval}} \left( \gls{frrcfb}(\gls{frrvar}) \right)
\end{equation}

\medskip

\gls{frrtrf} is complex.
It is either its module or its real part that will be used.
The functions can be represented according to two methods as shown in \figref{fig:rdd-output}.
In \gls{r1} the functions are represented in logarithmic scale as a function of \gls{frrvar}.
In \gls{r2} the functions are represented through the transformation \( \ln\left( \cdot \right) / \gls{frrvar}^2 \) as a function of \gls{frrvar} in logarithmic scale.
With \gls{r2} a linear behavior can be observed for the asymptotic values of \gls{frrvar}.

\bigfig{fig:rdd-output}{insert/output}{100_rho5e13m-2_square_3200nm_RDD_d5e-5nm-2_edge_S0_PBC1_output}{Results of an X-ray diffraction simulation conducted on a sample of \gls{rdd}}

The example shown in \figref{fig:rdd-output} can be exported with the following script.

\pyscript{insert/output}{plot.py}

\bigskip

For the rest it is defined the orthonormal basis \( \left( \ux, \uy, \uz \right) \) as follow.
\uz \ gives the direction of the dislocation line vectors \gls{vecl}.
\ux \ gives the direction of the vector associated with the Fourier variable \gls{frrvar}.
And \( \uy = \uz \times \ux \).

\subsection{Fit models}

To determine the density \gls{dst} and the outer cut-off radius \gls{cutrad}, the theoretical models at our disposal are fitted to the simulation results.
These models are presented here.
It is first defined some quantities that will be common to the models.
\( k \) can be compared to the directing coefficient of the linear part in \gls{r2} in \figref{fig:rdd-output}.
\( \psi \) is the angle between \gls{vecg} and \gls{vecl}.
\gls{pssrat} is the \glsdesc{pssrat}.
\( \gamma \) is the angle between the projections of \gls{vecg} and \gls{vecb} in the plane orthogonal to \gls{vecl}.
Finally \gls{confac} is the contrast factor defined for edge and screw dislocations in elastically isotropic crystals.

\begin{equation}
  k =
    \frac{\pi}{2} | \gls{hmc} \gls{vecg} |^2 | \gls{vecb} |^2 \gls{confac} \gls{dst}
\end{equation}

\begin{equation}
  \psi =
    \angle \left( \gls{vecg}, \gls{vecl} \right)
\end{equation}

\begin{equation}
  \gamma = \angle \left(
    \gls{vecg} - \left( \gls{vecg} \cdot \uz \right) \uz,
    \gls{vecb} - \left( \gls{vecb} \cdot \uz \right) \uz
    \right)
\end{equation}

\begin{equation}\label{eq:contrast-factor}
  \gls{confac}_\mathrm{edge} =
    \begin{cases}
      \sin^4 \psi \frac{1}{8(1-\nu)^2} \left( 1 - 4 \nu + 8 \nu^2 + 4 (1 - 2 \nu) \cos^2 \gamma \right)
      & \text{for edge dislocations} \\[3mm]
      \sin^2 \psi \cos^2 \psi
      & \text{for screw dislocations}
    \end{cases}
\end{equation}

\subsubsection{\glsentrytext{guw1}}

Equation \eqref{eq:guw1} gives be the Fourier transform of diffraction vector harmonic \gls{hmc} as predicted in the \gls{guw1} \cite{GUW1988} \cite{SGL2001}.
Compared to the original proposal, \( \langle \gls{dst}^2 \rangle - \langle \gls{dst} \rangle^2 \) has been simplified to \( \delta \langle \gls{dst} \rangle^2 \) with \( \delta \) a coefficient quantifying the density fluctuation and \( \ln(\gls{frrvar}/R_1) \ln(\gls{frrvar}/R_2) \) has been simplified to \( (\ln(\gls{frrvar}/R_0))^2 \).

\begin{equation}
  \define{
    \gls{guw1}_{\gls{hmc}}
  }{
    \gls{setR}^*
  }{
    \gls{setR}
  }{
    \gls{frrvar}
  }{
    \exp\left( \gls{frrvar}^2 D_{\gls{hmc}}(\gls{frrvar}) \right)
  }
  \label{eq:guw1}
\end{equation}

\begin{equation}
  D_{\gls{hmc}}(\gls{frrvar}) =
    k \left( \ln \left( \frac{\gls{frrvar}}{\gls{cutrad}} \right) + \frac{\delta}{2} k \gls{frrvar}^2 \left( \ln\left( \frac{\gls{frrvar}}{R_0} \right) \right)^2 \right)
\end{equation}

\subsubsection{\glsentrytext{guw2}}

Equation \eqref{eq:guw2} gives be the Fourier transform of diffraction vector harmonic \gls{hmc} as predicted in the \gls{guw2} \cite{GUW1988}.

\begin{equation}
  \define{
    \gls{guw2}_{\gls{hmc}}
  }{
    \gls{setR}^*
  }{
    \gls{setR}
  }{
    \gls{frrvar}
  }{
    \exp\left( \gls{frrvar}^2 D_{\gls{hmc}}(\gls{frrvar}) \right)
  }
  \label{eq:guw2}
\end{equation}

\begin{equation}
  D_{\gls{hmc}}(\gls{frrvar}) =
    k \left( \ln \left( \gls{frrvar} \right) - \ln\left( \left( \gls{hmc} \gls{vecg} \cdot \gls{vecb} \right) \gls{cutrad} \right) \right)
\end{equation}

\subsubsection{\glsentrytext{w1}}

Equation \eqref{eq:w1} gives be the Fourier transform of diffraction vector harmonic \gls{hmc} as predicted in the \gls{w1} \cite{W1970}.

\begin{equation}
  \define{
    \gls{w1}_{\gls{hmc}}
  }{
    \gls{setR}^*
  }{
    \gls{setR}
  }{
    \gls{frrvar}
  }{
    W_{\gls{hmc}}^S(\gls{frrvar}) W_{\gls{hmc}}^D(\gls{frrvar})
  }
  \label{eq:w1}
\end{equation}

\begin{align}
  W_{\gls{hmc}}^S(\gls{frrvar}) &= 1 \\
  W_{\gls{hmc}}^D(\gls{frrvar}) &= \exp\left( \gls{frrvar}^2 D_{\gls{hmc}}(\gls{frrvar}) \right)
\end{align}

\begin{equation}
  D_{\gls{hmc}}(\gls{frrvar}) =
    - k f \left( \frac{1}{2e^\frac{1}{4}} \frac{\gls{frrvar}}{\gls{cutrad}} \right)
\end{equation}

\medskip

\begin{equation}
  f(\eta) =
    \begin{cases}
      - \ln(\eta) + \frac{7}{4} - \ln(2) + \frac{512}{90 \pi} \eta^{-1} \\[5mm]
      + \frac{2}{\pi} \left( 1 - \frac{1}{4}\eta^{-2} \right) \int_0^\eta \frac{\arcsin(V)}{V} dV \\[5mm]
      - \frac{1}{\pi} \left( \frac{769}{180} \eta^{-1} + \frac{41}{90} \eta + \frac{2}{90}\eta^3 \right) \sqrt{ 1 - \eta^2 }
      & \forall \eta \leq 1 \\[1cm]
      \frac{512}{90 \pi} \eta^{-1} - \left( \frac{11}{24} + \frac{1}{4} \ln(2) \eta \right) \eta^{-2}
      & \forall \eta > 1
    \end{cases}
\end{equation}

\subsubsection{\glsentrytext{w2}}

Equation \eqref{eq:w2} gives be the Fourier transform of diffraction vector harmonic \gls{hmc} as predicted in the \gls{w2} proposed by \textcite{KD2001}.

\begin{equation}
  \define{
    \gls{w2}_{\gls{hmc}}
  }{
    \gls{setR}^*
  }{
    \gls{setR}
  }{
    \gls{frrvar}
  }{
    \exp\left( \gls{frrvar}^2 D_{\gls{hmc}}(\gls{frrvar}) \right)
  }
  \label{eq:w2}
\end{equation}

\begin{equation}
  D_{\gls{hmc}}(\gls{frrvar}) =
    k \left( \ln \left( \gls{frrvar} \right) - \ln\left( \left( \gls{hmc} \gls{vecg} \cdot \gls{vecb} \right) \gls{cutrad} \right) - 2 \ln(2) +\frac{1}{3} + \ln\left(|\sin(\psi) \gls{vecg} \cdot \gls{vecb}| \right) \right)
\end{equation}

\subsection{Fits}

For each model, the fits are performed for each harmonic \gls{hmc} and for several maximum values of \gls{frrvar}.
The Nelder–Mead method is used to find the minimum of the objective function.
\figref{fig:fit:example:rdd} show a fit for a given \gls{hmc} and a given maximum value of \gls{frrvar}.

\bigfig{fig:fit:example:rdd}{insert/fits/100_rho5e13m-2_square_3200nm_RDD_d5e-5nm-2_edge_S0_PBC1_output_analysis/fits_plot_GUW2}{j1_118nm}{Fit of \gls{guw2} over the harmonic 1 of the computed Fourier Transform of \gls{rdd}}

\subsubsection{Filters}

It has been developed two ways of choosing the maximum value of the maximum values of \gls{frrvar}.
The first one, named \gls{f1}, aims at keeping only the relevant results and locates the point where \gls{frrtrf} becomes noise (i.e. when it is no longer decreasing).
The second filter, named \gls{f2}, marks the end of the linearity zone of \( \ln \left( \gls{frrtrf}(\gls{frrvar}) \right) / \gls{frrvar}^2 \) as a function of \( \ln(\gls{frrvar}) \).
Given the application assumptions of the models, the filter \gls{f1} is applied with \gls{w1} and \gls{f2} is applied with \gls{guw2} and \gls{w2}.
Indeed \gls{guw2} and \gls{w2} are asymptotic models and \gls{w1} is supposed to describe the complete line profile for \gls{rrdd}.
The purpose of these filters is therefore to apply the models to the intervals for which they are intended.

\medfig{fig:filter-1}{insert/filters}{f1}{Example of filtering with \gls{f1}}%
\medfig{fig:filter-2}{insert/filters}{f2}{Example of filtering with \gls{f2}}%

\bigskip

\gls{f1} stops at index \( i \) when equation \eqref{eq:filter-1} is not verified.
In the same way \gls{f2} stops at index \( i \) when equation \eqref{eq:filter-2} is not verified.

\begin{equation}\label{eq:filter-1}
y_{i+1} < y_i
\end{equation}

\begin{equation}\label{eq:filter-2}
\left| \frac{\hat{\gls{stddev}}_{\text{Linear regression of } \{ y_i \}_{j<i}}}{\max \left( \{ y_i \}_{j<i} \right) - \min \left( \{ y_i \}_{j<i} \right)} \right| < 0.01
\end{equation}

\subsubsection{Residuals}

The models \gls{guw2} and \gls{w2} are fitted within the representation \( \ln \left( \gls{frrtrf}(\gls{frrvar}) \right)/L^2 \) as a function of \gls{frrvar} and the model \gls{w1} is fitted within the representation \( \gls{frrtrf}(\gls{frrvar}) \) as a function of \( \ln(\gls{frrvar}) \). Thus the residuals are defined in \eqref{eq:fit-residual-1} for \gls{w1} and in \eqref{eq:fit-residual-2} for \gls{guw2} and \gls{w2}.

\begin{align}
\hat{\epsilon}_i &=
\gls{frrtrf}(\gls{frrvar}_i) - \gls{frrtrf}^{M}(\gls{frrvar}_i) \label{eq:fit-residual-1} \\
\hat{\epsilon}_i &=
\frac{\ln\left(\gls{frrtrf}(\gls{frrvar}_i)\right)}{\gls{frrvar}^2} -
\frac{\ln\left(\gls{frrtrf}^{MOD}(\gls{frrvar}_i)\right)}{\gls{frrvar}^2} \label{eq:fit-residual-2}
\end{align}

\subsubsection{Weighting}
The application of the logarithmic scale to the abscissa axis in the representation of \( \ln \left( \gls{frrtrf}(\gls{frrvar}) \right) / \gls{frrvar}^2 \) as a function of \( \ln(\gls{frrvar}) \) induces a rapprochement of the measurement points with \gls{frrvar} increasing.
Here is proposed a weighting of each point according to the distance between it and its neighbors.
With this weighting, the fits fit better to the linear parts in the latter representation.

\begin{align}
w^{\gls{w1}}_i &= 1 \\
w^{\gls{guw2}}_i = w^{\gls{w2}}_i &=
n
\frac{
\ln \left(\gls{frrvar}_{i + 1} \right) - \ln \left(\gls{frrvar}_i\right)
}{
\ln \left(\gls{frrvar}_{n + 1} \right) - \ln \left(\gls{frrvar}_1\right)
} =
\frac{n}{\ln \left( n + 1 \right)} \ln \left( \frac{i+1}{i} \right)
\end{align}

\subsubsection{Standard fit error}
The objective function to be minimized for a given model \( M \), a harmonic \gls{hmc} and a maximum value \( \gls{frrvar}_n \) of \gls{frrvar} is the standard error of the fit defined in equation \eqref{eq:fit-standard-error}.

\begin{equation}\label{eq:fit-standard-error}
\hat{\gls{stddev}} \left( \gls{frrtrf}^M \right) = \sqrt{\sum_{i=1}^n \frac{w^M_i\hat{\epsilon}_i^2}{n-2}}
\end{equation}

\subsection{Synthesis}\label{sec:synthesis}

Below is an overview of the parameters used for the generation of the samples of distributions.

\begin{tcolorbox}
\begin{verbatim}
5e13m-2:
5.000e-05m-2 square 3200nm RDD (d=5e-5nm-2) S=0
5.000e-05m-2 square 3200nm RRDD-E (d=5e-5nm-2 s= 200nm) S=0
5.000e-05m-2 square 3200nm RRDD-E (d=5e-5nm-2 s= 400nm) S=0
5.000e-05m-2 square 3200nm RRDD-R (d=5e-5nm-2 s= 200nm) S=0
5.000e-05m-2 square 3200nm RRDD-R (d=5e-5nm-2 s= 400nm) S=0
5.000e-05m-2 square 3200nm RCDD-E (d=5e-5nm-2 s= 800nm t= 84nm) S=0
5.000e-05m-2 square 3200nm RCDD-R (d=5e-5nm-2 s= 800nm t= 84nm) S=0
5.000e-05m-2 square 3200nm RCDD-D (d=5e-5nm-2 s= 800nm t= 84nm l= 71nm) S=0
5.000e-05m-2 square 3200nm RCDD-D (d=5e-5nm-2 s= 800nm t= 84nm l=141nm) S=0
5.000e-05m-2 square 3200nm RCDD-D (d=5e-5nm-2 s= 800nm t= 84nm l=283nm) S=0

5e14m-2:
5.000e-04m-2 square 3200nm RDD (d=5e-4nm-2) S=0
5.000e-04m-2 square 3200nm RRDD-E (d=5e-4nm-2 s= 200nm) S=0
5.000e-04m-2 square 3200nm RRDD-E (d=5e-4nm-2 s= 400nm) S=0
5.000e-04m-2 square 3200nm RRDD-R (d=5e-4nm-2 s= 200nm) S=0
5.000e-04m-2 square 3200nm RRDD-R (d=5e-4nm-2 s= 400nm) S=0
5.000e-04m-2 square 3200nm RCDD-E (d=5e-4nm-2 s= 800nm t= 84nm) S=0
5.000e-04m-2 square 3200nm RCDD-R (d=5e-4nm-2 s= 800nm t= 84nm) S=0
5.000e-04m-2 square 3200nm RCDD-D (d=5e-4nm-2 s= 800nm t= 84nm l= 22nm) S=0
5.000e-04m-2 square 3200nm RCDD-D (d=5e-4nm-2 s= 800nm t= 84nm l= 45nm) S=0
5.000e-04m-2 square 3200nm RCDD-D (d=5e-4nm-2 s= 800nm t= 84nm l= 89nm) S=0

5e15m-2:
5.000e-03m-2 square 3200nm RDD (d=5e-3nm-2) S=0
5.000e-03m-2 square 3200nm RRDD-E (d=5e-3nm-2 s= 200nm) S=0
5.000e-03m-2 square 3200nm RRDD-E (d=5e-3nm-2 s= 400nm) S=0
5.000e-03m-2 square 3200nm RRDD-R (d=5e-3nm-2 s= 200nm) S=0
5.000e-03m-2 square 3200nm RRDD-R (d=5e-3nm-2 s= 400nm) S=0
5.000e-03m-2 square 3200nm RCDD-E (d=5e-3nm-2 s= 800nm t= 84nm) S=0
5.000e-03m-2 square 3200nm RCDD-R (d=5e-3nm-2 s= 800nm t= 84nm) S=0
5.000e-03m-2 square 3200nm RCDD-D (d=5e-3nm-2 s= 800nm t= 84nm l=  7nm) S=0
5.000e-03m-2 square 3200nm RCDD-D (d=5e-3nm-2 s= 800nm t= 84nm l= 14nm) S=0
5.000e-03m-2 square 3200nm RCDD-D (d=5e-3nm-2 s= 800nm t= 84nm l= 28nm) S=0
\end{verbatim}
\end{tcolorbox}

\bigskip

These distribution models are illustrated in section \ref{sec:data}.
Here is proposed a synthesis of the results of the fits performed on the simulation outputs of the latter.
The objective was to gather in a single data the fits performed for several maximum values of \gls{frrvar} for a given distribution, model and harmonic.
To simplify the reading of the tables, the density values closest to the real densities have been colored.
Not all decimal places are displayed.

\bigskip

\newpage

{\renewcommand{\arraystretch}{1.6}

\subsubsection{Mean effective cut-off radius and relative mean density deviation}

\input{load/tex/avg-tables}

\input{load/tex/avg-plots}

\newpage

\subsubsection{Effective cut-off radius sandard deviation and relative density standard deviation}

\input{load/tex/std-tables}

\input{load/tex/std-plots}

\newpage

\subsubsection{Validity domain of \glsentrytext{guw1}}

\input{load/tex/guw1-plots}

\newpage

\figref{fig:guw1-RRDD-E-A} to \figref{fig:guw1-RCDD-R} allow to observe the relevance of applying the model \gls{guw1} on the complete profile.
When the abscissa is equal to 1, we obtain the accuracy that would be offered by \gls{guw1} if it was applied on the same range as the asymptotic model \gls{guw2} (delimited by \gls{f2}).
The point on the curve with the greatest abscissa corresponds the accuracy that is offered by \gls{guw1} in its current application conditions (i.e. applied on the complete profile delimited by \gls{f1}).

\subsection{Program}

The third and last program is used to process the post-simulation data.
It allows to average the coefficients from the Fourier analysis, to plot the simulation results, and to export the data and figures of the fits performed for each model.

\subsubsection{Repository}

Useful information can be found on the project page: \github{lpa-output}

\subsubsection{Installation}

The program can be installed or updated with the following command:

\pipinstall{lpa-output}

\subsubsection{Fits data}

For each harmonic and each maximum value of \gls{frrvar}, the optimal density and outer cut-off radius in terms of fit are saved in a file like the one below. These files are produced for each fit model applied to each distribution model.

\txtlst{insert/fits}{fits\_data\_structure.dat}