\clearpage
\subsection{Type} % (fold)
\label{sub:type}

All values within a program will have a \textbf{type}. The type indicates how the data stored in the computers memory is interpreted by the program. There are three basic data types available in a programming language, as shown in \fref{fig:program-creation-type}.

\begin{itemize}
    \item \textbf{Textual} data such as `\emph{Fred}', `\emph{Hello World}', `\emph{23}', and `\emph{This is text!}'.
    \item \textbf{Whole numbers} such as \emph{1}, \emph{0}, \emph{-5}, and \emph{37}.
    \item \textbf{Real numbers} such as \emph{0.5}, \emph{-126.0}, \emph{3.141516}, and \emph{23.981}.
\end{itemize}

\begin{figure}[h]
   \centering
   \includegraphics[width=0.9\textwidth]{./topics/program-creation/diagrams/Type}
   \caption{A types define how values are interpreted and the operations that can be performed on the data.}
   \label{fig:program-creation-type}
\end{figure}

\mynote{
\begin{itemize}
  \item A type is an \textbf{artefact}, there will be a number of existing types that you can use, and later you will see how to create your own types.
  \item The concepts related to expressions are shown in Figure \ref{fig:program-creation-type}.
  \item A type is a programming artefact that indicates a kind of data.
  \item The type determines the basic actions that can be performed on the value.
  \item The type determines the amount of memory needed to store a value of that kind.
  \item Whole numbers are usually called \textbf{Integers}.
  \item Real numbers are usually represented as \textbf{Floating Point} values. These values have a limited precision, supporting only a certain number of digits of precision.
  \item Textual values can contain numbers as text characters. For example, the text `\emph{23}' is the character `\emph{2}' followed by the character `\emph{3}' - it is not the number \emph{23}.
  \item You can perform mathematic operations on numeric data, but not on textual data.
\end{itemize}
}

% section program (end)


\documentclass[oneside]{amsart}
%\usepackage{amsmath}
\usepackage{txfonts}
\usepackage{courier}
\usepackage{superdate}
\usepackage[margin=1.25in]{geometry}

\title{A Simple Graph type for Julia}
\author{Ed Scheinerman}
\thanks{Document version \texttt{\superdate}. Note: This documentation
might not quite be in sync with the functionality found in the
\texttt{SimpleGraphs} module. I will likely want to redo this at some
point.}
\begin{document}
\maketitle

\section{Fundamentals}

This is documentation for a \verb|SimpleGraph| data type for Julia. The
goal is to make working with graphs as painless as possible. The
\verb|SimpleGraph| data type is for simple graphs (undirected edges, no
loops, no multiple edges). Vertices in a \verb|SimpleGraph| are of a
given Julia data type, which might be \verb|Any|.

The key constructor is
\verb|SimpleGraph| which creates a graph whose vertices may be any Julia
type. Alternatively, \verb|G=SimpleGraph{T}()| sets up \verb|G| to be a
graph in which all vertices must be of type \verb|T|. Two special
cases are built into this module: \verb|IntGraph()| is a synonym for
\verb|SimpleGraph{Int}()| and \verb|StringGraph()| is a synonym for
\verb|SimpleGraph{String}|.

Vertices and edges are added to a graph with \verb|add!| and deleted
with \verb|delete!|. Membership is checked with \verb|has|.
\begin{verbatim}
julia> using SimpleGraphs

julia> G = IntGraph()
SimpleGraph{Int64} (0 vertices, 0 edges)

julia> add!(G,5)
true

julia> add!(G,1,2)
true

julia> G
SimpleGraph{Int64} (3 vertices, 1 edges)
\end{verbatim}
Notice that adding an edge automatically adds its end points to the
graph.

The number of vertices and edges can be queried with \verb|NV| and
\verb|NE|. The vertex and edge sets are returned as arrays by
\verb|vlist(G)| and \verb|elist(G)|.
\begin{verbatim}
julia> vlist(G)
3-element Array{Int64,1}:
 1
 2
 5

julia> elist(G)
1-element Array{(Int64,Int64),1}:
 (1,2)
\end{verbatim}

Use \verb|deg(G,v)| for the degree of a vertex and \verb|deg(G)| for
the graph's degree sequence.
\begin{verbatim}
julia> deg(G,1)
1

julia> deg(G)
3-element Array{Int64,1}:
 1
 1
 0
\end{verbatim}

The neighbors of a vertex can be sought with \verb|neighbors(G,v)| or,
alternatively, with \verb|G[v]|. Edges can be queried with
\verb|G[v,w]|.
\begin{verbatim}
julia> G[1]
1-element Array{Int64,1}:
 2

julia> G[1,2]
true

julia> G[1,5]
false
\end{verbatim}

The \verb|Complete| method can be used to create complete graphs
and complete bipartite graphs with \verb|Int| vertices.
\begin{verbatim}
julia> Complete(5)
SimpleGraph{Int64} (5 vertices, 10 edges)

julia> Complete(3,3)
SimpleGraph{Int64} (6 vertices, 9 edges)
\end{verbatim}
We also provide \verb|Cycle(n)| and \verb|Path(n)| to create
the graphs $C_n$ and $P_n$. An instance of a Erd\H{o}s-R\'enyi random
graph $G_{n,p}$ is returned by \verb|RandomGraph(n,p)|.

The adjacency, Laplacian, and vertex-edge incidence matrices can be
found with \verb|adjaceny|, \verb|Laplacian|, and \verb|incidence|. It
is important to note that the indexing of the rows/columns of these
matrices might not correspond to the natural order of the underlying
vertices (or edges).

The incidence matrix method takes an optional argument as to whether
the matrix is signed (a $1$ and a $-1$ in each column) or unsigned
(only positive $1$s). Also, it is a sparse matrix that can be
converted to dense storage with \verb|full|.

Finally, the \verb|vertex_type| function can be used to query the
data type of the vertices in the graph.
\begin{verbatim}
julia> G = StringGraph()
SimpleGraph{String} (0 vertices, 0 edges)

julia> vertex_type(G)
String (constructor with 1 method)
\end{verbatim}

\section{Look but don't touch}
\label{sect:fastN}

The \verb|SimpleGraph| objects have various internal fields. It is not
safe to change these directly, but there is no problem examining their
values.

\begin{itemize}
\item \verb|:V|

  This holds the vertex set of the graph. If \verb|G| is a
  \verb|SimpleGraph{T}| then \verb|G.V| is of type \verb|Set{T}|.

\item \verb|:E|

  This holds the edge set of the graph. If \verb|G| is a
  \verb|SimpleGraph{T}| then \verb|G.E| is a \verb|Set{(T,T)}|.

\item \verb|:Nflag|

  This boolean value indicates whether or not fast neighborhood lookup
  has been activated for this graph. See the discussion below and the
  description of the function \verb|fastN!|.

\item \verb|:N|

  This is a \verb|Dict| that keeps track of the neighborhood of each
  vertex. It is only active if the \verb|Nflag| is set to
  \verb|true|.

\item \verb|:cache|

  This is a dictionary that holds previously computed properties
  of the graph. See Section~\ref{sect:cache} for details and user
  functions for manipulating the cache.

\item \verb|cache_flag|

  Used to determine if caching should be enabled.

\end{itemize}

This design is redundant. One can test if two vertices are adjacent by
looking for the edge in \verb|E|.  One can determine the neighbors of
a given vertex by iterating over the edge set \verb|E|.  However, this
approach is slow. By providing the extra \verb|N| data structure,
these operations are very fast.

By calling \verb|fastN!(G,false)| the redudant neighborhood structure
\verb|N| is deleted. All functions will still work, but perhaps more
slowly. Calling \verb|fastN!(G,true)| rebuilds the \verb|N|
structure.

We recommend using the default structure unless the graph is so large
that it consumes too much memory.

\section{List of all functions}

\subsection*{Creators}

These are functions that create new graphs.

\begin{itemize}
\item \verb|SimpleGraph|

  Use \verb|G=SimpleGraph()| to create a graph whose vertices can be
  of \verb|Any| type. To create a graph with vertices of a particular
  type \verb|T| use \verb|G=SimpleGraph{T}()|.

\item \verb|IntGraph|

  This a synonym for \verb|SimpleGraph{Int}|. Use \verb|G=IntGraph()|
  to create a vertex whose vertices are integers (type \verb|Int|).

  Use \verb|IntGraph(n)| to create a \verb|SimpleGraph{Int}| graph
  with vertex set $\{1,2,\ldots,n\}$ and no edges.

\item \verb|StringGraph|

  This is a synonym for \verb|SimpleGraph{String}|. Use
  \verb|G=StringGraph()| to create a graph whose vertices are
  character strings.

  One can also call \verb|G=StringGraph(filename)| to read in a graph
  from a file. The file must have the following format:
  \begin{itemize}
  \item Each line should contain one or two tokens (words) that do not
    contain any whitespace.
  \item If a line contains one token, that token is added to the graph
    as a vertex.
  \item If a line contains two tokens, an edge is added with those
    tokens as end points. If those two tokens are the same, no edge is
    created (since we do not allow loops) but a vertex is added (if
    not already in the graph).
  \item If there are three or more tokens on a line, only the first
    two are read and the rest are ignored.
  \item If the line is blank, it is ignored.
  \item If the line begins with a \verb|#|, the entire line is
    ignored. (This does put a mild limitation on the names of
    vertices.)
  \end{itemize}

  \item \verb|Complete|

    The \verb|Complete| function can be used to create a complete
    graph $K_n$, a complete bipartite graph $K_{n,m}$, or a complete
    multipartite graph $K(n_1,n_2,\ldots,n_p)$.

    \begin{itemize}
    \item Use \verb|Complete(n)| to create a complete graph $K_n$.

    \item Use \verb|Complete(n,m)| to create a complete bipartite
      graph $K_{n,m}$.

    \item Use \verb|Complete([n1,n2,...,np])| to create a complete
      multipartite graph $K(n_1,n_2,\ldots,n_p)$.
    \end{itemize}

    Note the last version requires that the part sizes be in an
    array. In this way we distinguish \verb|Complete(n)| and
    \verb|Complete([n])|. The first makes $K_n$ and the second an
    edgeless graph with $n$ vertices, i.e., $\overline{K_n}$.
    However, \verb|Complete(n,m)| and \verb|Complete([n,m])| build
    exactly the same graphs.
    \small
\begin{verbatim}
julia> G = Complete(4,5)
SimpleGraph{Int64} (9 vertices, 20 edges)

julia> H = Complete([4,5])
SimpleGraph{Int64} (9 vertices, 20 edges)

julia> G == H
true
\end{verbatim}
\normalsize

  \item \verb|Cube|

    Create the cube graph. The $2^n$ vertices of \verb|Cube(n)| are
    \verb|String| objects. For example:
\small
\begin{verbatim}
julia> G = Cube(3)
SimpleGraph{String} (8 vertices, 12 edges)

julia> vlist(G)
8-element Array{String,1}:
 "000"
 "001"
 "010"
 "011"
 "100"
 "101"
 "110"
 "111"

julia> elist(G)
12-element Array{(String,String),1}:
 ("000","001")
 ("000","010")
 ("000","100")
 ("001","011")
 ("001","101")
 ("010","011")
 ("010","110")
 ("011","111")
 ("100","101")
 ("100","110")
 ("101","111")
 ("110","111")
\end{verbatim}
\normalsize

\item \verb|Path|

  Use \verb|Path(n)| to create a path graph with $n$ vertices.

  Also, given a list of vertices \verb|verts|, then \verb|Path(verts)|
  creates a path graph with edges \verb|(verts[k],verts[k+1])| when
  \verb|k=1:n-1|. It's the user's responsibility that there be no
  repeated entries in \verb|verts|.

\item \verb|Grid|

  Use \verb|Grid(n,m)| to create an $n\times m$ grid graph.

\item \verb|Cycle|

  Use \verb|Cycle(n)| to create a cycle graph with $n$ vertices. It is
  required that $n\ge3$.

\item \verb|Wheel|

  Use \verb|Wheel(n)| to create the wheel graph with $n$
  vertices. That is, a graph composed of an $(n-1)$-cycle with one
  additional vertex adjacent to every vertex on the cycle. This
  requires $n\ge4$.

\item \verb|BuckyBall|

  Create the Buckyball graph with $30$ vertices and $90$ edges.

\item \verb|RandomGraph|

  Use \verb|RandomGraph(n,p)| to create an Erd\H{o}s-R\'enyi random
  graph with $n$ vertices with edge probability $p$. If the argument
  \verb|p| is omitted, it is assumed $p=\frac12$.

\item \verb|RandomTree|

  Use \verb|RandomTree(n)| to create a random tree on vertex set
  \verb|1:n|. All $n^{n-2}$ trees are equally likely.

  This works by creating an $n-2$-long sequence of random values, each
  in the range \verb|1:n|. It then converts that Pr\"ufer code to a
  tree using \verb|code_to_tree|. This latter function is exposed for
  use by the user. It takes as input an array of integers and returns
  a tree assuming, that is, that the input is valid. No checks are
  done on the input so user beware.

\item \verb|RandomSBM|

  Use \verb|RandomSBM(bmap,pmat)| to create a random stochastic block
  model graph. Here \verb|bmap| is an $n$-long list of integers between
  $1$ and $b$ that assigns the $n$ vertices to blocks. The
  $i,j$-entry of the matrix \verb|pmat|
  gives the probability that a vertex in block $i$
  is adjacent to a vertex in block $j$.

  This can also be invoked by \verb|RandomSBM(n,pvec,pmat)| where
  \verb|n| is the number of vertices, \verb|pvec| is a probability vector
  whose $j$-th entry is the probability a vertex is placed in the $j$-th block.

\item \verb|Kneser|

  Use \verb|Kneser(n,k)| to create the Kneser graph with those
  parameters (with $0 \le k \le n$). This is a graph with $\binom nk$
  vertices that are the $k$-element subsets of $\{1,2,\ldots,n\}$. Two
  vertices $u$ and $v$ are adjacent iff $u \cap v = \varnothing$.

  Part of this implementation is a function \verb|subsets(A,k)| where
  \verb|A| is a \verb|Set| and \verb|k| is an \verb|Int|. This creates
  the set of all $k$-element subsets of $A$.

\item \verb|Petersen|

  Use \verb|Peteren()| to create Petersen's graph. This is created by
  calculating \verb|Kneser(5,2)|.

  To remap the vertex names to $\{1,2,\ldots,10\}$ use
  \verb|relabel(Petersen())|.

  \item \verb|Frucht|

    Use \verb|Frucht| to create the Frucht graph, 12-vertex, 3-regular graph with
    no non-nontrivial automorphisms.

  \item \verb|Hoffman|

    Use \verb|Hoffman()| to return a graph that is cospectral, but not
    isomorphic, to the 4-cube.

  \item \verb|HoffmanSingleton|

    Use \verb|HoffmanSingleton()| to create the Hoffman-Singleton graph:
    A $7$-regular, diameter-$2$, girth-$5$ graph.

  \end{itemize}

\subsection*{Graph operations}
These are operations that create new graphs from old.

\begin{itemize}

\item \verb|line_graph|

  Use \verb|line_graph(G)| to create the line graph of $G$. Note that
  if \verb|G| has vertex type \verb|T|, then this creates a graph with
  vertex type \verb|(T,T)|.

\item \verb|complement| and \verb|complement!|

  Use \verb|complement(G)| to create the graph $\overline{G}$. The
  original graph is not changed and the vertex type of the new graph
  is that same the vertex type of \verb|G|.

  We can use \verb|G'| in lieu of \verb|complement(G)|.

  Use \verb|complement!(G)| to complement a graph in place (i.e.,
  replace \verb|G| with its own complement).

\item \verb|copy|

  Use \verb|copy(G)| to create an independent copy of \verb|G|.

\item \verb|induce|

  Use \verb|induce(G,A)| to create the induced subgraph of \verb|G| on
  vertex set \verb|A|.

\item \verb|spanning_forest|

  Given a graph, this creates a maximal, acyclic, spanning
  subgraph. If the original graph is connected, this produces a
  spanning tree.

\item \verb|cartesian|

  Use \verb|cartesian(G,H)| to compute the Cartesian product $G\times
  H$ of $G$ and $H$. For example, to create a grid graph, do this:
  \verb|cartesian(Path(n), Path(m))|.

  Note that \verb|G*H| is equivalent to \verb|cartesian(G,H)|.

\item \verb|relabel|

  Create a new graph, isomorphic to the old graph, in which the
  vertices have been renamed. Use \verb|relabel(G,label)| where
  \verb|G| is a simple graph and \verb|labels| is a dictionary mapping
  vertices in \verb|G| to new names. Trouble ensues if two vertices
  are mapped to the same label (we don't check).

  Note that if the vertex type of \verb|G| is \verb|S|, then
  \verb|label| must be of type \verb|Dict{S,T}|. The new graph
  produced with have type \verb|SimpleGraph{T}|.

  Calling this with one argument, \verb|relabel(G)|, will produce a
  relabeled version of \verb|G| using consecutive integers starting
  with $1$.

\item \verb|disjoint_union|

  The disjoint union of two graphs is formed by taking
  nonoverlapping copies of the two graphs and merging them into a
  single graph (with no additional edges). In Julia, we do this by
  appending the intger 1 or 2 to the vertex names.  Thus, if a vertex
  of the first graph is \verb|"alpha"|, then in the disjoint union its
  name will be \verb|("alpha",1)|.

  Use \verb|disjoint_union(G,H)| to form the disjoint union. If the
  vertex types of the two graphs are both \verb|T|, then the vertex
  type of the result is type \verb|(T,Int)|. But if the two graphs
  have different vertex types, then the result has vertex type
  \verb|Any|.

  We append a 1 or a 2 to vertex names to ensure that we have two
  independent copies of the graphs. If the user knows that the two
  graphs have no vertices in common, then \verb|union| might be a
  preferrable choice.

\item \verb|join|

  The join of two graphs is formed by taking nonoverlapping copies of
  the two graphs and then adding all possible edges between the two
  copies. To ensure the two copies of the given graphs are on distinct
  vertex sets, we append a 1 or a 2 to the vertex names (see the
  description for \verb|disjoint_union|).

  Use \verb|join(G,H)| to form the join. If the two graphs have the
  same vertex type \verb|T|, then the result has vertex type
  \verb|(T,Int)|. Otherwise, the resulting graph has vertex type
  \verb|Any|.

\item \verb|union|

  Given graphs $G$ and $H$, the union has vertex set $V(G)\cup V(H)$
  and edge set $E(G) \cup E(H)$.

\item \verb|trim|

  Trimming a graph means to repeatedly remove vertices of a given
  degree $d$ or less until either all vertices have been removed or the
  remaining vertices induce a subgraph all of whose vertices have
  degree greater than $d$.

  Use \verb|trim(G,d)| to trim the graph, with \verb|trim(G)|
  equivalent to \verb|trim(G,0)|. The latter simply removes all
  isolated vertices.

\end{itemize}

\subsection*{Manipulators and inspectors}

These are functions that are used to modify a graph and to inspect its
structure.

\begin{itemize}

\item \verb|isequal|

  Test two graphs to see if they are the same; that is, the graphs
  must have equal vertex and edge sets. They need not be the same
  object. While this can be invoked as \verb|isequal(G,H)| it is more
  convenient to use \verb|G==H|.

  Note: If the vertex type of either graph cannot be sorted by
  \verb|<| then equality testing is slower (unless fast neighhborhood
  lookup is engaged).

\item \verb|add!|

  Use this to add vertices or edges to a graph. The syntax
  \verb|add!(G,v)| adds a vertex and calling \verb|add!(G,v,w)| adds an edge.

  These return \verb|true| if the operation succeeded in adding a
  \emph{new} vertex or edge.

\item \verb|delete!|

  Use this to delete vertices or edges from a graph. The syntax
  \verb|delete!(G,v)| to delete a vertex (and all edges incident
  thereon) and \verb|delete!(G,v,w)| to delete an edge.

  Returns \verb|true| if successful. If the vertex or edge slated for
  removal was not in the graph, returns \verb|false|.

\item \verb|contract!|

  Mutates a graph by contractin an edge. Calling
  \verb|contract!(G,u,v)| adds all vertices in \verb|v|'s neighborhood
  to \verb|u|'s neighborhood and then deletes vertex
  \verb|v|. Typically \verb|(u,v)| is an edge of the graph but this is
  not necessary.

  This returns \verb|true| is the operation is successful, but
  \verb|false| if either \verb|u| or \verb|v| is not a vertex of the
  graph or if \verb|u==v|.

\item \verb|has|

  Test for the presence of a vertex of edge. Use \verb|has(G,v)| to
  test if \verb|v| is a vertex of the graph and \verb|has(G,v,w)| to
  test if the edge is present. Returns \verb|true| if so and
  \verb|false| if not.

  Note that \verb|G[v,w]| is a synonym for \verb|has(G,v,w)|.

\item \verb|vlist|

  Use \verb|vlist(G)| to get the vertex set of the graph as a
  one-dimensional array. If possible, the vertices are sorted in
  ascending order.

\item \verb|elist|

  Use \verb|elist(G)| to get the edge set of the graph as a
  one-dimensional array of 2-tuples. If possible, the edges are sorted
  in ascending lexicographic order.

\item \verb|neighbors|

  Use \verb|neighbors(G,v)| to get the set of neighbors of vertex
  \verb|v| as a one-dimensional array.

  Note that \verb|G[v]| is a synonym.

\item \verb|deg|

  Use \verb|deg(G,v)| to get the degree of vertex \verb|v| and
  \verb|deg(G)| to get the degree sequence of $G$ as a one-dimensional
  array (in decreasing order).

\item \verb|fastN!|

  This is explained in \S\ref{sect:fastN}.

  Use this to switch on \verb|fastN!(G,true)| or to switch off
  \verb|fastN!(G,false)| rapid neighborhood lookup. If off,
  neighborhood lookup can be slow. If on, the data structure
  supporting the graph is roughly tripled in size.

  The difference is especially striking when looking for paths between
  vertices with \verb|find_path|.

\item \verb|NV| and \verb|NE|

  Use \verb|NV(G)| to get the number of vertices and \verb|NE(G)| to
  get the number of edges.

\item \verb|is_connected|

  Use \verb|is_connected(G)| to determine if the graph is connected.

\item \verb|num_components|

  Use \verb|num_components(G)| to determine the number of connected
  components in the graph.

\item \verb|components|

  The function \verb|components(G)| determines the vertex sets of the
  connected components of the graph. The return value is a set of
  sets. That is, if the graph has vertex type \verb|T|, then this
  function produces a \verb|Partition| (requires \verb|SimplePartitions|).

\item \verb|find_path|

  The function \verb|find_path(G,u,v)| finds a shortest path from
  \verb|u| to \verb|v| if one exists. An empty array is returned if
  there is no such path. An error is raised if either vertex is absent
  from the graph.

\item \verb|dist| and \verb|dist_matrix|

  These are used to find distances between vertices in a graph. The
  distance between vertices $u$ and $v$ is defined to be the number of
  edges in a shortest $(u,v)$-path. If there is no such path, one
  typically says that $d(u,v)$ is undefined of $\infty$. However since
  these functions report distances as \verb|Int| values, we signal the
  absence of a $(u,v)$ path by the value $-1$.

  Use \verb|dist(G,v,w)| to find the distance between the specified
  vertices in the graph.

  Use \verb|dist(G,v)| to find the distances from vertex \verb|v| to
  all vertices in the grpah. This is returned as a \verb|Dict|.

  Use \verb|dist(G)| to find all distances between all vertices in the
  graph. For example:
  {\small
\begin{verbatim}
julia> G = Cycle(10)
SimpleGraph{Int64} (10 vertices, 10 edges)

julia> d = dist(G);

julia> d[(3,9)]
4
\end{verbatim}
  }

  The function \verb|dist_matrix| creates an $n\times n$-matrix whose
  $i,j$-entry is the distance between the $i^{\text{th}}$ and
  $j^{\text{th}}$ vertex of the graph where the order is produced by
  \verb|vlist|.

\item \verb|wiener_index|

  The function \verb|wiener_index| computes the sum of the distances
  between distinct vertices in the graph:
  \[
  \frac12 \sum_{v\in V} \sum_{w \in V} d(v,w).
  \]

\item \verb|diam|

  Compute the diameter of a graph. Note that \verb|diam(G)| returns
  $-1$ if the graph is not connected.

\item \verb|eccentricty|

  The \emph{eccentricity} of a vertex $v$ of a graph $G$ is the
  maximum distance from $v$ to another vertex of $G$.
  \verb|eccentricity(G,v)| returns this
  value, but if the graph is not connected it returns $-1$.

\item \verb|radius|

  The \emph{radius} of a graph is the minimum eccentricty of a vertex.
  \verb|radius(G)| returns $-1$ if the graph is not connected.

\item \verb|is_ayclic|

  Determine if the graph is acyclic.

\item \verb|is_cut_edge|

  Determine if a given edge is a cut edge. This can be called either
  as \verb|is_cut_edge(G,u,v)| where \verb|u| and \verb|v| are
  vertices or as \verb|is_cut_edge(G,e)| where \verb|e| is an edge
  (i.e., a 2-tuple of vertices.

  If \verb|(u,v)| is not an edge of the graph, an error is raised.

\item \verb|euler|

  This is used to find Eulerian trails and tours in a graph. Typical
  call is \verb|euler(G,u,v)| to find an Eulerian trail starting at
  \verb|u| and ending at \verb|v|.  The first element of that arrary
  is \verb|u| and the last is \verb|v|. If a trail is found, the
  length of the array is \verb|NE(G)+1|. Otherwise, an empty array is
  returned.

  The graph may have isolated vertices, and these are ignored.

  The call \verb|euler(G,u)| is shorthand for \verb|euler(G,u,u)|. A
  simple call to \verb|euler(G)| will attempt to find an Euler tour
  from some vertex in the graph.

  If the graph is edgeless, then \verb|euler(G,u)| and
  \verb|euler(G,u,u)| return the 1-element array \verb|[u]|. Calling
  \verb|euler(G)| will pick \verb|u| for you.  An empty array is
  returned if the graph has no vertices. (This is mildly unfortunate
  as an empty array indicates failure to find a trail for nonempty
  graphs.)

\item \verb|bipartition| and \verb|two_color|

  Used to find a bipartition or two-coloring of a graph if the graph
  is bipartite; otherwise, return an error. The function
  \verb|bipartition| returns a \verb|Partition| with the two
  color classes.
  The function
  \verb|two_color| returns a map (\verb|Dict|) from the vertex set to
  the set $\{1,2\}$.
  {\small
\begin{verbatim}
julia> G = Cycle(6)
SimpleGraph{Int64} (6 vertices, 6 edges)

julia> two_color(G)
[5=>1,4=>2,6=>2,2=>2,3=>1,1=>1]

julia> bipartition(G)
{{2,4,6},{1,3,5}}
\end{verbatim}
  }

\item \verb|girth| and \verb|girth_cycle|

  Determine the girth of a simple graph and find a shortest cycle
  in that graph. If the graph is acyclic, \verb|girth| returns
  \verb|0| and \verb|girth_cycle| returns an empty array.

\item \verb|greedy_color| and \verb|random_greedy_color|

  This is a simple graph coloring function. Given an ordering of the
  vertices of the graph, \verb|greedy_color| creates a proper, greedy
  coloring. If the ordering is not provided, then a degree-decreasing
  ordering is given. Use \verb|greedy_color(G,seq)| where \verb|seq|
  is a permutation of the vertex set (if you wish to specify the
  order) or simply \verb|greedy_color(G)| in which case a
  degree-decreasing ordering is used.

  The second function performs multiple greedy colorings on random
  orderings of the vertex set. Use \verb|random_greedy_color(G,nreps)|
  where \verb|nreps| is the number of random orders generated.

  In all cases a \verb|Dict| is returned that maps the vertex set to a
  range of the form \verb|[1:k]|.

\end{itemize}

\subsection*{Graph matrices}

These functions return standard matrices associated with graphs.

\begin{itemize}
\item \verb|adjacency|

  Use \verb|adjacency(G)| to return the adjacency matrix of the graph.

\item \verb|laplace|

  Use \verb|laplace(G)| to return the Laplacian matrix of the graph.

\item \verb|incidence|

  Use \verb|incidence(G)| to return the signed incidence matrix of the
  graph. This is equivalent to \verb|incidence(G,true)|. Calling
  \verb|incidence(G,false)| returns the unsigned incidence matrix.

  Assignment of $+1$ and $-1$ in each column tries to put the $+1$ on
  the vertex that sorts lower than the vertex that gets a $-1$. If the
  vertices are not comparable by \verb|<| (less than), the assignment
  is unpredictable.

  Note that \verb|incidence| returns a sparse matrix. Use
  \verb|full(incidence(G))| if a full-storage matrix is desired.
\end{itemize}

\subsection*{Converting}

\textbf{Note}: The feature is currently turned off because of
errors generated by the \verb|Graphs| module.

This is explained in \S\ref{sect:convert}.

\begin{itemize}
\item \verb|convert_simple|

  Use \verb|convert_simple(G)| to create a Julia
  \verb|Graphs.simple_graph| version of a graph, together with
  dictionaries to translate between one vertex set and the other.
\end{itemize}

\section{Errors and gotchas}

\subsection*{Errors raised}
The functions in the \verb|SimpleGraphs| module generally do not
raise errors. Function such as \verb|add!| and \verb|delete!| return
\verb|false| if the graph is not changed by the requested
modification.

However, there are some instances in which an error might be raised.
\begin{itemize}
\item An error is raised if one attempts to add a vertex of a type
  that is incompatible with the vertex type of the graph. Here's an
  example:
\begin{verbatim}
julia> G = StringGraph()
SimpleGraph{String} (0 vertices, 0 edges)

julia> add!(G,4)
ERROR: no method convert(Type{String},Int64)
\end{verbatim}

\item An error is raised if one attempts to find the neighborhood or
  the degree of a vertex that is not in the graph. Here's an example:
\begin{verbatim}
julia> G = Complete(5)
SimpleGraph{Int64} (5 vertices, 10 edges)

julia> G[6]
ERROR: Graph does not contain requested vertex
\end{verbatim}

\item An error is raised if one attempts to create a cycle with fewer
  than three vertices.
\end{itemize}

Of course, code can be wrapped in a \verb|try|-\verb|catch| block to
handle these possibilities gracefully.

\subsection*{Please specify the vertex type}
Although \verb|G=SimpleGraph()| allows \verb|Any| type vertex, we
recommend specifying the type of vertex desired. Here's why.

Because we do not allow loops, the code for \verb|add!(G,v,w)| first
checks if \verb|v==w| and if so, does not add the edge and returns the
value \verb|false|. So far so good.

Internally, the vertices of the graph are held in a Julia \verb|Set|
container. Now \verb|Set| either does or does not contain a given
object; the object cannot be in the \verb|Set| twice. Where this gets
us into a bit of trouble is that the integer value \verb|1| and the
floating point value \verb|1.0| are different objects and therefore
may cohabit the same \verb|Set|. Here's an illustration:
\begin{verbatim}
julia> A = Set()
Set{Any}()

julia> push!(A,1)
Set{Any}(1)

julia> push!(A,1.0)
Set{Any}(1.0,1)
\end{verbatim}
The implication of this is that the vertex set of a \verb|SimpleGraph|
might contain both the integer \verb|1| and the floating point number
\verb|1.0|. However, we cannot add an edge between these two vertices
because the test \verb|1==1.0| returns \verb|true|.

Here's how this plays out:
\begin{verbatim}
julia> G = SimpleGraph()
SimpleGraph{Any} (0 vertices, 0 edges)

julia> add!(G,1)
true

julia> has(G,1.0)
false

julia> add!(G,1.0)
true

julia> add!(G,1,1.0)
false
\end{verbatim}

In principle, we could fix this problem by using a more liberal filter
in \verb|add!(G,v,w)| that allows the addition of an edge with
\verb|v==w| provided \verb|typeof(v)| and \verb|typeof(w)| are
different. But that would not entirely solve the problem.

Consider this example:
\begin{verbatim}
julia> G = SimpleGraph()
SimpleGraph{Any} (0 vertices, 0 edges)

julia> add!(G,1)
true

julia> add!(G,BigInt(1))
true

julia> vlist(G)
2-element Array{Any,1}:
 1
 1
\end{verbatim}
It appears that the number 1 is in the vertex set twice!

The preferred solution is to avoid using \verb|G=SimpleGraph()|
and, instead, to use \verb|G=SimpleGraph{T}()| where \verb|T| is the
data type of the vertices. The ready-to-use \verb|IntGraph| and
\verb|StringGraph| are handy for these popular vertex types.
\begin{verbatim}
julia> G = IntGraph()
SimpleGraph{Int64} (0 vertices, 0 edges)

julia> add!(G,1)
true

julia> add!(G,BigInt(1))
ERROR: 1 is not a valid key for type Int64

julia> add!(G,1.0)
ERROR: 1.0 is not a valid key for type Int64
\end{verbatim}

\subsection*{Unsortable vertex types}

Edges in a \verb|SimpleGraph| are held as a tuple. If the end points
of the edge can be compared using the \verb|<| operator, then the
smaller end point comes first in the pair. Otherwise, the order is
arbitrary. In the latter case, graph equalty checking is slower.

In general, it's best to specify vertex types for graphs, preferring
\verb|SimpleGraph{T}()| for some type \verb|T| that supports \verb|<|
comparison.

\section{Convert to Graphs.jl}
\label{sect:convert}

\textbf{Note}: The feature is currently turned off because of
errors generated by the \verb|Graphs| module.

The \verb|Graphs| module defined in \verb|Graphs.jl| is another tool
for dealing with graphs. We provide the function \verb|convert_simple|
to convert a graph from a \verb|SimpleGraph| to a
\verb|simple_graph| type graph from the \verb|Graphs| module
distributed with Julia.

A \verb|simple_graph|'s vertex set is always of the form \verb|1:n|,
so the output of \verb|convert_simple| provides two dictionaries for
mapping from the vertex set of the \verb|SimpleGraph| to the vertex set
of the \verb|simple_graph|, and back again.

\section{Results Caching}
\label{sect:cache}

Some graph-theoretic computations can be expensive. To avoid computing
the same item twice for a given graph, the results of these
calculations are saved in a data structure attached to the graph. Note
that any change to the graph will automaticaly clear the cache.

Some values held in the cache may be mutable Julia objects. Such
objects are deep copied when fetched from the cache.

The following functions are available to the user to manipulate the
cache.

\begin{itemize}
\item \verb|cache_clear(G)|: Removes all items held in the cache.

\item \verb|cache_clear(G,item)|: Remove a specific item from the
  cache. The variable \verb|item| is a \verb|Symbol| whose name
  corresponds to the function it caches (for example,
  \verb|:components| or \verb|:girth|).

\item \verb|cache_on(G)|: Enable the caching system for this graph.

\item \verb|cache_off(G)|: Disable the caching system for this graph.
  Note thie does not wipe the graph's cache, so to save space, also
  use \verb|cache_clear(G)|.

\item \verb|cache_check(G,item)|: See if there is a value associated
  with the symbol \verb|item| held in the graph's cache.

\item \verb|cache_recall(G,item)|: Copy a value associated with the
  symbol \verb|item| from the cache. \textbf{Warning}: If there is
  no such symbol held in the cache an error will be thrown. Be sure
  to first check using \verb|cache_check|.

\end{itemize}

\end{document}


% !TEX program = pdflatex
\documentclass{tufte-handout}

\title{\centering PHY202: Statistical Physics}
\author{Aditya Dev}

\date{\today} % without \date command, current date is supplied

%\geometry{showframe} % display margins for debugging page layout

\usepackage{graphicx} % allow embedded images
  \setkeys{Gin}{width=\linewidth,totalheight=\textheight,keepaspectratio}
\usepackage{amsmath}  % extended mathematics
\usepackage{booktabs} % book-quality tables
\usepackage{units}    % non-stacked fractions and better unit spacing
\usepackage{multicol} % multiple column layout facilities
\usepackage{lipsum}   % filler text
\usepackage{fancyvrb} % extended verbatim environments
  \fvset{fontsize=\normalsize}% default font size for fancy-verbatim environments

% Standardize command font styles and environments
\newcommand{\doccmd}[1]{\texttt{\textbackslash#1}}% command name -- adds backslash automatically
\newcommand{\docopt}[1]{\ensuremath{\langle}\textrm{\textit{#1}}\ensuremath{\rangle}}% optional command argument
\newcommand{\docarg}[1]{\textrm{\textit{#1}}}% (required) command argument
\newcommand{\docenv}[1]{\textsf{#1}}% environment name
\newcommand{\docpkg}[1]{\texttt{#1}}% package name
\newcommand{\doccls}[1]{\texttt{#1}}% document class name
\newcommand{\docclsopt}[1]{\texttt{#1}}% document class option name
\newenvironment{docspec}{\begin{quote}\noindent}{\end{quote}}% command specification environment
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% add numbers to chapters, sections, subsections
\setcounter{secnumdepth}{2}
\usepackage{xcolor}
\definecolor{g1}{HTML}{077358}
\definecolor{g2}{HTML}{00b096}
% chapter format  %(if you use tufte-book class)
%\titleformat{\chapter}%
%{\huge\rmfamily\itshape\color{red}}% format applied to label+text
%{\llap{\colorbox{red}{\parbox{1.5cm}{\hfill\itshape\huge\color{white}\thechapter}}}}% label
%{2pt}% horizontal separation between label and title body
%{}% before the title body
%[]% after the title body

% section format
\titleformat{\section}%
{\normalfont\Large\itshape\color{g1}}% format applied to label+text
{\llap{\colorbox{g1}{\parbox{1.5cm}{\hfill\color{white}\thesection}}}}% label
{1em}% horizontal separation between label and title body
{}% before the title body
[]% after the title body

% subsection format
\titleformat{\subsection}%
{\normalfont\large\itshape\color{g2}}% format applied to label+text
{\llap{\colorbox{g2}{\parbox{1.5cm}{\hfill\color{white}\thesubsection}}}}% label
{1em}% horizontal separation between label and title body
{}% before the title body
[]% after the title body

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\usepackage{color-tufte}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\begin{document}

\maketitle% this prints the handout title, author, and date

\begin{abstract}
\noindent
I'm made these notes after following the lectures by Prof. Susskind
\end{abstract}

%\printclassoptions

\section{Entropy}\label{sec:page-layout}

We define Entropy as follows:

\begin{definition}[Entropy]\label{def:entropy}
	Suppose a system can take values from set \(\mathcal{S} = \{x_1, x_2, x_3, \ldots x_n\}\),
	with probability of
	\(x_i\) being \(\mu(x_i)\). Then the (\textit{Boltzmann}) entropy \(S\) is defined as
	\[S = -k_b \sum _{i} \mu(x_i) \log(\mu(x_i))\]
\end{definition}

Entropy can be thought of as the amount of ignorance/uncertainity that you have. It's obvious that if
probability is 1 or 0 the you are \(100 \%\) sure that a particular result will be observed or not
observed.

\begin{assume}
	If \(S_a\) and \(S_b\) be respective entropies for system A and B. Then
	\[S_{\mathrm{net}} = S_a + S_b\]
	\label{assum:entropy}
\end{assume}

Using above assumption, if we have \(N\) identical systems then the net entropy of the system is
given as \(S = -Nk_b \sum \mu_i\log(\mu_i)\)

\subsection{*On existence of Entropy}

Does entropy exists? Or is it just a mathematial formalism?

I'll try to answer it it in my own way. But for that I need to make an assumption, and
it's a fairly good assumption. Let me give an example to support my argument,
suppose we are given an experiment  of tossing a fair coin, let say \(n\) number
of times, and we are asked to count probabilities of number of getting a head or tails.

Since, the above experiment follows a Binomial distribution, we know that most number of
times we are getting equal number of heads and tails (\textit{because number of arrangement given
equal number of heads and tails is the most}). So, the assumption that we'll make is:
\begin{assume}
	Given a constraint on a system, in equilibrium, the system will exist in the state with maximum
	number of configurations (\textit{or microstates}). And state is consistent with the constraint.
\end{assume}

We'll see in Microcanonical Ensemble, the constrain on the system is energy \(E\), volume \(V\) and \(N\) the
number of particles.

Let \(\Omega(E, V, N)\) denote the possible number of microstates of the system. Let's sub-divide this
system into two non-interacting parts, call \(A\) and \(B\). So, we have:
\[\begin{gathered}
	\Omega(E, V, N) = \Omega_A(E_A, V_A, N_A)\Omega_B(E_B, V_B, N_B)\\
	E = E_A + E_B\\
	V = V_A + V_B\\
	N = N_A + N_B
\end{gathered}\]

Since, by assumption 1.2 we need to maximize the \(\Omega\). So,
\[\begin{gathered}
	\dfrac{\partial \Omega}{\partial E} = 0\\
	\dfrac{\partial (\Omega_A \Omega_B)}{\partial E} = 0
\end{gathered}\]

Since, \(E\) is constant, we can formulate the whole argument in terms of either \(E_A\) or \(E_B\).

\[\begin{gathered}
	\dfrac{\partial (\Omega_A(E_A) \Omega_B(E - E_A))}{\partial E_A} = 0\\
	\dfrac{\partial (\Omega_A(E_A))}{\partial E_A}\Omega_B(E - E_A) -
	\dfrac{\partial (\Omega_B(E - E_A))}{\partial E_A}\Omega_A(E_A) = 0\\
	\frac{1}{\Omega_A(E_A)}\dfrac{\partial (\Omega_A(E_A))}{\partial E_A} =
	\frac{1}{\Omega_B(E - E_A)}\dfrac{\partial (\Omega_B(E - E_A))}{\partial E_A}\\
	\dfrac{\partial \log(\Omega_A(E_A))}{\partial E_A} = \dfrac{\partial
	\log(\Omega_B(E - E_A))}{\partial E_A}
\end{gathered}\]

We define the quantity \(k_b\log(\Omega)\) \footnote{the factor \(k_b\) has something to do
with units}and ``Entropy'' and denote it be \(S\).
\[S = k_b\log(\Omega)\]

Hence, the entropy comes before any of the physical quantities like pressure, temperature etc.
We'll see in the next section, that how the two definition of Entropy are related.

\section{Microcanonical Ensemble}

In \textit{Microcanonical Ensemble} \footnote{\textit{An \textbf{ensemble} is a large number of points in the phase space that can be described
by a density function
\(\mu (x, p)\)}} we consider an isolated system with \(N\)
particles and energy \(E\) in a volume
\(V\). By definition, such a system exchanges neither particles nor energy with the surroundings.

Let a system consist of {\(N\) particles}, for which each particle can have \(M\) configurations
\footnote{Configurations can be the rotation angle about some axis or spin being up or down etc}.
Also, if a particle is in \(i^{th}\) state then
let the energy associated with that particle be \(\epsilon _i\).

For this system the total energy
\(E = \sum n_i \epsilon_i\), where \(n_i\) denotes the number of particles in state (\textit{
	 or configuration i
}). Hence the constrain equations on the system are:
\[\begin{gathered}
	E = \sum n_i \epsilon_i\\
	\sum n_i = N
\end{gathered}\]

In the thermodynamic limit of Statistical mechanics we usually assume \(N\) and \(V\) to be very large
(i.e \(N, V \to \infty\))
such that \(\rho = \frac{N}{V}\) is constant. In such case, we can assume that the number of particle
in each state increases proportional to \(N\). Let probability
of finding particle in \(i^{th}\) configuration being \(\mu_i\) and by the definition of probability
 we have \(\mu_i = \lim_{N \to \infty} \frac{n_i}{N}\) or \(n_i = \mu_i N\).

 Now, we can reformulate the above constrain equations in terms of probability. And we have
 \[\begin{gathered}
	 \sum \mu_i = 1 \Longleftrightarrow \sum n_i = N\tag*{1}\\
	 \sum_i N\mu_i \epsilon_i = E \Longleftrightarrow  \sum_i \mu_i \epsilon_i = \epsilon \\
 \end{gathered}\]

 We define \(\epsilon = \frac{E}{N} = \langle E \rangle\) as average energy per particle.

Let \(\Omega\) be the number of possible microstates of the system
\footnote{in our case it's the possible arrangements N particles, with exactly \(n_i\) number of particles
in \(i^{th}\)configuration}.
 If you know some basics combinatorics, then for our case \(\Omega\) is give as
 \[\begin{gathered}
	\Omega  = \frac{N!}{\Pi n_i !}\\
	\log(\Omega) = \log(N!) - \sum \log(n_i!)
 \end{gathered}\]
Now we need to introduce \textit{Stirling's Approximation}, it says for large \(N\)
\[\begin{gathered}
	N! \sim e^{-N} N^N\\
	log(N!) \sim N \log(N) - N
\end{gathered}\]

Therefore we have,
\[\begin{gathered}
	\log(\Omega) = N \log(N) - N - \sum n_i \log(n_i)  + \sum n_i \\
	\log(\Omega) = N \log(N) - N - \sum n_i \log(n_i)  + N \\
	\log(\Omega) = N \log(N) - \sum N \mu _i\log(N)  - \sum N \mu _i\log(\mu_i)\\
	\log(\Omega) = N \log(N) - N \log(N) \sum  \mu _i  - \sum N \mu_i \log(\mu_i) \\
	\log(\Omega) = -N\sum \mu_i \log(\mu_i)
\end{gathered}\]

Buy assumption 1.1 observe that  \(\boxed{S = k_b\log(\Omega) =
 -N k_b \sum \mu_i\log(\mu_i)}\). Hence, entropy of the system can also be defined as
 \(S = k_b \log(\Omega)\)\footnote{\(\Omega\) is the total number of accessible
 microstates of the system}. Also, note that \(-k_b \sum \mu_i\log(\mu_i)\)  is the entropy associated
 with each particle.

\section{Boltzmann Distribution}
\textit{In statistical mechanics and mathematics, a Boltzmann distribution
(also called Gibbs distribution) is a probability distribution or probability
 measure that gives the probability that a system will be in a
certain state as a function of that state's energy and the temperature of the system.}

We'll try to derive the Boltzmann distribution from Microcanonical ensemble. The Boltzmann
distribution is the distribution that maximizes the entropy \(S = -k_b
\sum \mu_i\log(\mu_i)\) or equivalently \(S = -\sum \mu_i\log(\mu_i)\)

We need to find the probability distribution of the system under the given constrains, such that
the entropy is maximum Hence, we would use \href{https://en.wikipedia.org/wiki/Lagrange_multiplier}{Lagrange
multiplier}.

Let
\[\begin{gathered}
	F(\{\mu_i\}) = - \sum \mu_i \log(\mu_i) + \alpha (1 -
\sum \mu_i) + \beta (\epsilon - \sum \mu_i \epsilon_i) \\
= - \sum \mu_i \log(\mu_i) + \alpha G(\{\mu_i\}) + \beta G'(\{\mu_i\}) \tag*{2}
\end{gathered}\]
where \(G'(\{\mu_i\}) = 0 \ \& \ G(\{\mu_i\}) = 0\) are constrain equations\footnote{
	there was no need for them but, it looks trippy, and that's how mathematicians do it.
}.

To maximize, differentiate (2) w.r.t \(\mu_i\) and equate to \(0\), we get
\[\begin{gathered}
	\dfrac{d F}{d \mu_i}= - \log(\mu_i) - 1 - \alpha - \beta  \epsilon_i =0 \\
	\mu_i = e^{-1 - \alpha} e^{-\beta \epsilon}\\
	\boxed{\mu_i(\vec{r}, \vec{p}) = \frac{e^{-\beta \epsilon_i(\vec{r}, \vec{p})}}{z}}
\end{gathered}\]

where \(z = e^{1 + \alpha}\). \(z\) is called the \textit{partition function}. \textbf{NOTICE, THE DEPENDENCE OF
ENERGY ON PHASE SPACE}

Substitute \(\mu_i\) in above equations and you will see that
\[\begin{gathered}
	\sum \mu_i = 1 \Longleftrightarrow \boxed{z(\beta) = \sum e^{-\beta \epsilon_i}}\\
	\sum \epsilon_i \mu_i = \epsilon \Longleftrightarrow \sum \epsilon_i
	e^{-\beta \epsilon_i} = z \epsilon
\end{gathered}\]

Also, observe that
\[\begin{gathered}
	\dfrac{\partial z(\beta)}{\partial \beta} = - \sum \epsilon_i e^{-\beta \epsilon_i}= -z\epsilon\\
	\boxed{\dfrac{\partial \log(z)}{\partial \beta} = - \epsilon}
\end{gathered}\]

Let's look at how does the Entropy looks like. We had
\[\begin{gathered}
	S = -k_b \sum \mu_i \log(\mu_i)\\
	= -\frac{k_b}{z} \sum \{ e^{-\beta \epsilon_i} \log(e^{-\beta \epsilon_i})
	- e^{-\beta \epsilon_i} \log(z)\}\\
	= \frac{k_b}{z} \sum \{ e^{-\beta \epsilon_i}{\beta \epsilon_i})
	+ e^{-\beta \epsilon_i} \log(z)\}\\
	= \beta k_b \sum \frac{e^{-\beta \epsilon_i}}{z} \epsilon_i  + k_b \log(z)
	\sum \frac{e^{-\beta \epsilon_i}}{z}\\
	\boxed{S = k_b\beta \epsilon + k_b \log(z)}
\end{gathered}\]

We define (\textit{stastical definition of temperature}) temperature as
\footnote{don't question why is that so, it is what it is}
\[\dfrac{\partial S}{\partial E} = \frac{1}{T}\]
So,

\[\begin{gathered}
	\frac{1}{T} = \dfrac{\partial S}{\partial \epsilon} = k_b \beta\\
	\beta = \frac{1}{k_b T}
\end{gathered}\]

So, finally everything unveils it self and we get
\begin{main_equations}
\[
\begin{gathered}
	\mu_i = \frac{e^{\frac{-\epsilon_i}{k_b T}}}{z}\\
	z(T) = \sum_{i} e^{\frac{-\epsilon_i}{k_b T}}\\
	\epsilon = -\frac{\partial \log(z)}{\partial \beta} =
	k_B T^2 \frac{\partial \log(z)}{\partial T}\\
	S = \frac{\epsilon}{T} + k_b \log(z)
\end{gathered}
\]
\end{main_equations}

\subsection{Relation to thermodynamic variables}

We know variance is defined as :
\[\begin{gathered}
	\langle (\Delta X)^2 \rangle= \left\langle (X - \langle X\rangle)^2\right \rangle\\
	 = \langle X^2 \rangle - (\langle X \rangle)^2
\end{gathered}\]

We calculate:
\[\begin{gathered}
	\langle E \rangle = \epsilon = -\frac{\partial \log(z)}{\partial \beta}\\
	\langle E \rangle = \frac{1}{z}\sum_i e^{-\beta E_i} E_i ^2 \\
	= \frac{1}{z} \frac{\partial^2 z}{\partial^2 \beta}
\end{gathered}\]

So, \(\langle (\Delta E)^2 \rangle\) is:
\[\begin{gathered}
	\langle (\Delta E)^2 \rangle = \frac{1}{z} \frac{\partial^2 z}{\partial^2 \beta}
	- \left(-\frac{1}{z} \frac{\partial z}{\partial\beta}\right)^2\\
	=  \frac{\partial^2 \log(z)}{\partial^2 \beta} + \left(\frac{1}{z}
	\frac{\partial z}{\partial\beta}\right)^2
	-\left(\frac{1}{z} \frac{\partial z}{\partial\beta}\right)^2\\
	= \frac{\partial^2 \log(z)}{\partial^2 \beta}\\
	= - \dfrac{\partial \langle E \rangle}{\partial \beta}
\end{gathered}\]
or we can write it as
\[\begin{gathered}
	\langle (\Delta E)^2 \rangle = - \dfrac{\partial \langle E \rangle}{\partial \beta}\\
	= - \dfrac{\partial \langle E \rangle}{\partial T}\dfrac{\partial T}{\partial \beta}\\
	= k_b T^2\dfrac{\partial \langle E \rangle}{\partial T}\\
	= k_b T^2 C_v\\
	\text{or}\\
	\boxed{C_v = \frac{1}{k_b T^2} \langle (\Delta E)^2 \rangle}
\end{gathered}\]
where \(C_v\) is the heat capacity at constant volume\footnote{it's heat capacity at ``constant volume"
because we are talking about Microcanonical
ensemble.}.

Observe that:
\[A =  E - TS= -k_b T \log(z)\]

where \(A\) is the helmholtz free energy\footnote{it's the definition}.

We define pressure \(P\) to be:
\[\begin{gathered}
	P = \left. -\dfrac{\partial E}{\partial V} \right|_{S}
= \left. -\dfrac{\partial A}{\partial V} \right|_{T}\\
\boxed{P =  k_b T \left (\dfrac{\partial \log(z)}{\partial V} \right ) _{T} } \tag*{1}
\end{gathered}\]
\subsection{*Meaning of Partition Function}

\textit{Source: Wikipedia}

It may not be obvious why the partition function, as we have defined it above, is an important
quantity. First, consider what goes into it. The partition function is a function of the temperature
\(T\) and the microstate energies \(\epsilon_1, \epsilon_2, \epsilon_3, \) etc.
The microstate energies are determined by other
thermodynamic variables, such as the number of particles and the volume, as well as microscopic
quantities like the mass of the constituent particles. This dependence on microscopic variables
is the central point of statistical mechanics. With a model of the microscopic constituents of
a system, one can calculate the microstate energies, and thus the partition function, which will
then allow us to calculate all the other thermodynamic properties of the system.

The partition function can be related to thermodynamic properties because it has a very important
 statistical meaning. The probability \(\mu_i\) that the system occupies microstate \(i\) is

    \[\mu_i = \frac{1}{z} \mathrm{e}^{- \beta \epsilon_i}\]

Thus, as shown above, the partition function plays the role of a normalizing constant
(note that it does not depend on i), ensuring that the probabilities sum up to one:

    \[\sum_i \mu_i = \frac{1}{z} \sum_i \mathrm{e}^{- \beta \epsilon_i} = \frac{1}{z} z = 1\]

This is the reason for calling \(z\) the ``partition function": it encodes how the probabilities
are partitioned among the different microstates, based on their individual energies.
The letter \(z\) stands for the German word \textit{Zustandssumme}, ``sum over states". The usefulness
of the partition function stems from the fact that it can be used to relate macroscopic
thermodynamic quantities to the microscopic details of a system through the derivatives
of its partition function. Finding the partition function is also equivalent to performing a
Laplace transform of the density of states function from the energy domain to the \(\beta\) domain,
and the inverse Laplace transform of the partition function reclaims the state density function
of energies.

\section{The Ideal Gas}

\subsection{Introduction}
Suppose a system is made of N sub-systems (\textit{particles}) with negligible interaction energy, that is,
we can assume the particles are essentially non-interacting. If the partition functions of the
sub-systems are \(\zeta_1, \zeta_2, \ldots \zeta _N,\) respectively then the partition function
of the entire system is the product
of the individual partition functions:

    \[z =\prod_{j=1}^{N} \zeta_j.\]

If the sub-systems have the same physical properties, then their partition functions
 are equal, \(\zeta_1, \zeta_2, \ldots \zeta _N,\) in which case

    \[z = \zeta^N\]

However, there is a well-known exception to this rule. If the sub-systems
are actually identical particles, in the quantum mechanical sense that they
are impossible to distinguish even in principle, the total partition function
must be divided by a \(N!\)\footnote{This is to ensure that we do not ``over-count"
the number of microstates. }:

    \[z = \frac{\zeta^N}{N!}\]

While this may seem like a strange requirement, it is actually necessary
to preserve the existence of a thermodynamic limit for such systems.
This is known as the Gibbs paradox.
\subsection{The partition function for ideal gas}

If you have taken an introductory probability theory course, then you may know in continuous
case, PMF (probability mass function) is replaced by PDF (probability density function).

In classical mechanics, the position and momentum variables of a particle can vary continuously,
so the set of microstates is actually uncountable. In classical statistical mechanics, it is
rather inaccurate to express the partition function as a sum of discrete terms.
In this case we must describe the partition function using an integral rather than a sum.

We'll assume the systen to be non-interacting.
The partion function for single particle (assuming it to a subsystem) is defined as\footnote{
	To make it into a dimensionless quantity, we must divide it by h, it also has something to do with
	the precision with which we can measure the position and momenta in phase space.
}:
\[\begin{gathered}
	\zeta = \frac{1}{h^3}\int_p \int_x e^{-\beta E(x, p)} d^3x d^3p
\end{gathered}\]

For non-interating particles energy is due to momentum only. So, it implies:
\[\begin{gathered}
	\zeta = \frac{1}{h^3}\int_p \int_x e^{-\beta \frac{p^2}{2m}} d^3x d^3p\\
	 = \frac{1}{h^3} \int_x d^3 x \int_p e^{-\beta \frac{p^2}{2m}}d^3p\\
	 = \frac{V}{h^3}  \int_p e^{-\beta \frac{p^2}{2m}}d^3p \tag*{a}
	 %%\left(\frac{2\pi m}{\beta}\right)^{3/2}
\end{gathered}\]

observe that \(p^2 = p_x ^2 + p_y ^2 + p_z ^2\) and \(d^3 p= d p_x dp_y dp_z\).
We'll make an assumption

\begin{assume}[Equipartition theorem]
	Energy is distributed equally among all the degrees of freedom.
	In other words if total energy is \(E\) and there are \(d\) degree of freedom. Then each
	degree of freedom contains \(\frac{E}{d}\) amount of energy.
\end{assume}

The above form of \(p^2\) becomes \(p^2 = 3 \bar{p} ^2\) and \(d^3 p = (d \bar{p})^3\). And equation
\ref{a} becomes
\[\begin{gathered}
	\zeta = \frac{V}{h^3}  \int_p e^{-\beta \frac{p^2}{2m}}d^3p \\
	= \frac{V}{h^3} \left(\int_p e^{-\beta \frac{\bar{p}^2}{2m}}d \bar{p}\right)^3\\
	\zeta = \frac{V}{h^3}\left(\frac{2\pi m}{\beta}\right)^{3/2}
\end{gathered}\]

Hence, we have taken an ideal gas consisting of identical \(N\) particles.
The partition function for the whaole system is
\[\begin{gathered}
	z = \frac{(\zeta)^N}{N!}\\
	z = \frac{V^N}{h^{3N}N!}\left(\frac{2\pi m}{\beta}\right)^{3N/2}\\
	\log(z) = N \log(V) + \frac{3N}{2}
\log(2\pi m)-  \frac{3N}{2}\log(\beta) - \log(N!) - 3N\log(h)\end{gathered}\]
Energy for the system is
\[\begin{gathered}
	E = - \frac{\partial \log(z)}{\partial \beta} \\
	= \frac{3N}{2\beta} \\
	\boxed{E = \frac{3N}{2} k_b T}
\end{gathered}\]

Don't forget the Pressure from equation (i):
\[\begin{gathered}
	P = k_b T \left (\dfrac{\partial \log(z)}{\partial V} \right ) _{T}\\
	P = k_b T \frac{N}{V} \implies \boxed{PV = N k_b T}
 \end{gathered}\]
\end{document}

PHY202: Statistical-Mechanics and Thermodynamics/PHY202_-_Statistical Mechanics.tex