\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}


\documentclass{article}
\usepackage{amsmath,mathtools,amssymb}
\usepackage{graphicx}
\usepackage{booktabs}
\usepackage{blkarray}
\usepackage{gensymb}
\usepackage{verbatim}
\usepackage{mathrsfs}
\usepackage{bbm}
\usepackage{braket}
\usepackage{hyperref}
\usepackage{verbatim}
\usepackage{cancel}
\usepackage[margin=1.0in]{geometry}
\newcommand{\ol}{\overline}
\newcommand{\lp}{\left(}
\newcommand{\rp}{\right)}
\newcommand{\eps}{\varepsilon}
\newcommand{\lam}{\lambda}
\newcommand{\h}{\circ}
\newcommand{\p}{\bullet}

\newcommand{\Ezero}{E^{(0)}}
\newcommand{\Rz}{\mathcal{R}_{0}}

\newcommand{\Phizero}{\Phi^{(0)}}
\newcommand{\Eone}{E^{(1)}}
\newcommand{\En}{E^{(n)}}
\newcommand{\Phione}{\Phi^{(1)}}
\newcommand{\Phin}{\Phi^{(n)}}

\newcommand{\Ecorr}{E_{\mathrm{corr}}}
\newcommand{\Hc}{H_{\mathrm{c}}}
\newcommand{\dg}{\ensuremath{^\dagger} }
\def\*#1{\mathbf{#1}}
\DeclarePairedDelimiter\floor{\lfloor}{\rfloor}

\title{Lecture 5: Perturbation Theory II}
\date{April 6, 2020}
\begin{document}
\maketitle
\noindent

In perturbation theory, we split our Hamiltonian into parts $H = H_0 + V$, and our ground
state wavefunction $\ket{\Psi_0}$ and energy $E_0$ are expressed as an infinite series, where the first term is the unperturbed
quantity of some simpler model system described by $H_0$, and the rest of the terms
are corrections at various ``orders'' $n$:
\[\ket{\Psi_0} = \ket{\Phi_0} + \sum_{n=1}^{\infty} \ket{\Phin_0} \]
\[E_0 = \Ezero_0 + \sum_{n=1}^{\infty} \En_0\]

As we saw in the previous set of notes, the expression for each wavefunction and energy correction
    needs to be derived from a system of equations.
This way of doing things is very inefficient at high orders, so in this set of notes
    we will use a new scheme, which was primarily popularized and championed by Per-Olav L{\"o}wdin
    in his highly influential series of papers \textit{Studies in Perturbation Theory} in the 1960s.
The majority of the content in these notes can be found in the 9th (IX) paper in the series.
This new methodology will allow you to derive each order of PT using the same exact procedure.
Though the higher order wavefunctions and energy expressions get more and more complex,
the procedure for deriving them does not change at higher orders.
This methodology also beautifully translates into clean diagrams, which we will see later on.

%\section{L{\"o}wdin and his Resolvents}
\section{The Wave Operator}
Suppose there was some magical operator $\Omega$ which
acts on the unperturbed state $\ket{\Phi_0}$ (an eigenstate of $H_0$)
and transforms it into the exact state $\ket{\Psi_0}$ described by $H_0 + V$
\[\ket{\Psi_0} = \Omega \ket{\Phi_0} \]
We will call $\Omega$ the \textit{wave operator}.
For now, we have no idea what it is, but we do know what it does.
Suppose further that we are using an intermediate normalized $\Psi_0$ and normalized $\Phi_0$ such that
\[ \braket{\Phi_0|\Phi_0} = 1 \]
\[ \braket{\Phi_0 | \Psi_0} = \braket{\Phi_0 | \Omega | \Phi_0} = 1 \]
Under the above conditions, we will now see what happens to the Schr{\"o}dinger equation,
\[(H_0 + V) \ket{\Psi_0} = E_0 \ket{\Psi_0} \]
Projecting both sides of this equation by $\bra{\Phi_0}$ gives
\[\braket{\Phi_0 | H_0 | \Psi_0} + \braket{\Phi_0 | V | \Psi_0} = E_0 \braket{\Phi_0|\Psi_0} \]
The first term reduces to $\Ezero_0$ by acting $H_0$ to the left. The second term
can be re-expressed in terms of $\Omega$, and we obtain an expression for the
perturbed eigenvalue $E_0$ in terms of a \textit{shift} from the unperturbed eigenvalue $\Ezero_0$.
\[ E_0 = \Ezero_0 + \braket{\Phi_0 | V \Omega | \Phi_0}  \]
If we were to know what $\Omega$ is, at this point the eigenstates and eigenvalues would be completely
determined.
L{\"o}wdin derived that such an $\Omega$ can be constructed from an operator called a \textit{resolvent},
and under this definition, $\Omega$ yields the same perturbation expansion for $E_0$ and $\ket{\Psi_0}$.

\section{Resolvents}
A resolvent is a mathematical structure which is used to study the eigenspectrum
of operators, among other things.
The concept of a \textit{reduced resolvent} arises when one considers an eigenvalue problem \[A \phi = a \phi \]

Suppose the eigenfunctions $\phi$ can be expanded in an orthonormal basis ($f_1$, $f_2$, $f_3$,...) such that $\sum_i c_i f_i $
and let $\mathbf{A}_{ij} = \braket{f_i | A | f_j}$ be the matrix representation of the operator $A$ in this basis.
Suppose we divide the basis $f$ into two partitions $p$ and $q$.
If the $p$ partition is just a single basis function ($p: {f_1}$) (which we will just denote by the number 1) and the $q$ partition
    is all other basis functions ($q: {f_2, f_3,...}$),
    one finds with some manipulation that the eigenvalues are defined by the relation
\[ a =  A_{11} + \mathbf{A}_{1q}( a \cdot \mathbf{1}_{qq} - \mathbf{A}_{qq})^{-1} \mathbf{A}_{q1} \]
The above is the ``reduced'' characteristic equation, and it can be used for finding the eigenvalues.
It arises in the particular case of our partitioning of our basis in this manner.
The above equation can be thought of as an alternative to the standard characteristic equation $\mathrm{det}(\mathbf{A} - a\mathbf{1}) = 0$.

If we replace the eigenvalues $a$ in the expression above with some continuous, variable parameter $\kappa$, we obtain the following:
\[f(\kappa) =  A_{11} + \mathbf{A}_{1q}( \kappa \cdot \mathbf{1}_{qq} - \mathbf{A}_{qq})^{-1} \mathbf{A}_{q1} \]

Now, whenever this function is such that $f(\kappa) = \kappa $, we have found an eigenvalue $a = \kappa$.
If we vary this $\kappa$ until $f(\kappa) - \kappa = 0$, we pull out a discrete eigenvalue which is a solution to the eigenvalue problem.

The key quantity above
\[\mathcal{R}_{\kappa}(A) = ( \kappa \cdot \mathbf{1}_{qq} - \mathbf{A}_{qq})^{-1}\]
is the \textbf{reduced resolvent} operator of $\mathbf{A}$ for a particular $\kappa$.
\footnote{Here, $\mathbf{1}_{qq}$ is the identity matrix of size $q \times q$ and $\mathbf{A}_{qq}$ is
 the matrix representation of the operator in just the $q$-space, (over just $q$ basis functions)}
In words, the reduced resolvent is an operator that is assigned to another operator $\mathbf{A}$.
It is only defined in $q$-space part of the operator, and different values of $\kappa$ give different reduced resolvents.
As abstract as that is, it is tremendously useful, as we will see later.

Notice how the resolvent is dependent on just the matrix elements of the operator $\mathbf{A}$
which correspond to the $q$ partition; it lives in the $q$-space partition of our basis.
Expressed pictorially as a matrix representation divided into $pp$, $pq$, $qp$, $qq$ blocks,
\[\mathcal{R}_{\kappa}(A) =
\left( \begin{array}{c|c}
   0 & \mathbf{0} \\
   \midrule
   \mathbf{0} & (\kappa \mathbf{1}_{qq} - A_{qq})^{-1} \\
\end{array}\right)
  \]

\section{L{\"o}wdin's big idea: using reduced resolvents to define perturbation theory and solve the Schr{\"o}dinger equation}
Back to the world of quantum chemistry and the Schr{\"o}dinger equation,
we can define two projection operators $P$ and $Q$ which partition our $n$-electron Hilbert space into two parts (note: if that sounds like gobbledygook to you, see the Appendix for details).
It is this partitioning which birthed the idea of a reduced resolvent above.

$P$ is the ``model space projection operator'', which can act on a state
    and project it onto some reference determinant $\Phi_0$.
\[P = \ket{\Phi_0}\bra{\Phi_0}  \]
$Q$ is the \textit{orthogonal complement} of $P$, which projects out every determinant other than the reference $\Phi_0$
\[Q = 1 - P = \sum_{n \neq 0}  \ket{\Phi_n}\bra{\Phi_n}\]
$P$ and $Q$ basically just split our basis into two parts, and the sum of $P$ and $Q$ yield the resolution of the identity, $P + Q = 1$.
In terms of operators, the definition of the reduced resolvent for some operator $H$ is
\[\mathcal{R}_{\kappa} = (\kappa - H)^{-1} Q  \]
This is the operator analogue of the matrix representation form of $\mathcal{R}_{\kappa}(A)$
we defined earlier. Instead of only explicitly including matrix elements in the $q$ space,
we use our newly defined operator $Q$ to project the negative inverse of $H$ into the $Q$ space.
%TODO

L{\"o}wdin's idea, in short, was to generalize the Schr{\"o}dinger equation
to a continous spectrum in $\kappa$, and use the $\kappa$-dependent reduced resolvent in the definition of
a trial wavefunction to solve for the eigenvalues. Read that last sentence a few more times.
Hopefully, it will soon become clear what I mean by this.
Starting from the re-arranged Schr{\"o}dinger equation,
\[(E_0 - H) \ket{\Psi_0} = 0 \]
suppose we choose a form for the wavefunction which has a continuous dependence on some parameter
$\kappa$:
\[(\kappa - H) \ket{\Psi_{\kappa}} = ... \]
The above equation \textit{becomes} the Schrodinger equation whenever the right side is 0.
If this is the case, $\kappa$ happens to be equal to a true eigenvalue $E_0$.
For this reason, we refer to it as a \textit{generalization} of the Schr{\"o}dinger equation.

L{\"o}wdin derived that a \textbf{trial wavefunction} $\ket{\Psi_{\kappa}}$
    which is of the form $\ket{\Psi_\kappa} = \Omega_\kappa \ket{\Phi_0}$
    can be expressed in terms of the reduced resolvent.
\[\ket{\Psi_\kappa} = \Omega_\kappa \ket{\Phi_0}\]
\[\Omega_{\kappa} = P + \mathcal{R}_{\kappa} H P \]
\[\ket{\Psi_{\kappa}} = \ket{\Phi_0} + \mathcal{R}_{\kappa} H \ket{\Phi_0} \]

What happens when we apply $(\kappa - H)$ to our trial wavefunction $\ket{\Psi_{\kappa}}$?
as in the above expression $(\kappa - H) \ket{\Psi_{\kappa}} = ... $?
Applying the resolution of the identity $P + Q = 1$, we find
\[ (\kappa - H) \ket{\Psi_{\kappa}} =  P (\kappa - H) \ket{\Psi_{\kappa}} + Q (\kappa - H) \ket{\Psi_{\kappa}}  \]
Looking at just the $Q$ term, we find that
\begin{align*}
Q (\kappa - H) \ket{\Psi_{\kappa}} &= Q (\kappa - H) \ket{\Phi_0} + Q (\kappa - H) \mathcal{R}_{\kappa} H \ket{\Phi_0}  \\
&= \kappa Q \ket{\Phi_0} - Q H \ket{\Phi_0} + Q H \ket{\Phi_0}  \\
&= \kappa Q \ket{\Phi_0}  \\
&= 0
\end{align*}
Above we have used the fact that $ Q (\kappa - H) \mathcal{R}_{\kappa}  = Q$ , which follows
clearly from the definition of the reduced resolvent, and that $Q$ acting on $\ket{\Phi_0}$ is 0, since
$\ket{\Phi_0}$ lives in the $P$ space.
We conclude the $Q$ term is 0, so we are left with:
\[ (\kappa - H) \ket{\Psi_{\kappa}} =  P (\kappa - H) \ket{\Psi_{\kappa}} \]
Using the definition of $P = \ket{\Phi_0}\bra{\Phi_0}$, and noting that we can always ensure $\ket{\Psi_\kappa}$ is intermediately normalized, we obtain
\begin{align*}
 (\kappa - H) \ket{\Psi_{\kappa}} &=  \ket{\Phi_0}\bra{\Phi_0} (\kappa - H) \ket{\Psi_{\kappa}} \\
 &=  \kappa \ket{\Phi_0} \braket{\Phi_0|\Psi_\kappa} - \ket{\Phi_0} \braket{\Phi_0| H | \Psi_\kappa} \\
 &= (\kappa - \braket{\Phi_0 | H | \Psi_\kappa}) \ket{\Phi_0} \\
 &= (\kappa - \braket{\Phi_0 | H \Omega_\kappa | \Phi_0}) \ket{\Phi_0} \\
 &= (\kappa - \braket{\Phi_0 | H + H \mathcal{R}_\kappa H  | \Phi_0} ) \ket{\Phi_0} \\
 &= (\kappa - f(\kappa)) \ket{\Phi_0}
\end{align*}

where we have defined the function of $\kappa$, denoted  $f(\kappa)$ as
\[ f(\kappa) =  \braket{\Phi_0 | H | \Psi_\kappa} = \braket{\Phi_0 | H + H \mathcal{R}_\kappa H  | \Phi_0}\]
L{\"o}wdin calls this the \textit{bracketing function}, since it enables one to obtain both lower and upper bounds to true eigenvalues.
Restating the above in one compact expression, we have
\[ (\kappa - H) \ket{\Psi_{\kappa}} = (\kappa - f(\kappa)) \ket{\Phi_0} \]
\[ (\kappa - H) \Omega_\kappa \ket{\Phi_0} = (\kappa - f(\kappa)) \ket{\Phi_0} \]
This is a monumental result.
\textbf{When $\kappa$ is equal to $f(\kappa)$, the right side above goes to zero. If this occurs,
we conclude that our trial function $\ket{\Psi_{\kappa}}$
is a solution to the Schr{\"o}dinger equation, and the eigenvalue $\kappa$ is the corresponding
energy eigenvalue.}
Thus, our chosen trial function (derived by L{\"o}wdin) gives us access to the solutions of
the Schrodinger equation, by looking for zeros of $F(\kappa) = f(\kappa) - \kappa$.

\textbf{
To summarize, our discrete eigenvalue problem (the Schr{\"o}dinger equation)
was modified into a continuous form, which was enabled by the $\kappa$ dependence of the
reduced resolvent $\mathcal{R}_\kappa$, which Lowdin realized can be used to construct our magical wave operator $\Omega_\kappa$, which
transforms our reference determinant into some function $\Psi_\kappa$ by $ \ket{\Psi_\kappa} = \Omega_\kappa \ket{\Phi_0}$.
When $\kappa$ happens to be equal to an eigenvalue of the Schr{\"o}dinger equation,
we will know it, since $\kappa - f(\kappa) = 0$, and we will have found an eigenstate and eigenvalue (solved the Schr{\"o}dinger equation).
}

\subsection{L{\"o}wdin's Rayleigh-Schr{\"o}dinger Perturbation Theory}
We can now take our generalized Schr{\"o}dinger equation from above
\[ (\kappa - H) \Omega_\kappa \ket{\Phi_0} = (\kappa - f(\kappa)) \ket{\Phi_0} \]
and consider how it behaves when our Hamiltonian is split into two parts $H = H_0 + V$.

\paragraph{\textbf{The Wave Operator}}
Our wave operator becomes
\[\Omega_\kappa = P + \mathcal{R}_{\kappa} H_0 P + \mathcal{R}_{\kappa} V P \]
\[\Omega_\kappa = P + \mathcal{R}_{\kappa} H_0 \ket{\Phi_0}\bra{\Phi_0} + \mathcal{R}_{\kappa} V P \]
\[\Omega_\kappa = P + E_0 \mathcal{R}_{\kappa} P + \mathcal{R}_{\kappa} V P \]
\[\Omega_\kappa = P + \mathcal{R}_{\kappa} V P \]
where the reduced resolvent acting on $P$ is zero, since the resolvent entirely resides in the $Q$ space, which is orthogonal to $P$.

\paragraph{\textbf{The Bracketing Function}}
After a few manipulations which are left as an exercise,
the bracketing function $f(\kappa) = \braket{\Phi_0 | H \Omega_\kappa | \Phi_0}$ becomes
\[f(\kappa) = \Ezero_0 + \braket{\Phi_0 | V \Omega_\kappa | \Phi_0 } \]

\paragraph{\textbf{The Reduced Resolvent}}
We have one last quantity to fully define: the reduced resolvent.
How does the resolvent behave for our Hamiltonian $H = H_0 + V$?
\[\mathcal{R}_{\kappa} = (\kappa - H)^{-1}Q \]
We are about to do a lot of tricky manipulations, but in doing so,
we will arrive at perhaps the most important result in this set of notes.
Let's do it.
First we will expand $H$ and add $0 = \Ezero_0 - \Ezero_0$
\[\mathcal{R}_{\kappa} = (\kappa - \Ezero_0 + \Ezero_0 - H_0 - V)^{-1}Q \]
Rearranging and letting $V' = V - (\kappa - \Ezero_0)$:
\[\mathcal{R}_{\kappa} = (\Ezero_0 - H_0 - V')^{-1}Q \]
To move further, we use of the following identity for two operators $A$ and $B$,
\[ (A- B)^{-1} = A^{-1} + A^{-1} B (A - B)^{-1} \]
If we let  $A = (\Ezero_0 - H_0)$ and $B = V'$, we have
\[\mathcal{R}_{\kappa} = \left[ (\Ezero_0 - H_0)^{-1} +  (\Ezero_0 - H_0)^{-1} V' (\Ezero_0 - H_0 - V')^{-1} \right] Q\]
\[\mathcal{R}_{\kappa} = (\Ezero_0 - H_0)^{-1}Q +  (\Ezero_0 - H_0)^{-1} V' (\Ezero_0 - H_0 - V')^{-1}Q\]
Since $Q^2 = Q$ and Q is Hermitian we can insert a $Q$ in the second term:
\[\mathcal{R}_{\kappa} = (\Ezero_0 - H_0)^{-1}Q +  (\Ezero_0 - H_0)^{-1}Q V' (\Ezero_0 - H_0 - V')^{-1}Q\]
Expanding the definition of $V'$ in the parentheses we obtain
\[\mathcal{R}_{\kappa} = (\Ezero_0 - H_0)^{-1}Q +  (\Ezero_0 - H_0)^{-1}Q V' (\kappa - H)^{-1}Q\]
Now, we define the quantity $\Rz =  (\Ezero_0 - H_0)^{-1} Q$, the \textbf{unperturbed reduced resolvent},
which is the resolvent defined for $\kappa = \Ezero_0 $ and unperturbed Hamiltonian $H_0$.
\[\mathcal{R}_{\kappa} = \Rz +  \Rz V' (\kappa - H)^{-1}Q\]
Noting the last part of the second term is just our original reduced resolvent $\mathcal{R}_{\kappa} = (\kappa - H)^{-1}Q $,
we finally arrive at our result:
\[\mathcal{R}_{\kappa} = \Rz +  \Rz V' \mathcal{R}_{\kappa} \]
\textbf{The resolvent is dependent on itself.
Because of this, we can iteratively construct an expansion of the resolvent.
This will ultimately be the source of our perturbation expansion.}
In an exercise, you will explicitly iterate the resolvent, and show that it generalizes to the following
\[\mathcal{R}_{\kappa} = \sum_{n=0}^{\infty} (\Rz V')^n \Rz \]

Up to this point, we have defined everything with the subscript $\kappa$.
From here on, we will focus on just finding solutions for which $\kappa$ is our ground
state energy $\kappa = E_0$, so we will drop the $\kappa$ subscripts.
Since the only part of the resolvent above which depends on $\kappa$ is
$V' = V - (\kappa - \Ezero_0)$, we will now have
\[V' = V - (E_0 - \Ezero_0)\]
\[\mathcal{R} = \sum_{n=0}^{\infty} (\Rz V')^n \Rz \]
We will likewise drop the $\kappa$ from our definition of the wave operator
and the wave function
\[\Omega = P + \sum_{n=0}^{\infty} (\Rz V')^n \Rz V P \]
\[\ket{\Psi_0} = \Omega \ket{\Phi_0}\]
\[\ket{\Psi_0} =  \ket{\Phi_0} + \sum_{n=0}^{\infty} (\Rz V')^n \Rz V \ket{\Phi_0} \]
\textbf{This is our perturbation expansion for the wavefunction.}
From section 1, ``The Wave Operator'', we derived our energy expression to be,
\[ E_0 = \Ezero_0 + \braket{\Phi_0 | V \Omega | \Phi_0}  \]
Our energy expansion is therefore,
\[E_0 = \Ezero_0 + \braket{\Phi_0|V|\Phi_0} + \sum_{n=0}^{\infty} \braket{\Phi_0|V (\Rz V')^n \Rz V | \Phi_0}\]
\textbf{This is our perturbation expansion for the energy.}

The operator $V'$ introduces some complexity that is worth discussing.
It contains $E_0$, which is the exact energy,
    so it involves a sum over all orders of energy corrections.
\[V' = V - (E_0 - \Ezero_0) \]
\[V' = V - \sum_{m=1} E_0^{(m)} \]
\[V' = V - E_0^{(1)} - E_0^{(2)} - E_0^{(3)} - \cdots \]

To conclude, we have obtained expressions for the $n^{th}$ order wavefunction
and energy corrections in perturbation theory.
Looking at the expression for $\ket{\Psi_0}$, each order wavefunction correction
at higher orders is just a string of operators $(\Rz, V, V')$ acting on our reference determinant.
Each energy is just an expectation value of a string of operators $(\Rz, V, V')$.
Using these expansions in practice can be a bit tricky, as we will see in the next section.

\section{Deriving Perturbation Theory Orders}
Before we get started, we need to know how to identify the ``order'' of a term in our
wavefunction expansion. The reason is that if we want the
$m$th order wavefunction correction, we need to pull out all $m$th order
terms in $\ket{\Psi_0} =  \ket{\Phi_0} + \sum_{n=0}^{\infty} (\Rz V')^n \Rz V \ket{\Phi_0}$.

\paragraph{\textbf{How to identify the order of a term?}}
Some tips for finding the order of a given term:
\begin{itemize}
\item Each $V$ contributes an order of 1
\item Each $E_0^{(m)}$ contributes an order of $m$
\item Instead of counting orders from $V$ and $E_0^{(m)}$, you can instead count
the number of resolvents $\Rz$. Before doing so, you must convert all $E_0^{(m)}$ to the
corresponding analytic expression.
\end{itemize}
As an example of the above rules, when determining the order of the term
\[ \Rz E_0^{(2)} \Rz V \ket{\Phi_0} \]
which appears in the third-order wavefunction,
we could reason that $V$ and $E_0^{(2)}$ is $1 + 2 = 3 \implies$ third order.
Alternatively, we could recognize that $E_0^{(2)} = \braket{\Phi_0 |V \Rz V|\Phi_0}$ (for now,
just accept that this is true, we will derive it later),
so therefore our expression is
\[ \Rz \braket{\Phi_0 |V \Rz V|\Phi_0} \Rz V \ket{\Phi_0} \]
The above expression has 3 resolvents, so we conclude it is third order.
OR, we could count that the above expression has 3 $V$'s, and conclude it is third order.
Everything checks out.
Let's derive some perturbation theory orders.

\paragraph{\textbf{Zero order}}
The 0th order wavefunction correction is just the first term of the respective pertubation expansion
fro above, which is of course just our reference determinant $\ket{\Phi_0}$.
The 0th order energy is just $\Ezero_0$.

\paragraph{\textbf{First order}}
\[ \ket{\Phi_0^{(1)}} = \Rz V \ket{\Phi_0}\]
\[ E_0^{(1)} = \braket{ \Phi_0 | V | \Phi_0} \]

\paragraph{\textbf{Second order}}
We read off from the expansion for $n=1$,
\[ \ket{\Phi_0^{(2)}} = \Rz V' \Rz V \ket{\Phi_0}\]
Here is the only tricky thing with this formalism: $V'$ contains
higher order contributions to the energy
\[V' = V - E_0^{(1)} - E_0^{(2)} - E_0^{(3)} - \cdots\]
\textbf{Since we are building the second order wavefunction, it must be composed of only
second order pieces. The prefactor $\Rz V' \Rz V$ above should therefore only be second order.
The V is first order, so multiplying by V' should only increase the order by 1.
This means only terms in the V' expansion which are first order contribute
to the second order wavefunction.}
This means our $V'$ in this case is truncated to just $V + E_0^{(1)}$,
so we have,
\[\ket{\Phi_0^{(2)}} = \Rz (V - \Eone_0) \Rz V \ket{\Phi_0}\]
\[\ket{\Phi_0^{(2)}} = \Rz V \Rz V \ket{\Phi_0} - \Rz \Eone_0 \Rz V \ket{\Phi_0}\]
That's it!
The energy correction is,
\[ E_0^{(2)} = \braket{ \Phi_0 | V \Rz V | \Phi_0} \]

\paragraph{\textbf{Third order}}
Here we have track of the orders of various terms
more carefully.
To remind you, our wavefunction perturbation expansion is
\[\ket{\Psi_0} =  \ket{\Phi_0} + \sum_{n=0}^{\infty} (\Rz V')^n \Rz V \ket{\Phi_0} \]
At $n=2$, we have a $V$ and two $V'$ in our term.
To make the term third order overall (this is our target for constructing $\ket{\Phi_0^{(3)}}$),
we require that each $V'$ is 1st order, so we only take out the first order
energy and $V$ in our $V'$ expansion $V' = V - E_0^{(1)}$.
Let's now write this $n=2$ term down before moving on,
\[\ket{\Phi_0^{(3)}} = (\Rz (V - \Eone_0))^2 \Rz V \ket{\Phi_0} + (... \mathrm{more})\]

There is also a third-order term which appears when $n=1$,
$(\Rz V')^1 \Rz V \ket{\Phi_0}$. That $V'$ has a second order contribution from $E_0^{(2)}$,
therefore we set $V' = -E_0^{(2)}$ and
pick up an additional term $ \Rz E_0^{(2)} \Rz V \ket{\Phi_0}$ for $\ket{\Phi_0^{(3)}}$
\[\ket{\Phi_0^{(3)}} = (\Rz (V - \Eone_0))^2 \Rz V \ket{\Phi_0} - \Rz E_0^{(2)} \Rz V \ket{\Phi_0} \]
Expanding this and simplifying yields
\[\ket{\Phi_0^{(3)}} = \Rz V \Rz V \Rz V \ket{\Phi_0} - \Rz \Eone_0 \Rz V \Rz V \ket{\Phi_0}
  - \Rz V \Rz \Eone_0 \Rz V \ket{\Phi_0} + \Rz E_0^{(1)} \Rz E_0^{(1)} \Rz V \ket{\Phi_0}
 - \Rz E_0^{(2)} \Rz V \ket{\Phi_0} \]

Our energy expansion is
\[E_0 = \Ezero_0 + \braket{\Phi_0|V|\Phi_0} + \sum_{n=0}^{\infty} \braket{\Phi_0|V (\Rz V')^n \Rz V | \Phi_0}\]

The third order contribution to the energy expression occurs for $n=1$ and is
\[ E_0^{(3)} = \braket{\Phi_0 | V ( \Rz (V - E_0^{(1)})) \Rz V | \Phi_0} \]
Alternatively, we could have also found the above by noting that generally the $(m+1)$ order energy is found
by the $m$th order wavefunction,
\[ E_0^{(m+1)} = \braket{\Phi_0 | V | \Phi_0^{(m)}} \]
\[ E_0^{(3)} = \braket{\Phi_0 | V | \Phi_0^{(2)}} \]
and just plug in our derived $\ket{\Phi_0^{(2)}}$.

\section{The Energy Substitution Theorem}
There is a pattern for finding equations for $\Phi_0^{(m)}$, so you don't have to
go through the tedious process of analyzing where to get terms of a certain order for different
values of $n$ in the expansion, or plucking out the proper terms from $V'$
(but you should know how to do this anyway).

\paragraph{\textbf{Energy Substitution Theorem}}
 $\ket{\Phi_0^{(m)}}$ is equal to the sum of a ``principal term''
 $(\Rz V)^m \ket{\Phi_0} $ plus all unique substitutions of
adjacent factors $(\Rz V)^r$ with $(\Rz E_0^{(r)})$. Each term
in the sum is waited by a sign factor $(-1)^k$ where $k$ is the number of substitutions.
The pair of operators $\Rz V$ closest to the ket $\ket{\Phi_0}$ is not considered for substitutions. \\

We will not prove this, but hopefully by looking at the expressions for  $\ket{\Phi_0^{(2)}}$ and $\ket{\Phi_0^{(3)}}$ that we just derived will convince you:

\[\ket{\Phi_0^{(2)}} = \Rz V \Rz V \ket{\Phi_0} - \Rz \Eone_0 \Rz V \ket{\Phi_0}\]

\[\ket{\Phi_0^{(3)}} = \Rz V \Rz V \Rz V \ket{\Phi_0} - \Rz \Eone_0 \Rz V \Rz V \ket{\Phi_0}
  - \Rz V \Rz \Eone_0 \Rz V \ket{\Phi_0} + \Rz E_0^{(1)} \Rz E_0^{(1)} \Rz V \ket{\Phi_0}
 - \Rz E_0^{(2)} \Rz V \ket{\Phi_0} \]

Now we barely even need to think when we write down our perturbative wavefunction corrections.
Keeping in mind the energy corrections follow form
\[ E^{(m+1)} = \braket{\Phi_0 | V | \Phi_0^{(m)}} \]
our wavefunction correction expressions determine our energy expression corrections.

\section{Concluding Remarks}
I should note that we have not actually translated the energy corrections into
programmable expressions.
To do this, we would have to actually evaluate the expectation values, and it would
be a lot of work.
Later on in the course, after learning diagrams, we will revisit PT and learn
how to diagrammatically derive programmable expressions for the various energy orders.
When we do this, we will cleverly choose $H_0$ and $V$ such that $E_0^{(0)} = E_0^{(1)} = 0$,
which simplifies things a good bit, and also makes it so that each energy
correction is purely a correlation energy contribution.
For a sneak peak, you can look at handout 6 from the 2017 edition of this course.

That was a long and arduous mathematical climb. But we have finally reached the summit,
and now hopefully you can see that all of perturbation theory is obtainable by just
smacking your reference state $\ket{\Phi_0}$ with operator strings consisting
of resolvents $\Rz$ and the perturbed part of the Hamiltonian $V$.
Compare this to how we derived MP2 in the previous set of notes; we had to do a bunch of
algebraic manipulations to get to the end result.
As you can imagine, deriving MP3 and MP4 under that framework only gets worse.
In L{\"o}wdin's resolvent formalism, we can just read off the result,
    and then evaluate it to an algebraic expression using diagrams.

\section{Appendix}
\subsection{Hilbert Space}
Recall that many of the objects we have been talking about (spin orbitals, Slater determinants, wavefunctions)
``live'' in some Hilbert space. This means many things, but for our purposes, we just need to know
there is some ``space'' of \textit{abstract vectors} which have a defined inner product with a certain set of properties.
Every abstract vector in the space can be described in terms of the orthonormal basis which makes up the space.

\begin{itemize}
\item The set of all spin orbitals form a basis for what you might call the one-electron Hilbert space $\mathcal{H}$
\item $n$ tensor products of $\mathcal{H}$ with itself forms an $n$-electron Hilbert space $\mathcal{H}^n$.
        A member of the basis of such a space is a product of spin orbitals (Hartree products)
\item Denote the \textit{antisymmetric subspace} of $\mathcal{H}^n$ as $\mathscr{H}^n$. The basis of this space
    is the set of $n$-electron Slater determinants. All possible Slater determinants for an $n$-electron system live in $\mathscr{H}^n$
    The full CI wavefunction for an $n$-electron system can be constructed from a linear combination of basis vectors in $\mathscr{H}^n$
\end{itemize}

\subsection{Partitioning}
Consider the following \textit{partition} of this $n$-electron antisymmetric Hilbert space $\mathscr{H}^n$ into
a ``$P$'' space and a ``$Q$'' space.
\[ \mathscr{H}^n = \mathscr{H}^n_P \oplus  \mathscr{H}^n_Q \]
where $P$ is the \textit{projection operator} onto some reference determinant
\[P = \ket{\Phi_0}\bra{\Phi_0}  \]
and $Q$ is the \textit{orthogonal complement} of $P$, which projects onto every determinant other than the reference $\Phi_0$
\[Q = 1 - P = \sum_{n \neq 0}  \ket{\Phi_n}\bra{\Phi_n} \]
You can think of this as just dividing your Slater determinant basis into two parts, $P$ and $Q$.
The sum $P + Q$ is equal to unity. This can be most easily seen by thinking of $P$ and $Q$ as two distinct chunks of the resolution of the identity.

\end{document}