\documentstyle[a4wide,12pt]{article}

\begin{document}
\section*{Introduction to numerical projects}

Here follows a brief recipe and recommendation on how to write a report for each
project.
\begin{itemize}
\item Give a short description of the nature of the problem and the eventual
numerical methods you have used.
\item Describe the algorithm you have used and/or developed. Here you may find it convenient
to use pseudocoding. In many cases you can describe the algorithm
in the program itself.

\item Include the source code of your program. Comment your program properly.
\item If possible, try to find analytic solutions, or known limits
in order to test your program when developing the code.
\item Include your results either in figure form or in a table. Remember to
       label your results. All tables and figures should have relevant captions
       and labels on the axes.
\item Try to evaluate the reliabilty and numerical stability/precision
of your results. If possible, include a qualitative and/or quantitative
discussion of the numerical stability, eventual loss of precision etc.

\item Try to give an interpretation of you results in your answers to
the problems.
\item Critique: if possible include your comments and reflections about the
exercise, whether you felt you learnt something, ideas for improvements and
other thoughts you've made when solving the exercise.
We wish to keep this course at the interactive level and your comments can help
us improve it.
\item Try to establish a practice where you log your work at the
computerlab. You may find such a logbook very handy at later stages
in your work, especially when you don't properly remember
what a previous test version
of your program did. Here you could also record
the time spent on solving the exercise, various algorithms you may have tested
or other topics which you feel worthy of mentioning.
\end{itemize}

\section*{Format for electronic delivery of report and programs}
%
The preferred format for the report is a PDF file. You can also
use DOC or postscript formats.
As programming language we prefer that you choose between C/C++ and Fortran90/95.
You could also use Java or Python as programming languages.
Matlab/Maple/Mathematica/IDL are not allowed as programming
languages for the handins, but you can use them to check your results where possible.
The following prescription should be followed when preparing the report:
\begin{itemize}
\item Use Classfronter to hand in your projects, log in  at
blyant.uio.no and choose 'fellesrom fys3150 og fys4150'.
Thereafter you will see an icon to the left with 'hand in' or 'innlevering'.
Click on that icon and go to the given project.
There you can load up the files within the deadline.
\item Upload {\bf only} the report file and the source code file(s) you have developed.
The report file should include all of your discussions and a list of the codes you have developed.
Do not include library files which are available at the course homepage, unless you have
made specific changes to them.
\item Comments  from us on your projects, approval or not, corrections to be made
etc can be found under
your Classfronter domain and are only visible to you and the teachers of the course.

\end{itemize}
Finally,
we do prefer that you work two and two together. Optimal working groups consist of
2-3 students. You can then hand in a common report.

\section*{Project 1, deadline 19 september 12pm (midnight)}

The aim of this project is to get familiar with various matrix operations,
from dynamic memory allocation to the usage of programs in the library
package of the course.
For Fortran users memory handling and most matrix and vector operations
are included in the ANSI standard of Fortran 90/95. For C++ user however,
there are three possible options
\begin{enumerate}
\item Make your own functions for dynamic memory allocation of a
vector and a matrix. Use then the
library package lib.cpp with its header file
lib.hpp for obtaining LU-decomposed matrices, solve linear equations
etc.
\item Use the library package lib.cpp with its header file
lib.hpp which includes a function \verb?matrix? for dynamic memory
allocation. This program package includes all the other functions
discussed during the lectures for solving systems of linear equations,
obatining the determinant, getting the inverse etc.
\item Finally, we provide on the web-page of the course a library package
which uses Blitz++'s classes for array handling. You could then, since
Blitz++ is installed on all machines at the lab, use these classes for handling
arrays.
\end{enumerate}

Your program, whether it is written in C++ or Fortran 90/95, should include
dynamic memory handling of matrices and vectors.
\begin{enumerate}
\item[(a)]
Consider the linear system of equations
%
\begin{eqnarray}
 a_{11}x_1 +a_{12}x_2 +a_{13}x_3 =&w_1 \nonumber \\
a_{21}x_1 + a_{22}x_2 + a_{23}x_3=&w_2 \nonumber \\
a_{31}x_1 + a_{32}x_2 + a_{33}x_3=&w_3. \nonumber
\end{eqnarray}
This can be written in matrix form as
\[
   {\bf Ax}={\bf w}.
\]
Use the included programs for LU decomposition to solve the system of equations
\begin{eqnarray}
 -x_1 +x_2 -4x_3 =&0 \nonumber \\
  2x_1 + 2x_2 =&1 \nonumber \\
3x_1 + 3x_2 + 2x_3=&\frac{1}{2}. \nonumber
\end{eqnarray}
Use first standard Gaussian elimination and compute the result
analytically. Compare thereafter your analytical results with
the numerical ones obtained using the LU programs in the program library.

\item[(b)]
Consider now the $4\times 4$ linear system of equations
%
\begin{eqnarray}
a_{11}x_1 +a_{12}x_2 +a_{13}x_3 + a_{14}x_4=&w_1 \nonumber \\
a_{21}x_1 + a_{22}x_2 + a_{23}x_3 + a_{24}x_4=&w_2 \nonumber \\
a_{31}x_1 + a_{32}x_2 + a_{33}x_3 + a_{34}x_4=&w_3 \nonumber \\
a_{41}x_1 + a_{42}x_2 + a_{43}x_3 + a_{44}x_4=&w_4. \nonumber
\end{eqnarray}
with
\begin{eqnarray}
 x_1 +2x_3 +x_4 =&2 \nonumber \\
4x_1 -9x_2 + 2x_3 + x_4=&14 \nonumber \\
8x_1 + 16x_2 + 6x_3 + 5x_4=&-3 \nonumber \\
2x_1 + 3x_2 + 2x_3 + x_4=&0. \nonumber
\end{eqnarray}
Use again standard Gaussian elimination and compute the result
analytically. Compare thereafter your analytical results with
the numerical ones obtained using the programs in the program library.

\item[(c)] If the matrix $A$ is real, symmetric and positive definite, then
it has  a unique factorization (called Cholesky factorization)
\[
   A = LU = LL^T
\]
where $L^T$ is the upper matrix, implying that
\[
  L^T_{ij} = L_{ji}.
\]
The algorithm for the Cholesky decomposition
is a special case of the general LU-decomposition algorithm.
The algorithm of this decomposition is as follows
\begin{itemize}
\item Calculate the diagonal element $L_{ii}$ by setting up a loop
for $i=0$ to $i=n-1$ (C++ indexing of matrices and vectors)
\begin{equation}
   L_{ii} = \left(A_{ii} - \sum_{k=0}^{i-1}L_{ik}^2\right)^{1/2}.
\end{equation}
%
\item within the loop over $i$, introduce a new loop which goes
from $j=i+1$ to $n-1$ and calculate
%
\begin{equation}
      L_{ji} =
      \frac{1}{L_{ii}}\left(A_{ij}-\sum_{k=0}^{i-1}L_{ik}l_{jk}\right).
\end{equation}
\end{itemize}
For the Cholesky algorithm we have always that $L_{ii} > 0$ and the problem
with exceedingly large matrix elements does not appear and hence there is no
need for pivoting.
Write a function which performs the Cholesky decomposition.
Test your program against the standard LU decomposition by using the matrix
\begin{equation}
 {\bf A} =
      \left( \begin{array}{ccc} 6 & 3 & 2 \\
                                 3 & 2 & 1 \\
                                 2 & 1 & 1
             \end{array} \right)
\end{equation}
\item[(d)] Finally, use the Cholesky method to solve
\begin{eqnarray}
 0.05x_1 +0.07x_2+0.06x_3 +0.05x_4 =&0.23 \nonumber \\
0.07x_1 +0.10x_2 + 0.08x_3 + 0.07x_4=&0.32 \nonumber \\
0.06x_1 + 0.08x_2 + 0.10x_3 + 0.09x_4=&0.33 \nonumber \\
0.05x_1 + 0.07x_2 + 0.09x_3 + 0.10x_4=&0.31 \nonumber
\end{eqnarray}
You can also use the LU codes for linear equations to check the results.
\end{enumerate}

\end{document}


\documentclass[12pt,letterpaper]{article}

%Packages
\usepackage{amsmath}
\usepackage{amsthm}
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage{amscd}
\usepackage{dsfont}
\usepackage{enumerate}
\usepackage{fancyhdr}
\usepackage{mathrsfs}
\usepackage{bbm}
\usepackage{framed}
\usepackage{mdframed}
\usepackage{cancel}
\usepackage{float}
\usepackage{mathtools}
%\usepackage[]{mcode}
\usepackage{graphicx}
\usepackage{tikz}

%Page formatting
\usepackage[letterpaper,voffset=-.5in,bmargin=3cm,footskip=1cm]{geometry}
\setlength{\parindent}{0.0in}
\setlength{\parskip}{0.1in}
\allowdisplaybreaks
\headheight 15pt
\headsep 10pt

% Common Commands
\newcommand\N{\mathbb N}
\newcommand\Z{\mathbb Z}
\newcommand\R{\mathbb R}
\newcommand\Q{\mathbb Q}
\newcommand\lcm{\operatorname{lcm}}
\newcommand\setbuilder[2]{\ensuremath{\left\{#1\;\middle|\;#2\right\}}}
\newcommand\E{\operatorname{E}}
\newcommand\V{\operatorname{V}}
\newcommand\Pow{\ensuremath{\operatorname{\mathcal{P}}}}

\DeclarePairedDelimiter\ceil{\lceil}{\rceil}
\DeclarePairedDelimiter\floor{\lfloor}{\rfloor}

% 22 style
\newcommand\hint[1]{\textbf{Hint}: #1}
\newcommand\note[1]{\textbf{Note}: #1}
\newenvironment{22enumerate}{\begin{enumerate}[a.]\itemsep0em}{\end{enumerate}}
\newenvironment{22itemize}{\begin{itemize}\itemsep0em}{\end{itemize}}
\fancypagestyle{firstpagestyle} {
  \renewcommand{\headrulewidth}{0pt}%
  \lhead{\textbf{CSCI 0220}}%
  \chead{\textbf{Discrete Structures and Probability}}%
  \rhead{Klivans}%
}

\pagestyle{fancyplain}

\newcommand\EX{\mathds{E}}
\newcommand\PR{\mathds{P}}
\newcommand\zlam{Z_\lambda}
\DeclareMathOperator*{\argmin}{arg\,min}

%%%%%%%%%%%%%%%% COMPILE WITH \soltrue or \solfalse %%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\newif\ifsol
\soltrue  % SOLUTIONS
\solfalse % NO SOLUTIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%% solution help %%%%%%%%%%%%%%%%%%%%%
\newcommand{\solu}[2]{ \begin{mdframed} \ifsol #2 \else \vspace{#1} \fi \end{mdframed} }
\newcommand{\solt}{ \ifsol (T) \fi }
\newcommand{\solf}{ \ifsol (F) \fi }
\newcommand{\solm}[1]{\ifsol \textit{(#1)} \fi}

\begin{document}
  \thispagestyle{firstpagestyle}
  \begin{center}
    {\large \textbf{Recitation 4}}

    {\large Induction and Algorithms}
  \end{center}

 \section*{Review}

      We will review the template for an inductive proof.

      For example, say we are trying to prove that $\sum_{i=0}^n i = \frac{n(n+1)}{2}$ is true for all $n \in \N$.

      \begin{enumerate}
        \item Define the predicate $P(n)$.

        \textit{Let $P(n)$ be the predicate that $\sum_{i=0}^n i = \frac{n(n+1)}{2}$.}

        \item Show that the base case is true.

        \textit{We will first show $P(0)$ is true. $\sum_{i=0}^0 i = 0$ and $\frac{0(0+1)}{2} = 0$ so they are equal as needed.}

        \item Assume the inductive hypothesis is true. If you are using stardard induction then you will assume
			$P(k)$ is true for some integer $k$. If you are using strong induction then you will assume $P(i)$ is true for all $i \leq k$.

        \textit{Assume $P(k)$ is true for some integer $k$.}

        \item Show that $P(k+1)$ is true given the inductive hypothesis.

		\textit{We will now show that  $\sum_{i=0}^{k+1} i = \frac{(k+1)(k+2)}{2}$}.

       	\textit{We know that $\sum_{i=0}^{k+1} i = \left( \sum_{i=0}^{k} i \right)+ (k+1)$.}

		\textit{By our inductive hypothesis $\sum_{i=0}^k i = \frac{k(k+1)}{2}$.}

         \textit{Therefore}
		\begin{align*}
			\sum_{i=0}^{k+1} i &= \left( \sum_{i=0}^{k} i \right)+ (k+1) \\
			&=  \frac{k(k+1)}{2} + (k+1) \\
			&= \frac{k(k+1) + 2(k+1)}{2} \\
			&= \frac{(k+1)(k+2)}{2}
		\end{align*}
		\textit{as needed.}\qed

	\subsection*{Warm-up}

      \begin{22enumerate}

      \item
      Prove by induction that for all positive integers $n$, there exists a
      positive integer $m$ such that:
      \[m^2 \leq n < (m + 1)^2\]

	\hint{The inductive step may contain two cases.}

	\solu{17cm}{ Let $P(k)$ denote the property that there exists a positive integer
        $m$ such that $m^2 \leq k < (m + 1)^2$.

        Construct a proof by induction.

        \textbf{Base Case:} Consider $k = 1$.

        Let $m = 1$. Then $m^2 = 1$ and $(m + 1)^2 = 4$, so
        $m^2 \leq k <(m + 1)^2$. Thus $P(1)$ holds.

        \textbf{Inductive Hypothesis:}

        Assume $P(k)$ is true for some positive integer $k$.

        \textbf{Inductive Step:} Consider $n = k+1$.

        By the inductive hypothesis, there exists a positive integer $m$
        such that $m^2 \leq k < (m + 1)^2$.

        There are two cases:
        \begin{22enumerate}

        \item \textbf{Case 1:} $k + 1 < (m + 1)^2$. Then we can define
        $m_* = m$, and it holds that $m_*^2 \leq k + 1 < (m_* + 1)^2$.

        \item \textbf{Case 2:} $k + 1 = (m + 1)^2$. Then we can define
        $m_* = m + 1$. Then $k + 1 = (m + 1)^2 < ((m + 1) + 1)^2$, so
        $k + 1 < (m_* + 1)^2$.
        Since $k + 1 = (m + 1)^2$, $k + 1 = m_*^2$, so it is true that
        $m_*^2 \leq k + 1 < (m_* + 1)^2$.

        \end{22enumerate}

        Because $k < (m + 1)^2$ and $k$ and $m$ are integers, then
        $k + 1 \ngtr (m + 1)^2$, so these are the only two cases.

        In either case, we found an integer $m_*$ such that
        $m_*^2 \leq k + 1 < (m_* + 1)^2$. Thus $P(k + 1)$ is correct.

        Thus $P(k)$ implies $P(k + 1)$.

        Since $P(1)$ is true, and since for all positive integers $k$,
        $P(k)$ implies $P(k+1)$, then by standard induction, $P(n)$ is true for
        all positive integers $n$.

        Thus, for all positive integers $n$, there exists a positive integer
        $m$ such that $m^2 \leq n < (m + 1)^2$.}

		\pagebreak

      \item
      Prove by contradiction that there exists a \textbf{unique} such $m$.

	 \solu{17cm}{        We prove by contradiction. Assume that for some positive integer
        $n$, there exist two unique positive integer solutions
        $m_1 \neq m_2$ such that $m^2 \leq n < (m + 1)^2$. Without loss
        of generality, assume $m_2 > m_1$. Then $m_2 \geq m_1 + 1$.
        Because both sides of the equation are non-negative, we can square
        both sides of this equation to get $m_2^2 \geq (m_1 + 1)^2$.

        By our assumption, we also know that $m_2^2 \leq n$ and that
        $n < (m_1 + 1)^2$. $m_2^2 \leq n < (m_1 + 1)^2$, so
        $m_2^2 < (m_1 + 1)^2$.

        But this is a contradiction, because $m_2^2 \geq (m_1 + 1)^2$. Thus
        our assumption was false.

        Thus, for all positive integers $n$, there can exist only one unique
        integer $m$ such that $m^2 \leq n < (m + 1)^2$.

        From part a, we know that a solution exists for all positive
        integers $n$. Thus, for all positive integers $n$, there exists
        exactly one unique integer $m$ such that $m^2 \leq n < (m + 1)^2$.}

      \end{22enumerate}

	\textbf{Checkpoint - Call a  TA over}

    \end{enumerate}

	\section*{Section Lesson - Algorithms}

	\subsection*{Why does induction work?}

	You can think of induction as a ladder. We want to prove that we can reach every step of the ladder.

	The base case says that we can reach the first step of the ladder.

	The inductive hypothesis says that we can get to the $k^{\text{th}}$ step of the ladder.

	The inductive step says that if we can get to the $k^{\text{th}}$ step of the ladder, then we can get to step $k+1$.

	Therefore, once we get to step 1, we can get to step 2. Once we get to step 2, we can get to step 3. And so on for all steps of the ladder.

	\subsection*{Induction for algorithms}

	Induction can also be used to prove the correctness of algorithms. An algorithm is simply a series of steps.

	Consider the following $SORT$ algorithm which operates on a list of length $n$.
	\begin{enumerate}
		\item If $n=1$ do nothing as the list is already sorted.
		\item Find the smallest element in the list and remove it.
		\item Run the $SORT$ algorithm on the remaining $n-1$ elements.
		\item Put the smallest element at the begining of the list.
	\end{enumerate}

	We can now prove that $SORT$ correctly sorts a list of size $n$ for $n \geq 1$.

        \textit{Base case: $SORT$ does nothing on a list of size 1, which is already sorted.}

        \textit{Inductive hypothesis: Assume $SORT$ correctly sorts a list of size $k$.}

	   \textit{Inductive step: We will now show that $SORT$ correctly sorts a list of size $k+1$. In step 3, we are left with a list of size $k$. By our inductive hypothesis, $SORT$ correctly sorts this sublist. Therefore, when we put the smallest element (which we have removed) at the begining, our list is completely sorted as needed.}\qed

Your turn.

\textbf{Given a stack of pancakes, you can stick your spatula in between any two
pancakes, and flip the stack of pancakes above the spatula upside-down. Find an algorithm
to sort $n$ pancakes from largest to smallest, using at most $2n$ flips. Prove it is correct.}

\solu{18cm}{The algorithm is to always find the largest pancake, flip it to the top, then flip the whole stack so the largest pancake is on the bottom. After this proceed recursively on all but the largest pancake. The proof for why this is correct is identical to the proof for $SORT$ given above.}

\textbf{Checkpoint - Call a TA over}

\pagebreak

\textbf{Consider the following inductive proof}

Claim: All $n$ people in the room have the same eye color.
\begin{proof}

Base case: When $n=1$ clearly everyone in the room has the same eye color as there is only one person in the room.

Inductive Hypothesis: Assume that in a room of $k$ people, everyone in the room has the same eye color.

Inductive Step: We will now show that in a room of $k+1$ people everyone has the same eye color.

We know from our inductive step that the first $k$ people in the room have the same eye color, and that the last $k$ people in the room have the same eye color. Since there is some overlap between the first $k$ people and the last $k$ people, everyone in the room must have the same eye color.
\end{proof}

\textbf{Can you find the flaw in this proof?}

\solu{10cm}{The inductive step does not work for 2 people.}

\pagebreak

\textbf{Challlenge 1:}
100 dragons are sitting in a circle so that every dragon can see every other dragon.

Every dragon has green eyes, but the dragons don't know this. No dragon knows its own eye color, and the dragons cannot talk.

Ben comes and tells the circle of dragons that at least one of them has green eyes.

If a dragon knows it has green eyes, it will turn into a human at midnight.

Prove that on night 100, all dragons will turn into humans at once.

\hint{Use induction! What is the base case? Ignore the number 100 and instead consider $n$ dragons and show they turn into humans on the $n^{\text{th}}$ night.}

\solm{If there is only one dragon, it takes her one night to turn into a human. Now assume it takes $k$ nights for $k$ dragons. Consider the case where there is $k+1$ dragons and consider what one individual dragon is thinking. This one dragon sees $k$ dragons with green eyes. Therefore, if this dragon does not have green eyes, she would expect the other dragons to turn into humans after $k$ night since they can see her. Since they don't, this dragon realizes that she also has green and turns into a dragon on night $k+1$.}

\vspace{6cm}
\textbf{Challenge 2:}
We say that an infinite set $S$ is countable if there exists a bijection from $\N$ to $S$. Giventhat $\N \times \N$ is countable, prove by induction that $\N^k$ is countable where $k \in \N$.

\solm{$\N^k$ is countable so there exists a bijection $f_k$. We can now make a bijection $g_{k+1}$ from $\N^{k+1}$ to $\N \times \N$. $g_{k+1} ((x_1,...,x_{k+1})) = (f_k(x_1,...,x_k),x_{k+1})$.}

\end{document}


%\subsection{DFT-based transfer integrals using DIPRO}
\label{sec:dft}
\index{electronic coupling!DFT}
% While the use of the semiempirical ZINDO method provides an efficient on-the-fly technique to determine electronic coupling elements, it is not generally applicable to all systems. For instance, its predictive capacity with regards to atomic composition and localization behavior of orbitals within more complex structures is reduced. Moreover, transition- or semi-metals are often not even parametrized. In this case, {\it ab-initio} based approaches, e.g., density-functional theory can remedy the situation~\cite{huang_intermolecular_2004,huang_validation_2005,valeev_effect_2006,yin_balanced_2006,yang_theoretical_2007,baumeier_density-functional_2010}.

The calculation of one electronic coupling element requires the overlap matrix of atomic orbitals $\matr{\mathcal{S}}$, the expansion coefficients for monomer $\vctr{\boldsymbol{\lambda}}_{(k)} = \{ \lambda_\alpha^{(k)}\}$ and dimer orbitals $\vctr{D}_{(n)} = \{ D^{(n)}_{\alpha} \}$, as well as the orbital energies $E_{n}$ of the dimer are required as input. In practical situations, performing self-consistent quantum-chemical calculations for each individual monomer and one for the dimer to obtain this input data is extremely demanding. Several simplifications can be made to reduce the computational effort, such as using non-Counterpoise basis sets for the monomers (thereby decoupling the monomer calculations from the dimer run) and performing only a single SCF step in a dimer calculation starting from an initial guess formed from a superposition of monomer orbitals. This ''noCP+noSCF'' variant of \dipro is shown in \fig{dipro_scheme}(a) and recommended for production runs.
A detailed comparative study of the different variants can be found in~\cite{baumeier_density-functional_2010}.

The code currently contains supports evaluation of transfer integrals from quantum-chemical calculations performed with the \gaussian, \turbomole, and \nwchem packages. The interfacing procedure consists of three main steps: generation of input files for monomers and dimers, performing the actual quantum-chemical calculations, and calculating the transfer integrals.

\subsubsection{Monomer calculations}
\label{sec:edft}
First, \slink{sec:segments}{hopping sites} and a \slink{sec:neighborlist}{neighbor list} need to be generated from the atomistic topology and trajectory and written to the \sqlstate file. Then the parallel \calc{edft} \calculator manages the calculation of the monomer properties required for the determination of electronic coupling elements. Specifically, the individual steps it performs are:
%
\begin{enumerate}
\item Creation of a job file containing the list of molecules to be calculated with DFT
\votcacommand{Writing job file for \calc{edft}}{\ctpparallel \opt \xmloptions \sql \sqlstate \exe \calc{edft} \job \wrt }
\item Running of all jobs in job file
\votcacommand{Running all \calc{edft} jobs}{\ctpparallel \opt \xmloptions \sql \sqlstate \exe \calc{edft} \job \run }
which includes
\begin{itemize}
\item creating the input files for the DFT calculation (using the package specified in \xmloptions) in the directory
\begin{verbatim}
OR_FILES/package/frame_F/mol_M
\end{verbatim}
where {\tt F} is the index of the frame in the trajectory, {\tt M} is the index of a molecule in this frame,
\item executing the DFT run, and
\item after completion of this run, parsing the output (number of electrons, basis set, molecular orbital expansion coefficients), and saving it in compressed form to
\begin{verbatim}
 OR_FILES/molecules/frame_F/molecule_M.orb
\end{verbatim}
\end{itemize}
\end{enumerate}

\subsubsection{Calculating the transfer integrals}
\label{sec:idft}
After the momomer calculations have been completed successfully, the respective runs for dimers from the neighborlist can be performed using the parallel \calc{idft} \calculator, which manages the DFT runs for the hopping pairs and determines the coupling element using \dipro. Again, several steps are required:
\begin{enumerate}
\item Creation of a job file containing the list of pairs to be calculated with DFT
\votcacommand{Writing job file for \calc{idft}}{\ctpparallel \opt \xmloptions \sql \sqlstate \exe \calc{idft} \job \wrt }
\item Running of all jobs in job file
\votcacommand{Running all \calc{idft} jobs}{\ctpparallel \opt \xmloptions \sql \sqlstate \exe \calc{idft} \job \run }
which includes
\begin{itemize}
\item creating the input files (including the merged guess for a noSCF calculation, if requested) for the DFT calculation (using the package specified in \xmloptions) in the directory
\begin{verbatim}
OR_FILES/package/frame_F/pair_M_N
\end{verbatim}
where {\tt M} and {\tt N} are the indices of the molecules in this pair,
\item executing the DFT run, and
\item after completion of this run, parsing the output (number of electrons, basis set, molecular orbital expansion coefficients and energies, atomic orbital overlap matrix), and saving the pair information in compressed form to
\begin{verbatim}
 OR_FILES/pairs/frame_F/pair_M_N.orb
\end{verbatim}
\item loading the monomer orbitals from the previously saved {\tt *.orb files}.
\item calculating the coupling elements and write them to the job file
\end{itemize}
\item Reading the coupling elements from the job file and saving them to the \sqlstate file
\votcacommand{Saving \calc{idft} results from job file to \sqlstate}{\ctpparallel \opt \xmloptions \sql \sqlstate \exe \calc{idft} \job \rd }
\end{enumerate}


% Define document class
\documentclass[twocolumn]{aastex63}
\DeclareRobustCommand{\Eqref}[1]{Eq.~\ref{#1}}
\DeclareRobustCommand{\Figref}[1]{Fig.~\ref{#1}}
\DeclareRobustCommand{\Tabref}[1]{Tab.~\ref{#1}}
\DeclareRobustCommand{\Secref}[1]{Sec.~\ref{#1}}
\newcommand{\todo}[1]{{\large $\blacksquare$~\textbf{\color{red}[#1]}}~$\blacksquare$}
% \usepackage{cuted}
\usepackage{flushend}
\usepackage{amsmath}
\graphicspath{{./figures/}}

\begin{document}

% Title
\title{Pair-instability mass loss for top-down compact object mass calculations}

\author[0000-0002-6718-9472]{M.~Renzo}
\affiliation{Center for Computational Astrophysics, Flatiron Institute, New York, NY 10010, USA}
\affiliation{Department of Physics, Columbia University, New York, NY 10027, USA}

\author[0000-0002-8717-6046]{D.~D.~Hendriks}
\affiliation{Department of Physics, University of Surrey, Guildford, GU2 7XH, Surrey, UK}

\author[0000-0001-5484-4987]{L.~A.~C.~van~Son}
\affiliation{Center for Astrophysics $|$ Harvard $\&$ Smithsonian,60 Garden St., Cambridge, MA 02138, USA}
\affiliation{Anton Pannekoek Institute for Astronomy, University of Amsterdam, Science Park 904, 1098XH Amsterdam, The Netherlands}
\affiliation{Max-Planck-Institut für Astrophysik, Karl-Schwarzschild-Straße 1, 85741 Garching, Germany}

\author[0000-0003-3441-7624]{R.~Farmer}
\affiliation{Max-Planck-Institut für Astrophysik, Karl-Schwarzschild-Straße 1, 85741 Garching, Germany}

\begin{abstract}
  \noindent
  Population synthesis relies on semi-analytic formulae to determine
  masses of compact objects from the (helium or carbon-oxygen) cores
  of collapsing stars. Such formulae are combined across mass ranges
  that span different explosion mechanisms, potentialy introducing
  artificial features in the compact object mass distribution. Such
  artifacts impair the interpretation of gravitational-wave
  observations. We propose a ``top-down'' remnant mass prescription
  where we remove mass from the star for each possible mass-loss
  mechanism, instead of relying on the fallback onto a
  ``proto-compact-object'' to get the final mass. For one of these
  mass-loss mechanisms, we fit the metallicity-dependent mass lost to
  pulsational-pair instability supernovae from numerical
  simulations. By imposing no mass loss in the absence of pulses, our
  approach recovers the existing compact object masses at the low mass
  end and ensures continuity across the
  core-collapse/pulsational-pair-instability regime. % Our remnant mass
  % prescription can be extended
  % to include other mass-loss mechanisms at the final collapse.\\
\end{abstract}

\section{Introduction}

Stellar and binary population synthesis calculations are necessary to
predict event rates and population statistics of astrophysical
phenomena, including those involving neutron stars (NS) and
black holes (BH). Typically, at the end of the evolution (carbon
depletion) the mass of the core is mapped to a compact object mass, using a
$M_\mathrm{comp.\ obj}\equiv M_\mathrm{comp.\ obj}(M_\mathrm{core})$
informed by core-collapse (CC) simulations (e.g., \citealt{fryer:12,
  spera:15, mandel:20, couch:20}, see also \citealt{zapartas:21,
  patton:21}) and/or (pulsational) pair instability (PPI) simulations
(e.g., \citealt{belczynski:16, woosley:17, spera:17, stevenson:19,
  marchant:19, farmer:19, breivik:20, renzo:20csm, costa:21}).

The most commonly adopted algorithms to obtain compact object masses
in the CC regime are the ``rapid'' and ``delayed'' prescriptions of
\cite{fryer:12}. In both cases, the compact object is built from the
``bottom-up'', starting from a proto-NS mass and adding the amount of
fallback expected in the (possibly failed) explosion. However, the
proto-NS mass and information about the core structure relevant to
calculate the fallback are usually not available
\citep[e.g.,][]{patton:20}. Instead, the total final mass of the star
is arguably easier to constrain in population synthesis models.

At the transition between CC and PPI (roughly at carbon-oxygen cores
of $\sim{}35\,M_\odot$, \citealt{woosley:17, marchant:19, farmer:19,
  renzo:20csm, costa:21}), a mismatch between commonly adopted fitting
formulae exists, and impairs the
interpretation of gravitational-wave data \citep[as pointed out in
Fig.~5 of][]{vanson:21}. While it is possible that the BH mass
function is discontinuous at the onset of the PPI regime (e.g.,
\citealt{renzo:20conv,costa:21}, Hendriks et al., in prep.), the
location and amplitude of a putative discontinuity should not be
governed by a mismatch between the fitting formulae.

\section{Top-down compact object masses}

In contrast with the ``bottom up'' approach of \cite{fryer:12}, we
propose a ``top-down'' compact object mass calculation. Starting from
the total stellar mass, we remove the amount of mass lost due to all
of the processes associated with the (possibly failed) explosion:

\begin{widetext}
  \begin{equation}
    \label{eq:mass}
      M_\mathrm{comp.\ obj} =
      M_\mathrm{pre-CC} - \left(\Delta M_\mathrm{SN} + \Delta M_{\nu, \mathrm{core}} + \Delta M_\mathrm{env} + \Delta M_\mathrm{PPI} + \cdots \right)
  \end{equation}
\end{widetext}

% where all masses are in $M_\odot$,
where $M_\mathrm{pre-CC}$ is the total mass at the onset of CC, and
each term in parenthesis corresponds to a potential mass-loss
mechanism: $\Delta M_\mathrm{SN}$ for the CC ejecta,
$\Delta M_{\nu, \mathrm{core}}$ the change in gravitational mass of
the core due to the neutrino losses, $\Delta M_\mathrm{env}$ the loss
of the envelope that can occur even in red supergiant ``failed''
core-collapse due to % the change in
% gravitational mass corresponding to
$\Delta M_{\nu, \mathrm{core}}$
\citep{nadezhin:80, lovegrove:13, piro:13, fernandez:18, ivanov:21},
and $\Delta M_\mathrm{PPI}$ the pulsational mass loss due to
pair-instability. Each term may be a function of the progenitor
properties, and may be theoretically or observationally informed
(e.g., $\Delta M_\mathrm{SN}$ could be derived from the light curves of a
large sample of observed SNe). \Eqref{eq:mass} can be extended by
adding additional mass-loss mechanisms in the parenthesis (e.g., disk
winds).

In the CC regime, the previous approach from \cite{fryer:12} can be recovered by setting
$\Delta M_\mathrm{SN} + \Delta M_{\nu, \mathrm{core}} = M_\mathrm{pre-CC} - M_\mathrm{comp.\ obj}^\mathrm{Fryer+12}$,
where the last term is the compact object mass as predicted by
\cite{fryer:12} and ignoring the other mass loss terms,
such as $\Delta M_\mathrm{PPI}$ and $\Delta M_\mathrm{env}$.

\begin{figure}[tbp]
    \begin{centering}
      \includegraphics[width=0.75\linewidth]{fit_DM_PPI.pdf}
      \caption{Each panel shows our fitting formula \Eqref{eq:fit} for
        the PPI induced mass-loss as a function of carbon-oxygen core
        mass at each metallicity $Z$. The crosses show the values from
        Tab.~1 \cite{farmer:19}.}
        % This label tells showyourwork that the script `figures/fit_DM_PPI.py'
        % generates the PDF included above
        \label{fig:fit_DM_PPI}
    \end{centering}
\end{figure}

\section{New fit for PPI ejecta}

Imposing $\Delta M_\mathrm{PPI}=0$ at the edge of the PPI regime,
\Eqref{eq:mass} produces a smooth BH mass distribution.
\Eqref{eq:fit} provides a fit (in $M_\odot$ units) to naked helium
star models from \cite{farmer:19} for
$\Delta M_\mathrm{PPI} \equiv \Delta M_\mathrm{PPI}(M_\mathrm{CO},Z)$.
While the fit of \cite{farmer:19} provides the BH mass after PPI, this
is only an estimate because of other mass loss processes that might
occur at CC \citep[e.g.,][]{renzo:20csm, powell:21, rahman:22}. Here,
we fit the mass removed by PPI (crosses in \Figref{fig:fit_DM_PPI}),
which is what is directly computed in \cite{farmer:19}.

% Each panel of \Figref{fig:fit_DM_PPI} shows
% % The dashed curves in each panel of \Figref{fig:fit_DM_PPI} show the
% % fit \Eqref{eq:fit} for each
% one metallicity computed in
% \cite{farmer:19}.
We neglect the (weak) metallicity dependence of the minimum core mass
for PPI, and we fit the data for initial helium core masses between
$38-60\,M_\odot$.  We emphasize that \cite{farmer:19} only simulated
helium cores. In the presence of a H-rich envelope at the onset of
PPI, if it is extended and red it can be easily removed by the first
pulse \citep[][]{woosley:17,renzo:20csm}. Thus the H-rich mass of red
supergiants should be added to the $\Delta M_\mathrm{PPI}$ provided
here. It is unclear what occurs in cases when the envelope is compact
and blue \citep[e.g.,][]{dicarlo:19, renzo:20merger, costa:21}.

\input{fit_DM_PPI.tex} %% generated by src/figures/fit_DM_PPI.py

The mass lost in PPI is sensitive to convection
\citep{renzo:20conv} and nuclear physics \citep{farmer:19,
  farmer:20, costa:21, woosley:21, mehta:21}, which can introduce
uncertainties up to $\sim{}20\%$ on the maximum BH mass. The accuracy
of our fit is comparable to these uncertainties.

\vspace*{-10pt}

% \section*{Acknowledgements}
% MR is grateful to R.~Luger for help with showyourwork
% \citep{luger:21}. The code associated to this paper is publicly
% available at
% \url{https://github.com/mathren/top_down_compact_obj_mass} and the
% input data are loaded from \url{https://zenodo.org/record/3346593}.  LvS
% acknowledges partial financial support from the National Science
% Foundation under Grant No. (NSF grant number 2009131), the Netherlands
% Organisation for Scientific Research (NWO) as part of the Vidi
% research program BinWaves with project number 639.042.728 and the
% European Union’s Horizon 2020 research and innovation program from the
% European Research Council (ERC, Grant agreement No. 715063).

\newpage
\bibliography{./top_down_comp_obj_mass.bib}
\end{document}

%%% Local Variables:
%%% mode: latex
%%% TeX-master: t
%%% End:


% !TEX TS-program = pdflatex
% !TEX encoding = UTF-8 Unicode

% This is a simple template for a LaTeX document using the "article" class.
% See "book", "report", "letter" for other types of document.

\documentclass[11pt]{article} % use larger type; default would be 10pt

\usepackage[utf8]{inputenc} % set input encoding (not needed with XeLaTeX)

%%% Examples of Article customizations
% These packages are optional, depending whether you want the features they provide.
% See the LaTeX Companion or other references for full information.

%%% PAGE DIMENSIONS
\usepackage{geometry} % to change the page dimensions
\geometry{a4paper} % or letterpaper (US) or a5paper or....
\geometry{margin=1in} % for example, change the margins to 2 inches all round
% \geometry{landscape} % set up the page for landscape
%   read geometry.pdf for detailed page layout information

\usepackage{graphicx} % support the \includegraphics command and options
\usepackage{amsmath}
\usepackage{amsfonts}
% \usepackage[parfill]{parskip} % Activate to begin paragraphs with an empty line rather than an indent

%%% PACKAGES
\usepackage{booktabs} % for much better looking tables
\usepackage{array} % for better arrays (eg matrices) in maths
\usepackage{paralist} % very flexible & customisable lists (eg. enumerate/itemize, etc.)
\usepackage{verbatim} % adds environment for commenting out blocks of text & for better verbatim
\usepackage{subfig} % make it possible to include more than one captioned figure/table in a single float
% These packages are all incorporated in the memoir class to one degree or another...

%%% HEADERS & FOOTERS
\usepackage{fancyhdr} % This should be set AFTER setting up the page geometry
\pagestyle{fancy} % options: empty , plain , fancy
\renewcommand{\headrulewidth}{0pt} % customise the layout...
\lhead{}\chead{}\rhead{}
\lfoot{}\cfoot{\thepage}\rfoot{}

%%% SECTION TITLE APPEARANCE
\usepackage{sectsty}
\allsectionsfont{\sffamily\mdseries\upshape} % (See the fntguide.pdf for font help)
% (This matches ConTeXt defaults)

%%% ToC (table of contents) APPEARANCE
\usepackage[nottoc,notlof,notlot]{tocbibind} % Put the bibliography in the ToC
\usepackage[titles,subfigure]{tocloft} % Alter the style of the Table of Contents
\renewcommand{\cftsecfont}{\rmfamily\mdseries\upshape}
\renewcommand{\cftsecpagefont}{\rmfamily\mdseries\upshape} % No bold!

%%% END Article customizations

%%% The "real" document content comes below...

\title{Homework 2}
\author{Alireza Shafaei\\78428133}
%\date{} % Activate to display a given date or no date (if empty),
         % otherwise the current date is printed

\begin{document}
\maketitle

\section*{Problem 1}
Let G(X) be the woman that is paired with man X by the Gale-Shapley proposal algorithm. Prove that there is no stable pairing P such that X prefers P(X) (his partner in pairing P) to G(X).\\
\textbf{Proof.}
Let's say there's a stable pairing $P$ such that $X$ prefers $P(X)$ to $G(X)$. This means $P(X)$ has to appear before $G(X)$ in $X$'s preference list. If so, according to the Gale-Shapley proposal algorithm, $X$ must've proposed to $P(X)$ before $G(X)$. Given that the final stable marriage of $X$ is $G(X)$, then there must exist a $Y$ such that $P(X)$ preferes to $X$, and $P(X)$ is the first available preference in $Y$'s list, resulting in a break up of $X$ and $P(X)$; thus no such stable marriage $P$ can exist.

\section*{Problem 2}
Prove that the expectation of a sum of random variables is the sum of the expectation of these random variables.\\
\textbf{Proof.} I demonstrate this feature using two random variables. Through induction, it could be generalized for $n$ random variables.

\begin{gather}
\mathbb{E}[X+Y] = \sum_{\omega_1 \in \Omega} \sum_{\omega_2 \in \Omega} (X(\omega_1)+Y(\omega_2))\mathbb{P}(\omega_1,\omega_2) \\
\Rightarrow \mathbb{E}[X+Y] = 	\sum_{\omega_1 \in \Omega}X(\omega_1) \sum_{\omega_2 \in \Omega}\mathbb{P}(\omega_1,\omega_2) +
					\sum_{\omega_2 \in \Omega}Y(\omega_2) \sum_{\omega_1 \in \Omega}\mathbb{P}(\omega_1,\omega_2) \\
\Rightarrow \mathbb{E}[X+Y] = 	\sum_{\omega_1 \in \Omega}X(\omega_1) \sum_{\omega_2 \in \Omega}\mathbb{P}(\omega_1|\omega_2)\mathbb{P}(\omega_2) +
					\sum_{\omega_2 \in \Omega}Y(\omega_2) \sum_{\omega_1 \in \Omega}\mathbb{P}(\omega_2|\omega_1)\mathbb{P}(\omega_1)\\
\Rightarrow \mathbb{E}[X+Y] = 	\sum_{\omega_1 \in \Omega}X(\omega_1) \mathbb{P}(\omega_1)+
					\sum_{\omega_2 \in \Omega}Y(\omega_2) \mathbb{P}(\omega_2)\\
\Rightarrow \mathbb{E}[X+Y] = 	\mathbb{E}[X]+\mathbb{E}[Y]
\end{gather}

\section*{Problem 3}
 Prove that the expectation of a product of independent random variables is the product of the expectation of these random variables.\\
\textbf{Proof.} I demonstrate this feature using two independent random variables. Through induction, it could be generalized for $n$ independent random variables.
\begin{gather}
\mathbb{E}[XY] = \sum_{\omega_1 \in \Omega} \sum_{\omega_2 \in \Omega} X(\omega_1)Y(\omega_2)\mathbb{P}(\omega_1,\omega_2) \\
X \perp Y \Rightarrow \mathbb{E}[XY] = \sum_{\omega_1 \in \Omega} \sum_{\omega_2 \in \Omega} X(\omega_1)Y(\omega_2)\mathbb{P}(\omega_1)\mathbb{P}(\omega_2) \\
\Rightarrow \mathbb{E}[XY] = \sum_{\omega_1 \in \Omega} X(\omega_1)\mathbb{P}(\omega_1)\sum_{\omega_2 \in \Omega} Y(\omega_2)\mathbb{P}(\omega_2) \\
\Rightarrow \mathbb{E}[XY] = \mathbb{E}[X]\mathbb{E}[Y]
\end{gather}

\section*{Problem 4}
Use the previous two results to prove that the variance of a sum of pairwise independent random variables is the sum of the variances of these random variables.\\
\textbf{Proof.} I demonstrate this feature using two independent random variables. Through induction, it could be generalized for $n$ pairwise independent random variables.
\begin{gather}
Var[X+Y] = \mathbb{E}[(X+Y)^2] - (\mathbb{E}[X+Y])^2\\
\Rightarrow Var[X+Y] = \mathbb{E}[X^2+Y^2+2YX] - (\mathbb{E}[X]+\mathbb{E}[Y])^2\\
\Rightarrow Var[X+Y] = \mathbb{E}[X^2]+\mathbb{E}[Y^2]+\mathbb{E}[2YX] - (\mathbb{E}[X])^2-(\mathbb{E}[Y])^2-(2\mathbb{E}[X]\mathbb{E}[Y])\\
\Rightarrow Var[X+Y] = \mathbb{E}[X^2]+\mathbb{E}[Y^2]+2\mathbb{E}[Y]\mathbb{E}[X] - (\mathbb{E}[X])^2-(\mathbb{E}[Y])^2-(2\mathbb{E}[X]\mathbb{E}[Y])\\
\Rightarrow Var[X+Y] = \mathbb{E}[X^2]- (\mathbb{E}[X])^2+\mathbb{E}[Y^2]-(\mathbb{E}[Y])^2\\
\Rightarrow Var[X+Y] = Var[X]+Var[Y]
\end{gather}

\section*{Problem 4}
Suppose I have a sequence of $n$ different numbers. I reorder the sequence randomly (each ordering equally likely) and give you the numbers one at a time in this random order. You are interested in determining the maximum number in the sequence.

\begin{itemize}
	\item An obvious approach is to keep the maximum of the numbers given so far, updating this maximum as needed. What is the expected number of times you update the maximum (as a function of $n$)?\\
\textbf{Answer.} Let's say we have seen $i$ numbers so far, the probability that $(i+1)_{th}$ number is the biggest in a series of $i+1$ numbers will be $\frac{1}{i+1}$, since the biggest number could be any of $i+1$ numbers. Let $X_i$ denote whether we updated upon seeing $i_{th}$ number. The expected value of updates will be calculated as follows:

\begin{gather}
\mathbb{E}[X_i] = 1.\frac{1}{i}+0.\frac{i-1}{i}=\frac{1}{i}\\
Y = X_1+X_2+X_3+\ldots+X_n\\
\mathbb{E}[Y]=\sum_{i=1}^{n}\mathbb{E}[X_i] = \sum_{i=1}^{n}\frac{1}{i} = H_n
\end{gather}
So the answer will be $H_n$.

\item Suppose after you see each number, I ask ``Is this the maximum of all n numbers?'' If you say ``no'' then I give you the next number. If you say ``yes'' then you win if the number truly is the maximum number in the sequence, otherwise you lose.\\
Describe an algorithm for you to follow that results in a probability of winning that is at least 1/4. Note that your algorithm knows n from the start.\\
\textbf{Answer.} If we have seen $i$ numbers so far, it means there are $n-i$ numbers that we haven't seen. On updating max with $i_{th}$ number, the probability of $i_{th}$ number being  the biggest number will be $\frac{i}{n}$. Let's call probability of wining after update on $i_{th}$ number, $P_{i}$, we'd have:

\begin{gather}
	P_{i} = \frac{i}{n}\\
	P_i \geq \frac{1}{4} \Rightarrow \frac{i}{n} \geq \frac{1}{4}\\
	\Rightarrow i \geq \frac{n}{4}
\end{gather}
Meaning that after seeing at least $n/4$ numbers, if the maximum was updated, we should say yes. In other words, if an update on max occured after seeing at least $n/4$ numbers, we're at least $1/4$ sure that this is the biggest number.
\end{itemize}

\end{document}


\section{Reaction initial state simulation.}

\subsection{Allowed projectiles and bombarding energy range for interaction
with nucleon and nuclear targets.}
\hspace{1.0em}
The GEANT4 kinetic model is capable to predict final states (produced
hadrons
which belong to the pseudoscalar meson nonet and the baryon (antibaryon)
octet) of reactions on nucleon and nuclear targets
with a large variety of hadron (the same types as final state hadrons) and
nuclear projectiles. The allowed bombarding kinetic energy in
the hadron--nucleon,
  hadron--nucleus and nucleus--nucleus collisions
 is recommended to be more than
 20 MeV in the laboratory frame.
  The upper limit of initial
  kinetic energy is approximately $10$ GeV per initial particle.

  This model is also able to predict
final states in the photon--nucleon and photon--nucleus inelastic
collisions  as well as the nuclear absorption of the
stopping $\pi^{-}$, $K^{-}$ and $\bar{p}$.
 The last cases are described in the
separate chapters.

  There are also needs
 to simulate hadron
kinetics after the "parton string" stage of nuclear interaction, taking
account secondary hadron rescatterings.

\subsection{MC initialization procedure for a nucleus}
\hspace{1.0em}The initialization of each nucleus, consisting from $A$
nucleons and $Z$ protons ($N=A-Z$ neutrons)
with coordinates $\mathbf{r}_i$ and momenta
$\mathbf{p}_i$, where $i = 1,2,...,A$ is performed.
For the hadron kinetic model the MC initialization procedure for a nucleus is
similar as for the
parton string model except of some peculiarities, which are taken into
account:
\begin{itemize}
\item Nucleon radii $r_i$ are selected randomly in the rest of nucleus according
to proton or neutron density $\rho(r_i)$.
For heavy nuclei with $A > 16$ \cite{GLMP91} normalized on unity
nucleon density is
\begin{equation}
\label{KNIS1}\rho(r_i) =
 \frac{\rho_0}{1 + \exp{[(r_i - R)/a]}}
\end{equation}
where
\begin{equation}
\label{KNIS2}\rho_0 \approx \frac{3}{4\pi R^3}(1+\frac{a^2\pi^2}{R^2})^{-1}.
\end{equation}
Here $R=r_0 A^{1/3}$ \ fm and $r_0=1.16(1-1.16A^{-2/3})$ \ fm and $a
\approx 0.545$ fm.  For light nuclei with $A < 17$ normalized on unity
nucleon density is
given by a harmonic oscillator shell model \cite{Elton61}, e. g.
\begin{equation}
\label{KNIS3} \rho(r_i) = (\pi R^2)^{-3/2}\exp{(-r_i^2/R^2)},
\end{equation}
where $R^2 = 2/3<r^2> = 0.8133 A^{2/3}$ \ fm$^2$ or
\begin{equation}
\label{KNIS4} \rho(r_i) =
\frac{4}{\pi^{3/2}R^3}[1+\frac{A-4}{6}(\frac{r_i}{R})^2]
\exp{(-r_i^2/R^2)},
\end{equation}
where
\begin{equation}
\label{KNIS5} R^2=(\frac{5}{2}-\frac{4}{A})^{-1}(<r^2_{ch}>_{A}-
<r^2_{ch}>_{p})
\end{equation}
The mean squared charge radii of the nucleus $<r^2_{ch}>_{A}$ and proton
$<r^2_{ch}>_{p}$ are taken from the measurements of lepton-nucleus
scattering experiments \cite{BJ77}.  To take into account nucleon
repulsive core it is assumed that internucleon distance $d > 0.8$ \ fm;

\item The initial momenta of the nucleons are randomly choosen between $0$ and
$p^{max}_F$, where
the maximal momenta of nucleons (in the local Thomas-Fermi
approximation \cite{DF74}) depends from
the proton or neutron density $\rho_{Z,N}$ according to
\begin{equation}
\label{KNIS6} p^{max}_F = \hbar c(3\pi^2 \rho_{Z,N})^{1/3}
\end{equation}
with $\hbar c = 197.327$ MeVfm.

\item To obtain coordinate and momentum components, it
 is assumed that nucleons are distributed isotropicaly in configuration
 and momentum spaces;

We assume \cite{URQMD97}
that nucleons are not points in configuration space
and they are represented by Gaussian shaped density distributions (c = 1):
\begin{equation}
\label{KNIS7}\phi({\bf x_i}, t) = (\frac{2\alpha}{\pi})^{3/4}
\exp{\{-\alpha ({\bf x_i}
- {\bf r_i} (t))^2 + \frac{i}{\hbar}{\bf p_i} (t) {\bf x_i}\}},
\end{equation}
where $\alpha=0.25$ \ fm$^{-2}$ is a model parameter.
It gives us a possibility to take into account
the Pauli blocking (the Pauli blocking procedure is decsribed below),
i. e. if the phase space of $i$-th nucleon is already occupied by other
nucleons, its sampling is deserted;

\item Then perform shifts of nucleon coordinates ${\bf r_i^{\prime}}
= {\bf r_i} - 1/A \sum_i {\bf r_i}$ and momenta ${\bf p_i^{\prime}}
= {\bf p_i} - 1/A \sum_i {\bf p_i}$
of nucleon momenta. The nucleus must be centered in configuration space around
$\mathbf{0}$, \textit{i. e.} $\sum_i {\mathbf{r}_i} = \mathbf{0}$ and
 the nucleus must be at rest, i. e. $\sum_i {\bf p_i} = \bf 0$ and
$\sum_i {\bf r_i} \times {\bf p_i}={\bf 0}$;

\item We compute energy per nucleon $e = E/A = m_{N} + B(A,Z)/A$,
where $m_N$ is nucleon mass and the nucleus binding energy $B(A,Z)$ is given
by the Bethe-Weizs\"acker formula\cite{BM69}:
\begin{equation}
\begin{array}{c}
\label{KNIS8} B(A,Z) = \\
= -0.01587A + 0.01834A^{2/3} + 0.09286(Z- \frac{A}{2})^2 +
0.00071 Z^2/A^{1/3},
\end{array}
\end{equation}
 and find the effective mass of each nucleon $m^{eff}_i =
\sqrt{(E/A)^2 - p^{2\prime}_i}$.
\end{itemize}

\subsection{Lorentz boost of nucleon longitudinal momenta and energies.}

\hspace{1.0em}In the case of fast moving nucleus with initial momentum
per nucleon ${\bf P_0}= \{0, 0, P_{z0}\}$ one should perform Lorentz
transformation of the nucleon longitudinal momenta
\begin{equation}
\label{KNIS9}  p_{zi} \rightarrow \gamma_i (p_{zi} - \beta_i e_{i})
\end{equation}
and the nucleon energies
\begin{equation}
\label{KNIS10} e_{i} \rightarrow \gamma_i (e_{i} - \beta_i p_{zi}),
\end{equation}
where $\beta_{i}$ is defined as
\begin{equation}
\label{KNIS11} \beta_{i} = \frac{P_{z0}}{\sqrt{P_{z0}^2 + m^{eff2}_i}}
\end{equation}
and $\gamma_i$ is given by
\begin{equation}
\label{KNIS12}\gamma_i = \frac{1}{\sqrt{1 - \beta_i^2}}.
\end{equation}

\subsection{Lorentz contraction of the fast moving nucleus.}
\hspace{1.0em}For this case one need also to perform the Lorentz
contraction of the nucleus, \textit{i. e.}
\begin{equation}
\label{KNIS13} r_{zi} \rightarrow r_{zi}/ \gamma_{i}.
\end{equation}
\subsection{Random choice of the impact parameter.}

\hspace{1.0em}The impact parameter $0 \leq b \leq R_p + R_t$ is randomly
selected according to the probability:
\begin{equation}
\label{KNIS14}P({\bf b})d{\bf b} = b d{\bf b},
\end{equation}
where $R_p$ and $R_t$ are the target and projectile radius,
respectively. In the case of nuclear projectile or target the nuclear radius is
determined from condition:
\begin{equation}
\label{KNIS15}\frac{\rho(R)}{\rho(0)} = 0.01.
\end{equation}
 Then one should update the transversal components of
nucleon coordinates:
\begin{equation}
\label{KNIS16} r_{xi} \rightarrow r_{xi} + b_x
\end{equation}
and
\begin{equation}
\label{KNIS17} r_{yi} \rightarrow r_{yi} + b_y.
\end{equation}
Finaly, for target nucleus, if a projectile is centered around $0$, one
should perform a shift of the nucleon longitudinal coordinates:
\begin{equation}
\label{KNIS18} r_{zi} \rightarrow r_{zi} + \Delta r_z/\gamma_{i},
\end{equation}
where $\Delta r_z = R_p + 1.5 \ fm + R_t + 1.5 \ fm$ is taken.

In the case of hadron--nucleus collision we determine the initial
angular momentum
of target nucleus:
\begin{equation}
\label{KNIS19} \vec{L}_0= \vec{p}_0 \times \vec{r}_0,
\end{equation}
where $\vec{p}_0$ and $\vec{r}_0$ are initial momentum and  radius vector
of incoming hadron enter point in the target nucleus rest frame.


% JuliaCon proceedings template
\documentclass{juliacon}
\usepackage[ruled,vlined]{algorithm2e}
\setcounter{page}{1}

\keywords{landscape ecology , computational ecology,  julia programming language}

\makeatletter
\newcommand{\removelatexerror}{\let\@latex@error\@gobble}
\makeatother

\begin{document}

\input{header}
\maketitle

\begin{abstract}
Connectivity across landscapes influences a wide range of conservation-relevant ecological processes, including species movements, gene flow, and the spread of wildfire, pests, and diseases. The computational demands of the next generation of connectivity models and the availability of increasingly fine grained remote sensing data drive the need for faster software for connectivity modelling. To address this, we upgraded the widely-used Circuitscape connectivity package to the Julia programming language. The Julia package, Circuitscape.jl, can now solve much larger problems up to an order of magnitude faster, with improved solvers and parallel computing features. We demonstrate scaling up to problems of size 437 million grid cells, with speedups of up to 1800\% over the previous version. These improvements increase the pace of interaction between scientists and key stakeholders, facilitating faster policy decisions.

\end{abstract}

\section{Introduction}
Connectivity models provide important insights into ecological processes that involve variation in movement or flow patterns across heterogeneous environments \cite{crooks2006}. In applied conservation, connectivity maps are incorporated into a wide range of resource evaluations and risk assessments, informing decisions on how to sustain population dynamics and genetic diversity in plant and animal populations \cite{kareiva1995connecting}, how to most effectively prevent infectious disease spread or reduce risks from wildfire \cite{gray2016applying}, and choices of where to invest in land protection or restoration to help support species range shifts under a changing climate \cite{heller2009biodiversity, littlefield2017connecting, keeley2017habitat}.

A common requirement for modeling connectivity is a gridded depiction of the landscape in which values for each cell represent some relative value of “resistance” to movement. These resistance grids are developed through several different methods, often involving iterative processes for categorizing resistance weights for different types of barriers based on expert opinion and information on species’ life histories and movement behaviors \cite{spear2010use, zeller2012estimating}. This grid can then be abstracted as a graph \cite{urban2001landscape}, providing a way to quantify ecological distance measures via graph-theoretic metrics.

The range of mathematical approaches and software tools used for modeling connectivity reflect differences in theoretical approaches, and in the underlying assumptions about how movement proceeds. The classical isolation by distance model (IBD) posits that the least cost distance across the landscape graph acts as a good proxy for ecological distance \cite{wright1943isolation}.  Tools based on this approach typically identify a single “best” route between focal locations, an important result, but one that is highly dependent upon the choice of start and end points, and has limited application if one’s goal is to compare potential options for restoration or protection across a landscape with multiple habitat patches and pathways.  As reviewed in \cite{dickson2019circuit}, from 2006-08, three seminal papers by the late Brad McRae built upon earlier work by \cite{doyle1984random} to demonstrate that isolation by resistance (IBR)\cite{mcrae2006isolation}, which operationalizes the potential for genes and individuals to follow “random walks” across multiple pathways in the same way that electrical current can spread across multiple resistors, can provide an effective tool for considering connectivity potential across landscapes. These insights and McRae’s interest in informing conservation applications inspired the Circuitscape software package \cite{mcrae2008using}, which calculates effective resistance and “current flow,” a measure of net movement probability, across heterogeneous landscapes \cite{dickson2019circuit}.  This approach has evolved into a very flexible set of tools that allow users to vary the resistance grid and identification of what can be connected, enabling modelers to address a wide range of questions related to structural (ability of a landscape to support movement) and functional (modeling that is tailored to species-specific traits) connectivity.
Over the past decade Circuitscape has emerged as the most cited landscape connectivity tool in the world \cite{dickson2019circuit}. In the last year alone, Circuitscape has been cited 129 times, and in the past three years, 480 times. Dickson et al. (2019) reviews 277 applications of the software, in fields ranging from gene flow and animal movement to fire, water, and disease spread, and also describes how outputs are being used to inform conservation decisions.

\begin{figure*}
    \centering
    \includegraphics[width=\textwidth]{res.pdf}
    \caption{\textbf{An illustration of the impact of coarsening the resistance grid to address computational limitations.}  For this agricultural area along the border of Illinois and Indiana, USA, we show current flow derived from a resistance grid coarsened to 900m (left), compared to a higher-resolution map (180m cells, right).  Both resistance grids were derived from the 2011 NLCD (30m), and run with a “wall-to-wall” application of Circuitscape to evaluate landscape structural connectivity.  All “natural” terrestrial land cover types in the NLCD were assigned low resistance values, with pasture, roads, row crops, etc., assigned higher resistances. The 900m resolution map misses many narrow bands of natural land cover with high current flow (dark blue) indicating high connectivity value along streams and rivers. Analyses and maps by Melissa Clark, to support work in \cite{baldwin2018future}.
}
    \label{fig:my_label}
\end{figure*}

\section{Circuitscape in Julia}
\label{sec:documentclass}
%
The goal of increasing the computational power of Circuitscape has been addressed multiple times by developers Brad McRae and Viral Shah.  McRae’s first version was written in Java, before being ported to MATLAB, to improve ease of development. Then, in collaboration with Tanmay Mohapatra, it was translated to Python for flexible scripting, platform independence and release under an open source license. This package makes heavy use of the numpy \cite{van2011numpy}, scipy \cite{jones2014scipy} and pyamg \cite{bell2015pyamg} numerical libraries and solves problems of up to tens of millions of nodes, but connectivity analysis increasingly finer resolution databases often scaled to hundreds of millions of nodes and dozens of focal node pairs, a workload size well beyond its capacity. Circuitscape needed to be upgraded to support the newer demands of user community.

To address these demands, McRae and Shah collaborated on  a project called GFLOW \cite{leonard2017gflow}, a software tool for conducting circuit-theory based analyses on supercomputers. Written in the C programmming language and making use of solver libraries such as PetSc \cite{balay2004petsc} and BoomerAMG \cite{yang2002boomeramg}, GFLOW yields state of the art performance on large clusters and supercomputers. However, this performance comes at the cost of accessibility (does not work on the Windows operating system, which the majority of Circuitscape users use), composability (ability to integrate with other software libraries) as well as a tangible difficulty in shipping binaries because of their complicated build processes. For many practitioners and researchers, these constraints are a key barrier, as they prevent GFLOW from being supported on the Windows operating system, and limit integration into a decision support tool or workflow with other tools.

As the maintainers of the Circuitscape, we saw the need for an open-source implementation that is easy to maintain, is high performance, is accessible to our user base and works well on every platform. We decided to use the Julia programming language \cite{bezanson2017julia}. Julia is an open source dynamic programming language which combines the readability of scripting languages such as R or Python, with the performance of a statically compiled language such as C or Fortran. With relatively little development effort via a straight reimplementation of the algorithm, Julia allowed us to not only significantly improve the package's computational capacity, but provide new user-facing features for free. For example, Julia's first class sparse matrix library and factorization support allowed us to support multiple solvers. Its modern Just in Time (JIT) compiler enables programmers to write generic code, and then generate specialized code for desired precision, index types and hardware platform. This makes maintenance of the code base simple. Our upgrade, "Circuitscape.jl", is a registered Julia package and is already being used by the community to solve the next generation of connectivity problems.

The rest of this paper is organized as follows: we present an overview of the algorithm in Section 3, before describing the numerical methods and software packages in Section 4. Section 5 then briefly describe the new features introduced in the upgrade and then present benchmarks both on synthetic problems as well as real user data. We then round off this work with a discussion on how speed improvements enable increased collaboration between computer scientists and ecologists enable improved collaboration between ecologists and conservation managers and other stakeholders.

\section{The Algorithm}
\begin{figure}
\removelatexerror
\centering
\begin{algorithm}[H]
\SetAlgoLined
\LinesNumbered
\KwResult{Current (probability) maps $C$, nodal voltages $V$, pairwise resistances}
 Read input raster grid \;
 Read focal nodes \;
Construct undirected, weighted graph connecting neighboring cells\;
Compute graph Laplacian $G$ \;
\For{all pairs of focal nodes}{
    Set up $I$\;
    Solve linear system $GV = I$ \;
    Compute effective resistance $r$\;
    Write nodal voltages $V$ to disk\;
    Compute nodal currents from $I$ and write current map C to disk\
}

 \caption{Circuitscape - Pairwise Mode }
\end{algorithm}
\end{figure}

\begin{figure*}
    \centering
    \includegraphics[width=0.5\textwidth]{flow.png}
    \caption{\textbf{Stages of computation and inputs/outputs}. The input raster grid to is usually assembled and produced using a GIS software package, and the output current maps are often exported to a GIS software package for postprocessing.}
    \label{fig:flow}
\end{figure*}

Circuitscape takes as input a raster grid, and a list of points which are potential starting and ending points for animal migration. Selecting these points (or focal nodes) on the landscape is often context dependent. For example, they could be two different national parks, or points on the landscape which share important climate properties. The raster grid is a spatial discretization of a heterogeneous landscape where each cell is assigned a value. Each value represents varying qualities of habitat, dispersal routes, or movement barriers. These “resistance” values are often problem specific, and are either empirically derived based on movement or genetic data, or derived via expert opinion. The following content has been summarized in Figure \ref{fig:flow}. This grid can then be represented as a graph, with nodes representing grid cells and edge weights proportional to the movement probabilities or number of migrants exchanged. Other inputs include a list of focal points, which represent points on the landscape of interest to the practitioner. These include habitat patches, protected areas, or populations to connect. These can be specified either through a raster grid with numerical labels for each focal point, or a text file with a list of coordinates. Once the graph is constructed, we then compute its laplacian, which is an alternate representation of the landscape. We then solve for Ohm’s law using the computed graph laplacian as the conductance matrix and the node locations of the focal points as current sources and sinks. On solving the system, we obtain a list of nodal voltages, which are then used to compute branch currents, which represent movement probabilities along branches of the graph. The ecological significance of these various quantities are summarized in related works \cite{mcrae2008using}. The branch currents are then accumulated on each node as nodal currents, which are then written to disk as a raster ASCII grid, for easy import into a geographic information system (GIS).

\section{Numerical Methods}
The vast majority of the computation in Circuitscape is applying Ohm’s law and Kirchoff’s law over very large resistive grids, and solving a large sparse linear system:
$$
GV = I
$$
where $G$ is the graph laplacian representation of the landscape is stored as a large sparse matrix, $I$ are the current sources, and $V$ are the nodal voltages. We provide two solver options to the user: one based on the choleksy factorization and a preconditioned iterative method. The Cholesky factorization \cite{higham2009cholesky} is efficient for applications with smaller study areas and a large number of focal nodes. The sparse matrix is factored once and the solution to multiple pairs is computed via back substitution. Since the cost for backsubstitution is polynomially smaller than the cost of factorization, problems with a large number of focal pairs scale efficiently. The solver that scales to large problems is a preconditioned conjugate gradient (PCG) \cite{trefethen1997numerical}, with an algebraic multigrid preconditioner (AMG) \cite{vanvek1996algebraic}. We leverage Julia implementations of these methods from open source packages IterativeSolvers.jl and AlgebraicMultigrid.jl.

\subsection{Preconditioner Implementation}
Multigrid preconditioners are often used in problems solved across large spatial domains. In general, they take the original grid and generate a hierarchy of coarser grids, via predefined or algebraically derived restriction and interpolation operators. Large problems are solved by restricting quantities down to the coarsest level, obtaining a fast solution, and then interpolating the solution back to the original size. This procedure is often referred to as a “V” cycle. The efficacy of a good multigrid preconditioner is to with obtaining good restriction and interpolation operators. Usually, these operators are derived from the structure of the underlying problem. However, one can also estimate these operators algebraically, from the numerical values at each grid cell. This procedure is often referred to as Algebraic Multigrid (AMG). There are several variants of AMG, which are summarized in \cite{stuben2001review}. We use a variant called the Smoothed Aggregation AMG, which is known to work well for solving matrices generated by elliptic partial differential equations, such as Laplace’s equation. Laplacian matrices are structurally identical to the laplacians of planar graphs that are generated in Circuitscape.

\section{New Features}

\subsection{New Solver Mode}

Circuitscape now supports a new solver based on the Cholesky factorization of the graph laplacian representation of the landscape. We use the SuperNodal sparse cholesky factorization implemented in the CHOLMOD library \cite{chen2008algorithm}. The Julia programming language has first class sparse matrix library and matrix factorization support, which makes it easy to use this solver with a single function call.This solver mode also enables new approaches that divide the landscape into tiles and process them independently \cite{pelletier2014applying}or analyses that move sliding windows across the landscape \cite{mcrae2016conserving}, both of which yield fine scale and localized results. The obvious limitation of this solver, as is of most sparse direct solvers, is that they work very well for relatively small matrices and run out of memory for larger ones. This exponential growth in memory is a by product of the factorization itself, as factors are often less sparse than the original matrix.

\subsection{Generic Programming}

Julia supports the development of generic code while relying on the compiler to generate specialized code for different platforms and precision required. Generic programs are powerful tools for our users, and can be made to adapt to their requirements. For example, the python package had a 32-bit integer type for indexing matrices hardcoded throughout the package, which limited the size of the computation the package ran. This led to crashes when running simulations for hundreds of millions of nodes. One such dataset studying the Mojave desert tortoise \cite{gray2019} used a resistance surface of 437 million pixels. This crashed the old version of Circuitscape, while the upgrade ran smoothly to completion. Circuitscape.jl defaults to a 32-bit integer type for cache efficiency, but provide users with a runtime flag to switch to 64-bit integer to index sparse matrices on the order of hundreds of millions. Since our Julia code was written generically, and this feature came for free without any additional programming effort. Upgrading the python package to support this feature would require significant effort.

\subsection{Improved Parallel Computations}

%Circuitscape.jl introduces support for parallelism on the Windows operating system. This was not possible with the Python package.

Parallel computing in Circuitscape.jl is inherently faster, because the preconditioner can be serialized as a byte stream and sent over the network to other processes. This is not possible in the python code, as the python multiprocessing module internally uses the package pickle to serialize objects, and pyamg objects, implemented in C++, are not “pickle-able” \cite{pydoc}. The ability to serialize native Julia objects significantly reduced the amount of effort to parallelize Circuitscape.
In addition to faster parallel processing, we also extend parallelism support for more problem types in Circuitscape. In the benchmarks section, a dataset which received speed improvements from these new features. The Julia version also lets the user call Circuitscape itself in parallel. As users aim to run Circuitscape over entire countries or continents, landscape are often divided into multiple tiles \cite{pelletier2014applying}. This feature allows users to process (a batch of) these tiles by running different Circuitscape problem instances on each tile in parallel. These parallel features work on all platforms: Linux, MacOS and Windows.

\section{Benchmarks}

\subsection{Experimental Setup}
We conducted our experiments on an Intel(R) Xeon(R) Silver 4114 CPU @ 2.20GHz with 384 GB of RAM. We used Julia v1.1.0 and Circuitscape v5.5.0, and compared against Circuitscape v4.0.5

\subsection{Standard Benchmarks}
We benchmarked Circuitscape on standard synthetic problems. These benchmarks represent the most commonly used configuration and mode (Raster Pairwise) but with different problem sizes. These datasets can be found at \url{https://github.com/Circuitscape/BigTests/}. The benchmark results are summarized in Figure \ref{fig:csbench}.

\begin{figure*}
    \centering
    \includegraphics[width=0.5\textwidth]{bench.pdf}
    \caption{\textbf{Results on the standard Circuitscape benchmark suite (smaller is better)}. The red column standards for the Julia package run under the AMG solver and green column stands for the Julia package run with the Cholesky-based CHOLMOD solver. Note that we benchmark only up to size 24M because at higher sizes the CHOLMOD solver runs out of memory and the Python version takes much, much longer. In summary, this chart demonstrates that Julia-CHOLMOD is the right choice for smaller problem sizes and Julia-CGAMG is the right choice for large problem sizes.}
    \label{fig:csbench}
\end{figure*}

\subsection{Benchmarks on Data from Existing Studies}

We ran the Python and Julia version of Circuitscape on a dataset used to model connectivity in the Sonoran desert \cite{drake2017using} (SONORAN). We used to all-to-one scenario \cite{mcrae2009circuitscape}, which models species migrating across the landscape from many different areas to one area. When the researcher used the old version of Circuitscape, this mode did not support parallelism, and the entire computation took over 2 days to run. Parallelism was trivial to support in the Julia version, which reduced execution time to less than 3 hours, resulting in a speedup of nearly 18x. We also benchmarked against a new range-wide model of connectivity for the endangered Mojave desert tortoise \cite{gray2019}(MOJAVE). We found that the Python version crashed, but the Julia package was able to scale effectively. The benchmark results are summarized in Figure \ref{table:bench}.

\begin{figure*}
%\begin{table*}[]
\begin{tabular}{|l|l|l|l|l|}
\hline
\textbf{Benchmark} & \textbf{Size} & \textbf{Number of Solves} & \textbf{Time (Python)} & \textbf{Time (Julia)} \\ \hline
SONORAN            & 3339832       & 6002                      & 56.62 hrs              & 2.838 hrs             \\ \hline
MOJAVE             & 437 million   & 1                         & Crashed                & 3.385 hrs             \\ \hline
\end{tabular}
\centering
%\end{table*}
\caption{\textbf{Benchmarks on data from two conservation studies}. Two metrics determine the execution time of a Circuitscape run: the size of the problem and the number of linear system solves. Our package scales desirably in both directions. }
\label{table:bench}
\end{figure*}

\section{Discussion}

The growth in popularity of circuit theory to model ecological processes has to lead to widespread adoption of the Circuitscape software package. \cite{mcrae_shah_mohapatra_anantharaman}. The Circuitscape project has always evolved with the demands of the users and this upgrade to the Julia programming language seeks to drive the next generation of compute-intensive connectivity models, by shortening execution time from weeks to days and from days to hours. Users no longer have to coarsen their analysis due to computational limitations \cite{drake2017using}. Faster results often enhance stakeholder engagement, improve the feedback loop with policy makers and result in faster turnaround time for conservation decisions. Julia is already being used by ecologists to model ecological networks \cite{timothee_poisot_2018_1438428} and bioenergetic food webs \cite{delmas_eva_2019_2584373} and we see a strong role for it in other areas of computational ecology and conservation science. Its high level mathematical syntax is accessible to scientists while its speed allows them to simulate large, intricate models that capture complexity. We hope to see more ecologists and practitioners use and adopt Julia.

% While connectivity tools typically focus in variation across space, questions related to temporal variability in connectivity, and simulations of how connectivity might change through habitat loss or restoration, would be of great interest as well.

\section{Conclusion}
We present an upgrade to the Circuitscape package, which will allow researchers to analyze ecological processes over large landscapes at fine resolutions. Our upgrade in the high performance Julia programming language presents upto a 1800\% improvement in computation time and the ability to solve landscapes with hundreds of millions (and potentially billions) of grid cells. Julia’s sophisticated compiler allows for faster parallelism, generic programming and composability with other software packages. Circuitscape.jl is open source and is available at \url{https://github.com/Circuitscape/Circuitscape.jl} under the MIT license. Binaries are available on \url{https://circuitscape.org/downloads/}. It can also be installed using the Julia package manager by starting Julia, and entering \texttt{using Pkg; Pkg.add("Circuitscape")}.

\section{Acknowledgement}
The work to update Circuitscape to the Julia computing language was funded through a grant from NASA’s Ecological Forecasting Program (16-ECO4CAST0018), and a grant from the Wilburforce Foundation.  The authors also wish to acknowledge the Wilburforce Foundation’s long-term investment in Circuitscape and related tools through several previous awards to Dr. Brad McRae.  We thank all of the Circuitsape users who have shared datasets, reported issues, and provided feedback on various versions of these tools, and look forward to continued collaboration with the user community.

\input{bib.tex}
%\bibliography{ref}  %%% Remove comment to use the external .bib file (using bibtex).

\end{document}

% Inspired by the International Journal of Computer Applications template


 \documentclass [12pt]{article}

\usepackage {amsmath}
\usepackage {amsthm}
\usepackage {amssymb}
\usepackage {graphicx}
\usepackage {float}
\usepackage {multirow}
\usepackage {xcolor}
\usepackage {algorithmic}
\usepackage [ruled,vlined,commentsnumbered,titlenotnumbered]{algorithm2e} \usepackage {array}
\usepackage {booktabs}
\usepackage {url}
\usepackage {parskip}
\usepackage [margin=1in]{geometry}
\usepackage [T1]{fontenc}
\usepackage {cmbright}
\usepackage [many]{tcolorbox}
\usepackage [colorlinks = true,
            linkcolor = blue,
            urlcolor  = blue,
            citecolor = blue,
            anchorcolor = blue]{hyperref}
\usepackage {enumitem}
\usepackage {xparse}
\usepackage {verbatim}
\usepackage{listings}
\usepackage{xcolor}
\lstset { %
    language=C++,
    backgroundcolor=\color{black!5}, % set backgroundcolor
    basicstyle=\footnotesize,% basic font setting
}

\DeclareTColorBox {Solution}{}{breakable, title={Solution}} \DeclareTColorBox {Solution*}{}{breakable, title={Solution (provided)}} \DeclareTColorBox {Instruction}{}{boxrule=0pt, boxsep=0pt, left=0.5em, right=0.5em, top=0.5em, bottom=0.5em, arc=0pt, toprule=1pt, bottomrule=1pt} \DeclareDocumentCommand {\Expecting }{+m}{\textbf {[We are expecting:} #1\textbf {]}} \DeclareDocumentCommand {\Points }{m}{\textbf {(#1 pt.)}}

\begin {document}

{\LARGE \textbf {COMP 285 (NC A\&T, Spr `22)}\hfill \textbf {Lecture 4} }
\vspace {1em}
\begin {Instruction}

Adapted From Virginia Williams' lecture notes. Additional credits: J. Su, W. Yang, Gregory Valiant, Mary Wootters, Aviad Rubinstein, Sami Alsheikh.
\end {Instruction}

\begin{centering}
\section*{MergeSort and Introduction to Recurrence Relations}
\end{centering}

\section{MergeSort Cont.}

From last lecture, we will continue our implementation of MergeSort, and go over some of the details regarding correctness and running time.

\subsection{Correctness of MergeSort}
Let's focus on the first question first. As before, we'll proceed by induction. This time, we'll maintain a \textit{recursion invariant} that any time \texttt{MergeSort} returns, it returns a sorted array.

\begin{itemize}
    \item \textbf{Inductive Hypothesis.} Whenever \texttt{MergeSort} returns an array of size $\leq i$, that array is sorted.
    \item \textbf{Base case.} Suppose that $i = 1$. Then whenever \texttt{MergeSort} returns an array of length $0$ or length $1$, that array is sorted. (Since all array of length $0$ and $1$ are sorted). So the Inductive Hypothesis holds for $i = 1$.
    \item \textbf{Inductive step.} We need to show that if \texttt{MergeSort} always returns a sorted array on inputs of length $leq i - 1$, then it always does for length $\leq i$. Suppose that \texttt{MergeSort} has an input of length $i$. Then $L$ and $R$ are both of length $\leq i - 1$, so by induction, $L$ and $R$ are both sorted. Thus, the inductive step boils down to the statement:

    ``When Merge takes as inputs two sorted arrays $L$ and $R$, then it returns a sorted array containing all of the elements of $L$, along with all of the elements of $R$.''

    This statement is intuitively true, although proving it rigorously takes a bit of bookkeeping. In fact, it takes another proof by induction! Check out CLRS Section 2.3.1 for a rigorous treatment.
    \item \textbf{Conclusion.} By induction, the Inductive hypothesis holds for all $i$. In particular, given an array of any length $n$, \texttt{MergeSort} returns a sorted version of that array.
\end{itemize}

\subsection{Running time of MergeSort}
Finally, we get to our first question in this lecture where the answer may not be intuitively obvious. What is the running time of \texttt{MergeSort}? In the next few lectures, we'll see a few principled ways of analyzing the runtime of a recursive algorithm. Here, we'll just go through one of the ways, which is called the \texttt{recursion tree} method.

The idea is to draw a tree representing the computation (see the slides for the visuals). Each node in the tree represents a subproblem, and its children represent the subproblems we need to solve to solve the big sub-problem. The recursion tree for \texttt{MergeSort} looks something like
this:

\begin{figure}[h!]
\centering{}
\includegraphics[scale=0.75]{mergesort_tree.png}
\end{figure}

At the top (zeroth) level is the whole problem, which has size $n$. This gets broken into two sub-problems, each of size $n/2$, and so on. At the $t$'th level, there are $2^t$ problems, each of size $n/2^t$
. This continues until we have $n$ problems of size $1$, which happens at the $log(n)$'th level.

\textbf{Some notes:}

\begin{itemize}
\item In this class, logarithms will \textbf{always} be base $2$, unless otherwise noted.
\item We are being a bit sloppy in the picture above: what if $n$ is not a power of $2$? Then $n/2^j$ might not be an integer. In the pseudocode above, we actually break a problem of size n into problems of size $\lfloor n/2 \rfloor$ and $\lceil n/2 \rceil$. Keeping track of this in our analysis will be messy, and it won't add much, so we will ignore it, and for now we will assume that $n$ is a power of $2$ \footnote{To formally justify the assumption that $n$ is a power of $2$, notice that we can always sort a \textit{longer} list of length $n' = 2^{\lceil log_2(n) \rceil}$. That is, we'll add extra entries, whose values are $\infty$, to the list. Then we sort the new list of length $n'$, and return the first $n$ values. Since $n' \leq 2n$ (why?) this won't affect the asymptotic running time. Also see CLRS Section 4.6.2 for a rigorous analysis of the original algorithm with floors and ceilings.}
\end{itemize}

In order to figure out the total amount of work, we will figure out how much work is done at each node in the tree, and add it all up. To that end, we tally up the work that is done in a particular node in the tree—that is, in a particular call to \texttt{MergeSort}. There are three things:

\begin{enumerate}
    \item Checking the base case
    \item Making recursive calls (but we don't count the work actually done in those recursive calls; that will count in other nodes)
    \item Running Merge.
\end{enumerate}

Let's analyze each of these. Suppose that our input has size $m$ (so that $m = n/2^j$ for some $j$).

\begin{enumerate}
    \item Checking the base case doesn't take much time. For concreteness, let us say that it takes one operation to retrieve the length of $A$, and other operation to compare this length to $1$, for a total of two operations.\footnote{Of course, there's no reason that the ``operation'' of getting the length of $A$ should take the same amount of time as the ``operation'' of comparing two integers. This disconnect is one of the reasons we use big-Oh notation.}
    \item Making the recursive calls should also be fast. If we implemented the pseudocode well, it should also take a constant number of operations.

        \textbf{Aside:} This is a good point to talk about how we interpret pseudocode in this class. Above, we've written \texttt{MergeSort(A[:n/2])} as an example of a recursive call. This makes it clear that we are supposed to recurse on the first half of the list, but it's not clear how we actually implement that. Our ``pseudocode'' above is in fact working Python code, and in Python, this implementation, while clear, is a bit inefficient. That is, written this way, Python will actually copy the first $n/2$ elements of the list before sending them to the recursive call. A much better way would be to instead just pass in pointers to the $0$'th and $n/2 - 1$'st index in the list. This would result in a faster algorithm, but kludgier pseudocode. In this class, we generally will opt for cleaner pseudocode, as long as it does not hurt the asymptotic running time of the algorithm. In this case, our simple-but-slower pseudocode turns out not to affect the asymptotic running time, so we'll stick with this.

    In light of the above Aside, let's suppose that this step takes $m + 2$ operations, $m/2$ to copy each half of the list over, and 2 operations to store the results. Of course, a better implementation of this step would only take a constant number (say, four) operations.
    \item The third thing is the tricky part. We claim that the Merge step also takes about $m$ operations.

    Consider a single call to Merge, where we'll assume the total size of $A$ is $m$ numbers. How long will it take for Merge to execute? To start, there are two initializations for $i$ and $j$. Then, we enter a for loop which will execute $m$ times. Each loop will require one comparison, followed by an assignment to $S$ and an increment of $i$ or $j$. Finally, we'll need to increment the counter in the for loop $k$. If we assume that each operation costs us a certain amount of time, say $Cost_a$ for assignment, $Cost_c$ for comparison, $Cost_i$ for incrementing a counter, then we can express the total time of the Merge subroutine as follows:

    $$
        2Cost_a + m(Cost_a + Cost_c + 2Cost_i)
    $$
    This is a precise, but somewhat unruly expression for the running time. In particular, it seems difficult to keep track of lots of different constants, and it isn't clear which costs will be more or less expensive (especially if we switch programming languages or machine architectures). To simplify our analysis, we choose to assume that there is some global constant $c_{op}$ which represents the cost of an operation. You may think of $c_{op}$ as $\max\{Cost_a, Cost_c , Cost_i, \dots\}$. We can then bound the amount of running time for Merge as
    $$
    2c_{op} + 4c_{op}m = 2 + 4m \text{ operations}
    $$
\end{enumerate}

Thus, the total number of operations is at most
$$
2 + (m+2) + 4m + 2 \leq 11m
$$

using the assumption that $m \geq 1$. This is a very loose bound; for larger $m$ this will be much closer to $5m$ than it is to $11m$. But, as we'll discuss more below, the difference between $5$ and $11$ won't matter too much to us, so much as the linear dependence on $m$.

Now that we understand how much work is going on in one call where the input has size $m$, let's add it all up to obtain a bound on the number of operations required for \texttt{MergeSort}. In a Merge of $m$ numbers, we want to translate this into a bound on the number of operations required for \texttt{MergeSort}. At first glance, the pessimist in you may be concerned that at each level of recursive calls, we're spawning an exponentially increasing number of copies of
\texttt{MergeSort} (because the number of calls at each depth doubles). Dual to this, the optimist in you will notice that at each level, the inputs to the problems are decreasing at an exponential rate (because the input size halves with each recursive call). Today, the optimists win out.

\textbf{Claim 3.} MergeSort \textit{requires at most $11n \log n + 11n$ operations to sort $n$ numbers}.

Before we go about proving this bound, let’s first consider whether this running time bound is good. We covered in last lecture that more obvious methods of sorting, like \texttt{InsertionSort}, required roughly $n^2$ operations. How does $n^2 = n \cdot n$ compare to $n \cdot \log n$? An intuitive definition of $\log n$ is the following: ``Enter n into your calculator. Divide by $2$ until the total is $\leq 1$. The number of times you divided is the logarithm of $n$.'' This number in general will be significantly smaller than $n$. In particular, if $n = 32$, then $\log n = 5$; if $n = 1024$, then $\log n = 10$. Already, to sort arrays of $\approx 103$ numbers, the savings of $n \log n$ as compared to $n^2$ will be orders of magnitude. At larger problem instances of $10^6, 10^9$, etc. the difference will become even more pronounced! $n \log n$ is much closer to growing linearly (with $n$) than it is to growing quadratically (with $n^2$).

One way to argue about the running time of recursive algorithms is to use recurrence relations. A recurrence relation for a running time expresses the time it takes to solve an input of size $n$ in terms of the time required to solve the recursive calls the algorithm makes. In particular, we can write the running time $T(n)$ for \texttt{MergeSort} on an array of n numbers as the following
expression.

\begin{align*}
T(n) &= T(n/2) + T(n/2) + T(Merge(n)) \\
&\leq 2\cdot T(n/2) + 11n
\end{align*}

There are a number of sophisticated and powerful techniques for solving recurrences. We will cover many of these techniques in the coming lectures. Today, we can actually analyze the running time directly.

\textit{Proof of Claim 3} Consider the recursion tree of a call to \texttt{MergeSort} on an array of $n$ numbers. Assume for simplicity that $n$ is a power of $2$. Let’s refer to the initial call as Level $0$, the proceeding recursive calls as Level $1$, and so on, numbering the level of recursion by its depth in the tree. How deep is the tree? At each level, the size of the inputs is divided in half, and there are no recursive calls when the input size is $\leq 1$ element. By our earlier ``definition'', this means the bottom level will be Level $\log n$. Thus, there will be a total of $\log n + 1$ levels.

We can now ask two questions: (1) How many subproblems are there at Level $i$? (2) How large are the individual subproblems at Level $i$? We can observe that at the $i$th level, there will be $2^i$ subproblems, each with inputs of size $n/2^i$.

We’ve already worked out that each sub-problem with input of size $n/2^
i$ takes at most $11n/2^i$ operations. Now we can add this up:

\begin{align*}
    \text{Work at Level }i &= (\text{number of subproblems}) \cdot (\text{work per subproblem}) \\
    &\leq 2^i \cdot 11 \left( \frac{n}{2^i} \right) \\
    &= 11n \text{ operations.}
\end{align*}

Importantly, we can see that the work done at Level $i$ is independent of $i - i$. It only depends on $n$ and is the same for every level. This means we can bound the total running time as follows:

\begin{align*}
    \text{Total number of operations } &= (\text{operations per level}) \cdot (\text{number of levels}) \\
    &\leq (11n)\cdot (\log n + 1) \\
    &= 11n \log n + 11n
\end{align*}
This proves the claim, and we’re done!

\end{document}