We have already seen that given any logical expression $L$ with $n$ variables we can form a truth table with precisely $2^n$ rows documenting the output of $L$ when it is evaluated at each possible input. Now we want to answer the reverse question: if we have a table $Y$ of the format of a truth table with $2^n$ rows documenting some possible output with each input of $n$ variables, then is there a logical expression involving all $n$ variables and some of the binary logical operators introduced earlier for which its truth table is exactly the table $Y$? It turns out that this answer is yes, and in this section we will see why.

\subsection{The $\land$ as an indicator function}

Suppose that $x_1, \dots, x_n$ are our boolean variables under consideration. Then the logical expression
\[L \equiv x_1 \land x_2 \land \cdots \land x_n\] evaluates to $T$ only if every variable $x_k$ is set to $T$. So $L$ can be seen as an indicator function which is true on only one possible input of logical variables. But what if I wanted an expression which evaluates to $T$ only if every variable except $x_1$ is set to $T$? This is not too much of a problem either, since the expression
\[K \equiv (\shortsim x_1) \land x_2 \land\cdots \land x_n\] evaluates to $T$ in this case and $F$ otherwise. With these two examples it is clear how to make an ``indicator function'' which evaluates to true given one assignment of random variables and false otherwise. Simply take the expression
%I need to think up better notation than this here..
\[\bigwedge\limits_{x_k \rightarrow F}(\shortsim x_k) \land \bigwedge\limits_{x_j \rightarrow T}x_j\]
where the big $\land$ represents a logical and over all the variables in question where we want the variables to be $F$ or $T$. It is clear that this expression evaluates to $T$ only one one choice of variable assignment.

\subsection{The $\lor$ as a join function}

So far we have demonstrated how to represent any truth table $Y$ with exactly one row of the table evaluating to $T$ as a logical expression. However, what about the rest? The remaining questions can be answered once we consider the act of conjoining equations using the $\lor$ operator.

First consider the logical expression $L$ in the previous subsection. For any other logical expression $M$, consider the logical expression $L \lor M$. One thing we can say about $L \lor M$ is that it evaluates to true when every variable $x_k$ is set to $T$. We don't know that much about its evaluation at any of the other variables though. If instead we considered the logical expression $L \lor K$, where $K$ was defined in the previous section, then we see that $L \lor K$ evaluates to $T$ at exactly two assignments, precisely those that made $L$ and $K$ evaluate to $T$.

Using these two concepts it is now clear how to represent any truth table $Y$ using a logical expression. First, consider for which assignments of variables $Y$ evaluates to $T$. For these assignments create indicator $\land$ expressions $L_j$ which evaluate to true only when we have that specific variable assignment. Finally, take all such expressions $L_j$ and conjoin them with $\lor$ expressions to create a final expression.

\begin{example}
Consider the following truth table:

\begin{table}[h]
\centering
\begin{tabular}{|l|l|l|}
\hline
$p$ & $q$ & ??\\ \hline
$T$ & $T$ & $T$ \\ \hline
$T$ & $F$ & $F$ \\ \hline
$F$ & $T$ & $T$ \\ \hline
$F$ & $F$ & $F$ \\ \hline
\end{tabular}
\end{table}

We will create a logical expression whose truth table is the same as this truth table. Note that the this table only evaluates to true when $p \equiv T, q \equiv T$, and $p \equiv F, q \equiv T$. The associated indicator $\land$ functions for these assignments are $p \land q$ and $(\shortsim p) \land q$. Hence the final expression whose truth table is equal to the above truth table is
\[(p \land q) \lor ((\shortsim p) \land q).\]
\end{example}

One can see that the process described above will always generate a logical expression whose truth table is equivalent to the given truth table. To see this, we observe that the expression we generate is several indicator expressions linked up with the $\lor$ operator. If any one of these is true, then the whole expression is true. Conversely, if an assignment of variables goes to false in the original truth table then it does not match any of the indicator expressions, so the whole logical expression evaluates to false. The final expression that we obtain is said to be in \textbf{disjunctive normal form}.

\subsection{Using $\lor$ as an indicator function instead}

Note that given $n$ boolean variables $x_1, \dots, x_n$, the expression
\[x_1 \lor \cdots \lor x_n\] evaluates to $T$ for all variable assignments except for the assignment where every boolean variable is assigned $F$. Using similar ideas to the first subsection, we can create indicator logical expressions where every assignment evaluates to true except for one. To create a general expression we can take such indicator expressions and join them together with $\land$ taking in mind that any logical expression $L$ will satisfy
\[L \land F \equiv F.\]
The resulting expression obtained is said to be in \textbf{conjunctive normal form}.


Suppose the discretization of a boundary value problem, such as the Poisson equation, leads to the matrix equation
\begin{align*}
uA + Bu = f,
\end{align*}
that needs to be solved for $u$. Here $u$ is $n \times m$, $A$ is $m \times m$, $B$ is $n \times n$, and $f$ is $n \times m$.

\begin{questions}

\question{Assuming both $A$ and $B$ are non-defective matrices, with $A = V_A \Lambda_AV_A^{-1}$ and $B = V_B \Lambda_BV_B^{-1}$, show that the solution $u$ is given by $u = V_B UV_A^{-1}$, where
\begin{align*}
U_{i,j} = \frac{F_{i,j}}{\alpha_j + \beta_i},
\end{align*}
$F = V_B^{-1}fV_A$, and $\alpha_k$ and $\beta_k$ are the diagonal entries of $\Lambda_A$ and $\Lambda_B$ respectively.
 }

\begin{solution}

We begin with,
\begin{align*}
& uA + Bu = f \\
\Rightarrow ~& uV_A \Lambda_AV_A^{-1} + V_B \Lambda_BV_B^{-1} u = f~.
\end{align*}
We then multiple the entire equation by $V_B^{-1}$ from the left and $V_A$ from the right to obtain,
\begin{align*}
V_B^{-1}uV_A\Lambda_A + \Lambda_B V_B^{-1} u V_A = V_B^{-1} f V_A~.
\end{align*}
Then let $U = V_B^{-1}uV_A$ and $F = V_B^{-1} f V_A$ so that,
\begin{align*}
U\Lambda_A + \Lambda_B U = F~.
\end{align*}
Which in matrix form,
\begin{align*}
&\begin{bmatrix}
\tilde{u}_{11}& \cdots & \tilde{u}_{1m} \\
\tilde{u}_{21}& \cdots & \tilde{u}_{2m} \\
\vdots& ~ & \vdots \\
\tilde{u}_{n1}& \cdots & \tilde{u}_{nm}
\end{bmatrix} \begin{bmatrix}
\alpha_1 & 0 & \cdots & 0 \\
0 & \alpha_2 & ~ & \vdots \\
\vdots & ~& \ddots & ~ \\
0 & \cdots & 0 & \alpha_m
\end{bmatrix} + \begin{bmatrix}
\beta_1 & 0 & \cdots & 0 \\
0 & \beta_2 & ~ & \vdots \\
\vdots & ~& \ddots & ~ \\
0 & \cdots & 0 & \beta_m
\end{bmatrix}\begin{bmatrix}
\tilde{u}_{11}& \cdots & \tilde{u}_{1m} \\
\tilde{u}_{21} & \cdots & \tilde{u}_{2m} \\
\vdots& ~ & \vdots \\
\tilde{u}_{n1} & \cdots & \tilde{u}_{nm}
\end{bmatrix} = \begin{bmatrix}
\tilde{f}_{11} & \cdots & \tilde{f}_{1m} \\
\tilde{f}_{21} & \cdots & \tilde{f}_{2m} \\
\vdots & ~ & \vdots \\
\tilde{f}_{n1} & \cdots & \tilde{f}_{nm}
\end{bmatrix}~,
\end{align*}
shows us,
\begin{align*}
 \begin{cases} \tilde{u}_{11}\alpha_1 + \beta_1 \tilde{u}_{11} = \tilde{f}_{11} \\ \tilde{u}_{12}\alpha_2 + \beta_1 \tilde{u}_{12} = \tilde{f}_{12} \\ \vdots \end{cases} \Rightarrow ~U_{i,j} = \frac{F_{i,j}}{\alpha_j + \beta_i}~.
\end{align*}
Then, to get back our solution, we use $u = V_B U V_A^{-1}$.

\end{solution}

\question{Using part (a), solve the Poisson equation $\Delta u = \sin(x)\cos(100y)$ on $[0,1] \times [0,1]$ (with zero Dirichlet boundary conditions) using 100 points in the $x$ direction and 300 in the $y$ direction. Estimate the accuracy of your solution.
}

\begin{solution}

Following the exact scheme above, we obtain a solution for $u$ depicted in the figure below,

\begin{figure}[H]
\center{\includegraphics[scale=.5]{P2F2.eps}}
\caption{Surface of $u$}
\end{figure}

The error, found by comparing $uD2A + D2Bu$ and $f$, where $D2A$ and $D2B$ are the centered finite difference matrices for $x$ and $y$ respectively, is $2.2451e-12$.

\end{solution}

\end{questions}

\subsubsection*{MATLAB}

    \begin{verbatim}
% % Laplacian with zero BCs
m = 100;
hA = 1/(m-1);
D2A = (gallery('tridiag',m,1,-2,1))/(hA^2);
[eVA,evalA] = eig(full(D2A)); lamA = diag(evalA);
n = 300;
hB = 1/(n-1);
D2B = (gallery('tridiag',n,1,-2,1))/(hB^2);
[eVB,evalB] = eig(full(D2B)); lamB = diag(evalB);

y = linspace(0,1,300);
x = linspace(0,1,100);
[xx,yy] = meshgrid(x,y);
f = sin(xx).*cos(100.*yy);

F = eVB'*f*eVA;

U = zeros(size(f));

for j = 1:m
    U(:,j) = F(:,j)./(lamB + lamA(j));
end

u = eVB*U*eVA';

sol = u*D2A' + D2B*u;

err = norm(sol - f,inf);

figure
plot(xx,sol(1,:),'r*',xx,f(1,:),'bo'); hold on
plot(xx,sol(2,:),'g*',xx,f(2,:),'mo')
plot(xx,sol(end,:),'k*',xx,f(end,:),'yo')
grid on

figure
surf(xx,yy,u,'EdgeColor','none')
\end{verbatim}


\section{Computer exercises for the lab}

This week is a good time for
\begin{itemize}
\item[(a)] making sure you are comfortable with the mathematics behind matrices as well as:
\item[(b)] making sure you are comfortable with the matrix operators in R.
\item[(c)]  Check that you are very very sure you can subscript R matrices, i.e. use things such as \text{[,1]} to select column 1, \text{[,-1]} to select everything \emph{except} column 1, and \text{[,2:3]} to select columns 2 and 3.
\end{itemize}

Although we will use in built multivariate analysis functions in R, you should consider checking you understand the techniques by using R as a matrix calculator.

\begin{enumerate}

\item Find (where possible) the determinants and the inverse of the following matrices:

$C_{1} = \left[ \begin {array}{cc} 4& 4\\\noalign{\medskip} 4& 4\end {array} \right]$, $C_{2} = \left[ \begin {array}{cc} 4& 4.001\\\noalign{\medskip} 4.001& 4.002\end {array} \right]$ and $C_{3} = \left[ \begin {array}{cc} 4& 4.001\\\noalign{\medskip} 4.001& 4.002001\end {array} \right] $

Very briefly comment on the magnitude of the difference between $C_{2}^{-1}$ and  $C_{3}^{-1}$ given the only difference between $C_{2}$ and $C_{2}$ amounts to a difference of $0.000001$ in the bottom right position.

\begin{Schunk}
\begin{Sinput}
> A <- matrix(c(4, 4, 4, 4), 2, 2)
> A
> det(A)
> try(solve(A))
> B <- matrix(c(4, 4.001, 4.001, 4.002), 2, 2)
> B
> det(B)
> solve(B)
> C <- matrix(c(4, 4.001, 4.001, 4.002001), 2, 2)
> C
> det(C)
> solve(C)
\end{Sinput}
\end{Schunk}

\begin{itemize}
  \item What's going on here?
\end{itemize}

\textit{Note that A is singular, the determinant is zero and it can't be inverted.   Also note that the inverses of B and C are very very different - but this is something of a pathological example}

\item Matrix partitioning.   Consider Sterling's financial data held in the R object LifeCycleSavings (see \verb+?LifeCycleSavings+).   To make life a little easier, reorder the columns using \texttt{X <- LifeCycleSavings[,c(2,3,1,4,5)]}.

\begin{itemize}
\item Find the correlation matrix of \texttt{X} (longhand, using the centering matrix), call this matrix \texttt{R}

\begin{Schunk}
\begin{Sinput}
> data(LifeCycleSavings)
> X <- LifeCycleSavings[, c(2, 3, 1, 4, 5)]
> R <- cor(X)
> R
\end{Sinput}
\end{Schunk}

\item Partition \textit{R = cov(X)} following the scheme below such that $\boldsymbol{R_{11}}$ is a $2 \times 2$ matrix containing the covariance of \texttt{pop15} and \texttt{pop75}, and $\boldsymbol{R_{22}}$ contains the covariance of \texttt{sr}, \texttt{dpi} and \texttt{ddpi}

\begin{displaymath}
\boldsymbol{R} = \left( \begin{array}{l|l} \boldsymbol{R_{11}} & \boldsymbol{R_{12}} \\ \hline    \boldsymbol{R_{21}} & \boldsymbol{R_{22}} \end{array} \right)
\end{displaymath}

You should find for example that  $\boldsymbol{R_{11}}$ is given by:
 % latex table generated in R 2.3.1 by xtable 1.3-2 package
% Wed Nov 15 22:15:30 2006
\begin{table}[ht]
\begin{center}
\begin{tabular}{rrr}
\hline
 & pop15 & pop75 \\
\hline
pop15 & 83.75 & $-$10.73 \\
pop75 & $-$10.73 & 1.67 \\
\hline
\end{tabular}
\end{center}
\end{table}

\begin{Schunk}
\begin{Sinput}
> R11 <- R[1:2, 1:2]
> R12 <- R[1:2, 3:5]
> R21 <- R[3:5, 1:2]
> R22 <- R[3:5, 3:5]
> R11
> R22
> R21
> R12
> t(R21)
\end{Sinput}
\end{Schunk}

\item Find the matrix $\boldsymbol{A}$, where:

\begin{displaymath}
\boldsymbol{A} = \boldsymbol{R_{22}^{-1}R_{21}R_{11}^{-1}R_{12}}
\end{displaymath}

\begin{Schunk}
\begin{Sinput}
> A <- solve(R22) %*% R21 %*% solve(R11) %*% R12
\end{Sinput}
\end{Schunk}

%\begin{itemize}

\item Are $\boldsymbol{A}$ and $\boldsymbol{B}$ symmetric?   What is the difference between symmetric and asymmetric matrices in terms of their eigenvalues and eigenvectors?\\
\textit{Note that they are both asymmetric matrices, it just so happens for these particular matrices that the eigenvalues are positive and the eigenvectors are real.   This isn't always the case for asymmetric matrices!}

\item Find the eigenvalues and eigenvectors of $\boldsymbol{A}$ and $\boldsymbol{B}$ then find the square roots of the eigenvalues.

\begin{Schunk}
\begin{Sinput}
> eigen(B)
> sqrt(eigen(A)$values)
> sqrt(eigen(B)$values)
\end{Sinput}
\end{Schunk}

\item Do you notice any similarities between the first two eigenvalues from either matrix?\\
\textit{Note that the square roots of the eigen values are identical.}
\end{itemize}

\item Revisit the \texttt{wines} data in the \texttt{Flury} package.   Consider only Y1, Y5, Y6, Y8 and Y9, use matrix algebra to find the means, correlation and covariance of these data.   Compare the eigenvalues and eigenvectors, and the determinants and inverse you get from the covariance matrix and the correlation matrix.\\

\end{enumerate}

\section{Summary of week 2}

\fbox{\parbox[c]{0.9\textwidth}{\color{blue}

\begin{itemize}
\item We have revised, and are comfortable with matrix multiplication, matrix inverse, (normalised) eigenvalues and eigenvectors.  We can center and scale matrices.  We can do this by hand and in R.
\item We are also comfortable using R as a matrix calculator if and when we wish.
\end{itemize}
}}


\lab{Introduction to Matplotlib}{Introduction to Matplotlib}
\label{lab:Matplotlib}
\objective{
Matplotlib is the most commonly used data visualization library in Python. Being able to visualize data helps to determine patterns, to communicate results, and is a key component of applied and computational mathematics.
In this lab we introduce techniques for visualizing data in 1, 2, and 3 dimensions.
The plotting techniques presented here will be used in the remainder of the labs in the manual.
}

\section*{Line Plots} % =======================================================

Raw numerical data is rarely helpful unless it can be visualized.
The quickest way to visualize a simple 1-dimensional array is via a \emph{line plot}.
The following code creates an array of outputs of the function $f(x) = x^2$, then visualizes the array using the \li{matplotlib} module.\footnote{Like NumPy, Matplotlib is \emph{not} part of the Python standard library, but it is included in most Python distributions.}

\begin{lstlisting}
>>> import numpy as np
>>> from matplotlib import pyplot as plt

>>> y = np.arange(-5,6)**2
>>> y
array([25, 16,  9,  4,  1,  0,  1,  4,  9, 16, 25])

# Visualize the plot.
>>> plt.plot(y)                     # Draw the line plot.
<<[<matplotlib.lines.Line2D object at 0x1084762d0>]>>
>>> plt.show()                      # Reveal the resulting plot.
\end{lstlisting}

The result is shown in Figure \ref{fig:basic1}.
Just as \li{np} is a standard alias for NumPy, \li{plt} is a standard alias for \li{matplotlib.pyplot} in the Python community.

The call \li{plt.plot(y)} creates a figure and draws straight lines connecting the entries of \li{y} relative to the $y$-axis.
The $x$-axis is (by default) the index of the array, which in this case is the integers from $0$ to $10$.
Calling \li{plt.show()} then displays the figure.

\begin{figure}[H] % plt.plot(y) compared to plt.plot(x,y).
\captionsetup[subfigure]{justification=centering}
\centering
\begin{subfigure}{.5\textwidth}
    \centering
    \includegraphics[width=\linewidth]{figures/basic1.pdf}
    \caption{\li{plt.plot(y)} uses the indices of\\the array for the $x$-axis.}
    \label{fig:basic1}
\end{subfigure}%
\begin{subfigure}{.5\textwidth}
    \centering
    \includegraphics[width=\linewidth]{figures/basic2.pdf}
    \caption{\li{plt.plot(x,y)} specifies both the\\domain and the range.}
    \label{fig:basic2}
\end{subfigure}
\caption{Plots of $f(x) = x^2$ over the interval $[-5,5]$.}
\end{figure}

\begin{problem} % Law of Large Numbers / NumPy review.
NumPy's \li{random} module has tools for sampling from probability distributions.
For instance, \li{np.random.normal()} draws samples from the normal (Gaussian) distribution.
The \li{size} parameter specifies the shape of the resulting array.
\begin{lstlisting}
>>> np.random.normal(size=(2,3))    # Get a 2x3 array of samples.
array([[ 1.65896515, -0.43236783, -0.99390897],
       [-0.35753688, -0.76738306,  1.29683025]])
\end{lstlisting}
%
Write a function that accepts an integer $n$ as input.
\begin{enumerate}
\item Use \li{np.random.normal()} to create an $n\times n$ array of values randomly sampled from the standard normal distribution.
\item Compute the mean of each row of the array.
\\(Hint: Use \li{np.mean()} and specify the \li{axis} keyword argument.)
\item Return the variance of these means.
\\(Hint: Use \li{np.var()} to calculate the variance).
\end{enumerate}
Define another function that creates an array of the results of the first function with inputs $n = 100,\ 200,\ \ldots,\ 1000$.
Plot (and show) the resulting array.
% This result illustrates one version of the \emph{law of large numbers}.
\end{problem}

\subsection*{Specifying a Domain} % -----------------------------------------

An obvious problem with Figure \ref{fig:basic1} is that the $x$-axis does not correspond correctly to the $y$-axis for the function $f(x) = x^2$ that is being drawn.
To correct this, define an array \li{x} for the domain, then use it to calculate the image \li{y = f(x)}.
The command \li{plt.plot(x,y)} plots \li{x} against \li{y} by drawing a line between the consecutive points \li{(x[i], y[i])}.
% Note that the arrays must have the same number of elements to be compatible.

Another problem with Figure \ref{fig:basic1} is its poor resolution: the curve is visibly bumpy, especially near the bottom of the curve.
NumPy's \li{linspace()} function makes it easy to get a higher-resolution domain.
Recall that \li{np.arange()} return an array of evenly-spaced values in a given interval, where

% NOTE: the \noindent is to fix a page break problem in PythonEssentials.pdf.

\noindent the \textbf{spacing} between the entries is specified.
In contrast, \li{np.linspace()} creates an array of evenly-spaced values in a given interval where the \textbf{number of elements} is specified.

\begin{lstlisting}
# Get 4 evenly-spaced values between 0 and 32 (including endpoints).
>>> np.linspace(0, 32, 4)
array([  0.        ,  10.66666667,  21.33333333,  32.        ])

# Get 50 evenly-spaced values from -5 to 5 (including endpoints).
>>> x = np.linspace(-5, 5, 50)
>>> y = x**2                        # Calculate the range of f(x) = x**2.
>>> plt.plot(x, y)
>>> plt.show()
\end{lstlisting}

The resulting plot is shown in Figure \ref{fig:basic2}.
This time, the $x$-axis correctly matches up with the $y$-axis.
The resolution is also much better because \li{x} and \li{y} have $50$ entries each instead of only $10$.

Subsequent calls to \li{plt.plot()} modify the same figure until \li{plt.show()} is executed, which displays the current figure and resets the system.
This behavior can be altered by specifying separate figures or axes, which we will discuss shortly.

\begin{info} % Interactive Mode.
Plotting can seem a little mystical because the actual plot doesn't appear until \li{plt.show()} is executed.
Matplotlib's \emph{interactive mode} allows the user to see the plot be constructed one piece at a time.
Use \li{plt.ion()} to turn interactive mode on and \li{plt.ioff()} to turn it off.
This is very useful for quick experimentation.
Try executing the following commands in IPython:

\begin{lstlisting}
<g<In [1]:>g> import numpy as np
<g<In [2]:>g> from matplotlib import pyplot as plt

# Turn interactive mode on and make some plots.
<g<In [3]:>g> plt.ion()
<g<In [4]:>g> x = np.linspace(1, 4, 100)
<g<In [5]:>g> plt.plot(x, np.log(x))
<g<In [6]:>g> plt.plot(x, np.exp(x))

# Clear the figure, then turn interactive mode off.
<g<In [7]:>g> plt.clf()
<g<In [8]:>g> plt.ioff()
\end{lstlisting}

Use interactive mode \textbf{only} with IPython.
Using interactive mode in a non-interactive setting may freeze the window or cause other problems.
\end{info}

\begin{problem} % Plot two lines (sin() and cos()).
Write a function that plots the functions $\sin(x)$, $\cos(x)$, and $\arctan(x)$ on the domain $[-2\pi, 2\pi]$ (use \li{np.pi} for $\pi$).
% Call \li{plt.xlim(-2*np.pi, 2*np.pi)} before \li{plt.show()} to stretch the $x$-axis appropriately.
Make sure the domain is refined enough to produce a figure with good resolution.
\end{problem}

\section*{Plot Customization} % ===============================================

\li{plt.plot()} receives several keyword arguments for customizing the drawing.
For example, the color and style of the line are specified by the following string arguments.
%
\begin{table}[H] % Color and style.
\begin{tabular}{r|l}
    Key & Color \\
    \hline
    \li{'b'} & blue\\
    \li{'g'} & green\\
    \li{'r'} & red\\
    \li{'c'} & cyan\\
    % \li{'m'} & magenta\\
    % \li{'y'} & yellow\\
    \li{'k'} & black\\
    % \li{'w'} & white
\end{tabular}
\qquad
\begin{tabular}{r|l}
    Key & Style \\
    \hline
    \li{'-'} & solid line\\
    \li{'--'} & dashed line\\
    \li{'-.'} & dash-dot line\\
    \li{':'} & dotted line\\
    % \li{'.'} & point marker\\
    \li{'o'} & circle marker\\
    % \li{'*'} & star marker\\
    % \li{'+'} & plus marker
\end{tabular}
\end{table}
%
Specify one or both of these string codes as the third argument to \li{plt.plot()} to change from the default color and style.
Other \li{plt} functions further customize a figure.
%
\begin{table}[H]
\centering
\begin{tabular}{r|l}
    Function & Description\\
    \hline
    % \li{grid()} & Add grid lines\\
    \li{legend()} & Place a legend in the plot\\
    % \li{text()} & Add text at a given position on the plot\\
    \li{title()} & Add a title to the plot\\
    \li{xlim()} / \li{ylim()} & Set the limits of the $x$- or $y$-axis\\
    % \li{xticks()} & set the location of the tick marks on the x axis, returns current locations if no arguments are given\\
    % \li{yticks()} & set the location of the tick marks on the y axis, returns current locations if no arguments are given\\
    \li{xlabel()} / \li{ylabel()} & Add a label to the $x$- or $y$-axis\\
\end{tabular}
\end{table}

\begin{lstlisting}
>>> x1 = np.linspace(-2, 4, 100)
>>> plt.plot(x1, np.exp(x1), 'g:', linewidth=6, label="Exponential")
>>> plt.title("This is the title.", fontsize=18)
>>> plt.legend(loc="upper left")    # plt.legend() uses the 'label' argument of
>>> plt.show()                      # plt.plot() to create a legend.

>>> x2 = np.linspace(1, 4, 100)
>>> plt.plot(x2, np.log(x2), 'r*', markersize=4)
>>> plt.xlim(0, 5)                  # Set the visible limits of the x axis.
>>> plt.xlabel("The x axis")        # Give the x axis a label.
>>> plt.show()
\end{lstlisting}
%
\begin{figure}[H] % Figure customizations.
\captionsetup[subfigure]{justification=centering}
\centering
\begin{subfigure}{.49\textwidth}
    \centering
    \includegraphics[width=\linewidth]{figures/custom1.pdf}
    \label{fig:custom1}
\end{subfigure}
%
\begin{subfigure}{.49\textwidth}
    \centering
    \includegraphics[width=\linewidth]{figures/custom2.pdf}
    \label{fig:custom2}
\end{subfigure}
\label{fig:custom}
\end{figure}
%
% See Appendix \ref{mpltables} for more comprehensive lists of colors, line styles, and figure customization routines.
%
\begin{problem} % Line plots with different domains but uniform style.
Write a function to plot the curve $f(x) = \frac{1}{x-1}$ on the domain $[-2,6]$.
\begin{enumerate}
\item
Although $f(x)$ has a discontinuity at $x=1$, a single call to \li{plt.plot()} in the usual way will make the curve look continuous.
Split up the domain into $[-2,1)$ and $(1,6]$.
Plot the two sides of the curve separately so that the graph looks discontinuous at $x=1$.
\item Plot both curves with a dashed magenta line.
Set the keyword argument \li{linewidth} (or \li{lw}) of \li{plt.plot()} to $4$ to make the line a little thicker than the default setting.
\item Use \li{plt.xlim()} and \li{plt.ylim()} to change the range of the $x$-axis to $[-2,6]$ and the range of the $y$-axis to $[-6, 6]$.
\end{enumerate}
The plot should resemble the figure below.

\begin{figure}[H] % Solution.
\includegraphics[width=.5\textwidth]{figures/discontinuousProblem.pdf}
\end{figure}
\end{problem}

\subsection*{Figures, Axes, and Subplots} % -----------------------------------

The window that \li{plt.show()} reveals is called a \emph{figure}, stored in Python as a \li{plt.Figure} object.
A space on a figure where a plot is drawn is called an \emph{axes}, a \li{plt.Axes} object.
A figure can have multiple axes, and a single program may create several figures.
There are several ways to create or grab figures and axes with \li{plt} functions.

\begin{table}[H]
\centering
\begin{tabular}{r|l}
    Function & Description\\
    \hline
    \li{axes()} & Add an axes to the current figure\\
    \li{figure()} & Create a new figure or grab an existing figure\\
    \li{gca()} & Get the current axes\\
    \li{gcf()} & Get the current figure\\
    \li{subplot()} & Add a single subplot to the current figure\\
    \li{subplots()} & Create a figure and add several subplots to it\\
\end{tabular}
\end{table}

Usually when a figure has multiple axes, they are organized into non-overlapping \emph{subplots}.
The command \li{plt.subplot(nrows, ncols, plot_number)} creates an axes in a subplot grid where \li{numrows} is the number of rows of subplots in the figure, \li{numcols} is the number of columns, and \li{plot_number} specifies which subplot to modify.
If the inputs for \li{plt.subplot()} are all integers, the commas between the entries can be omitted.
For example, \li{plt.subplot(3,2,2)} can be shortened to \li{plt.subplot(322)}.

\begin{figure}[H] % The layout created by subplots(23i).
\captionsetup[subfigure]{justification=centering}
\centering
\begin{framed}
\begin{subfigure}{.32\textwidth}
    \centering
    \includegraphics[width=\linewidth]{figures/layout_1.pdf}
\end{subfigure}
%
\begin{subfigure}{.32\textwidth}
    \centering
    \includegraphics[width=\linewidth]{figures/layout_2.pdf}
\end{subfigure}
%
\begin{subfigure}{.32\textwidth}
    \centering
    \includegraphics[width=\linewidth]{figures/layout_3.pdf}
\end{subfigure}
\\
\begin{subfigure}{.32\textwidth}
    \centering
    \includegraphics[width=\linewidth]{figures/layout_4.pdf}
\end{subfigure}
%
\begin{subfigure}{.32\textwidth}
    \centering
    \includegraphics[width=\linewidth]{figures/layout_5.pdf}
\end{subfigure}
%
\begin{subfigure}{.32\textwidth}
    \centering
    \includegraphics[width=\linewidth]{figures/layout_6.pdf}
\end{subfigure}
\end{framed}
\caption{The layout of subplots with \li{plt.subplot(2,3,i)} (2 rows, 3 columns), where \li{i} is the index pictured above. The outer border is the figure that the axes belong to.}
\label{fig:subplots-layout}
\end{figure}

\begin{lstlisting}
>>> x = np.linspace(.1, 2, 200)
# Create a subplot to cover the left half of the figure.
>>> ax1 = plt.subplot(121)
>>> ax1.plot(x, np.exp(x), 'k', lw=2)
>>> ax1.plot(x, np.exp(2*x), 'b', lw=2)
>>> plt.title("Exponential", fontsize=18)

# Create another subplot to cover the right half of the figure.
>>> ax2 = plt.subplot(122)
>>> ax2.plot(x, np.log(x), 'k', lw=2)
>>> ax2.plot(x, np.log(2*x), 'b', lw=2)
>>> ax2.set_title("Logarithmic", fontsize=18)
>>> plt.show()
\end{lstlisting}

\begin{figure}[H] % The layout created by plt.subplot(23i).
\captionsetup[subfigure]{justification=centering}
\centering
\begin{framed}
\begin{subfigure}{.49\textwidth}
    \centering
    \includegraphics[width=\linewidth]{figures/subplots_1.pdf}
\end{subfigure}
%
\begin{subfigure}{.49\textwidth}
    \centering
    \includegraphics[width=\linewidth]{figures/subplots_2.pdf}
\end{subfigure}
\end{framed}
\end{figure}

\begin{info}
Plotting functions such as \li{plt.plot()} are shortcuts for accessing the current axes on the current figure and calling a method on that \li{Axes} object.
Calling \li{plt.subplot()} changes the current axis, and calling \li{plt.figure()} changes the current figure.
Use \li{plt.gca()} to get the current axes and \li{plt.gcf()} to get the current figure.
Compare the following equivalent strategies for producing a figure with two subplots.

\begin{lstlisting}
>>> x = np.linspace(-5, 5, 100)

# 1. Use plt.subplot() to switch the current.
>>> plt.subplot(121)
>>> plt.plot(x, 2*x)
>>> plt.subplot(122)
>>> plt.plot(x, x**2)

# 2. Use plt.subplot() to explicitly grab the two subplot axes.
>>> ax1 = plt.subplot(121)
>>> ax1.plot(x, 2*x)
>>> ax2 = plt.subplot(122)
>>> ax2.plot(x, x**2)

# 3. Use plt.subplots() to get the figure and all subplots simultaneously.
>>> fig, axes = plt.subplots(1, 2)
>>> axes[0].plot(x, 2*x)
>>> axes[1].plot(x, x**2)
\end{lstlisting}

% Having direct access to the axes and figures as Python objects provides a great deal of flexibility for plot customization.
% If you ever need access to the current axes for detailed customization, use \li{plt.gca()}.
\end{info}

\begin{problem} % Subplots of sine functions.
Write a function that plots the functions $\sin(x)$, $\sin(2x)$, $2\sin(x)$, and $2\sin(2x)$ on the domain $[0, 2\pi]$, each in a separate subplot of a single figure.
\begin{enumerate}
    \item Arrange the plots in a $2\times 2$ grid of subplots.
    \item Set the limits of each subplot to $[0, 2\pi]\times[-2,2]$.
    \\(Hint: Consider using \li{plt.axis([xmin, xmax, ymin, ymax])} instead of \li{plt.xlim()} and \li{plt.ylim()} to set all boundaries simultaneously.)
    \item Use \li{plt.title()} or \li{ax.set_title()} to give each subplot an appropriate title.
    \item Use \li{plt.suptitle()} or \li{fig.suptitle()} to give the overall figure a title.
    \item Use the following colors and line styles.
    \begin{align*}\begin{array}{lcl}
    \sin(x)\text{: green solid line.} && \sin(2x)\text{: red dashed line.}\\ \\
    2\sin(x)\text{: blue dashed line.} && 2\sin(2x)\text{: magenta dotted line.}
    \end{array}\end{align*}
\end{enumerate}
\end{problem}

\begin{warn}
Be careful not to mix up the following functions.
\begin{enumerate}
    \item \li{plt.axes()} creates a new place to draw on the figure, while \li{plt.axis()} (or \li{ax.axis()}) sets properties of the $x$- and $y$-axis in the current axes, such as the $x$ and $y$ limits.
    \item \li{plt.subplot()} (singular) returns a single subplot belonging to the current figure, while \li{plt.subplots()} (plural) creates a new figure and adds a collection of subplots to it.
\end{enumerate}
% The \li{subplots()} function is especially useful for figures with many subplots.
% \begin{lstlisting}
% # The subplot axes are organized in an array of the given shape.
% >>> fig, ax = plt.sublplots(2,3)
% >>> ax.shape
% (2, 3)
% >>> ax[1,1].plot([1,2,3],[4,5,6])
% # ...
% \end{lstlisting}
\end{warn}

\section*{Other Kinds of Plots} % =============================================

Line plots are not always the most illuminating choice of graph to describe a set of data.
Matplotlib provides several other easy ways to visualize data.

\begin{itemize}
\item A \emph{scatter plot} plots two 1-dimensional arrays against each other without drawing lines between the points.
Scatter plots are particularly useful for data that is not correlated or ordered.

To create a scatter plot, use \li{plt.plot()} and specify a point marker (such as \li{'o'} or \li{'*'}) for the line style, or use \li{plt.scatter()} (or \li{ax.scatter()}).
Beware that \li{plt.scatter()} has slightly different arguments and syntax than \li{plt.plot()}.

\item A \emph{histogram} groups entries of a 1-dimensional data set into a given number of intervals, called \emph{bins}.
Each bin has a bar whose height indicates the number of values that fall in the range of the bin.
% The more bins, the greater the detail, but having too many bins can also destroy the picture by creating interval gaps between values.
Histograms are best for displaying distributions, relating data values to frequency.

To create a histogram, use \li{plt.hist()} (or \li{ax.hist()}).
Use the argument \li{bins} to specify the edges of the bins, or to choose a number of bins.
The \li{<<range>>} argument specifies the outer limits of the first and last bins.
\end{itemize}

\begin{lstlisting}
# Get 500 random samples from two normal distributions.
>>> x = np.random.normal(scale=1.5, size=500)
>>> y = np.random.normal(scale=0.5, size=500)

# Draw a scatter plot of x against y, using transparent circle markers.
>>> ax1 = plt.subplot(121)
>>> ax1.plot(x, y, 'o', markersize=5, alpha=.5)

# Draw a histogram to display the distribution of the data in x.
>>> ax2 = plt.subplot(122)
>>> ax2.hist(x, bins=np.arange(-4.5, 5.5))      # Or, equivalently,
#   ax2.hist(x, bins=9, range=[-4.5, 4.5])

>>> plt.show()
\end{lstlisting}

\begin{figure}[H]
\captionsetup[subfigure]{justification=centering}
\centering
\begin{framed}
\begin{subfigure}{.49\textwidth}
    \centering
    \includegraphics[width=\linewidth]{figures/scatterplot.pdf}
\end{subfigure}
%
\begin{subfigure}{.49\textwidth}
    \centering
    \includegraphics[width=\linewidth]{figures/histogram.pdf}
\end{subfigure}
\end{framed}
\end{figure}

% On the histogram, specifying 9 bins in the range $[-4.5, 4.5]$ creates a bin centered over each integer from $-4$ to $4$.

\begin{problem} % FARS data visualization.
The Fatality Analysis Reporting System (FARS) is a nationwide census that provides yearly data regarding fatal injuries suffered in motor vehicle traffic crashes.%
\footnote{See \url{http://www.nhtsa.gov/FARS}.}
The array contained in \texttt{FARS.npy} is a small subset of the FARS database from 2010--2014.
Each of the 148,206 rows in the array represents a different car crash; the columns represent the hour (in military time, as an integer), the longitude, and the latitude, in that order.

Write a function to visualize the data in \texttt{FARS.npy}.
Use \li{np.load()} to load the data, then create a single figure with two subplots:
%
\begin{enumerate}
\item A scatter plot of longitudes against latitudes.
Because of the large number of data points, use black pixel markers (use \li{"k,"} as the third argument to \li{plt.plot()}).
Label both axes using \li{plt.xlabel()} and \li{plt.ylabel()} (or \li{ax.set_xlabel()} and \li{ax.set_ylabel()}).
\\
(Hint: Use \li{plt.axis("equal")} or \li{ax.set_aspect("equal")} so that the $x$- and $y$-axis are scaled the same way.

\item A histogram of the hours of the day, with one bin per hour.
Set the limits of the $x$-axis appropriately.
Label the $x$-axis.
You should be able to clearly see which hours of the day experience more traffic.
\end{enumerate}
\end{problem}

Matplotlib also has tools for creating other kinds of plots for visualizing 1-dimensional data, including bar plots and box plots.
See the Matplotlib Appendix for examples and syntax.

\subsection*{Visualizing 3-D Surfaces} % --------------------------------------

Line plots, histograms, and scatter plots are good for visualizing $1$- and $2$-dimensional data, including the domain and range of a function $f:\mathbb{R}\rightarrow\mathbb{R}$.
However, visualizing $3$-dimensional data or a function $g:\mathbb{R}^2\rightarrow\mathbb{R}$ (two inputs, one output) requires a different kind of plot.
The process is similar to creating a line plot but requires slightly more setup: first construct an appropriate domain, then calculate the image of the function on that domain.

NumPy's \li{np.meshgrid()} function is the standard tool for creating a 2-dimensional domain in the Cartesian plane.
Given two 1-dimensional coordinate arrays, \li{np.meshgrid()} creates two corresponding coordinate matrices.
See Figure \ref{fig:meshgrid}.

\begin{figure}[H] % np.meshgrid() visual demonstration.
\begin{tikzpicture}[>=stealth', shorten <= .1cm,shorten >=.1cm, dot/.style=
    {circle,fill=black,minimum size=3pt,inner sep=0pt, outer sep=-1pt} ]

\foreach \x/\y in {0/0, 0/2, 0/4, 2/0, 2/2, 2/4, 4/0, 4/2, 4/4}
    \node[draw, dot]at(\x,\y){};
\foreach \x/\y in {0/0, 0/1, 0/2, 1/0, 1/1, 1/2, 2/0, 2/1, 2/2}
    \node[draw=none]at(\x*2-.5, \y*2+.3){(\x,\y)};

\foreach \x/\y in {0/0, 0/1, 0/2, 1/0, 1/1, 1/2, 2/0, 2/1, 2/2}
    \node[draw=none]at(\x*.75+7, \y*.75+.1){\y};
\foreach \x/\y in {0/0, 0/1, 0/2, 1/0, 1/1, 1/2, 2/0, 2/1, 2/2}
    \node[draw=none]at(\x*.75+7, \y*-.75+3.9){\x};

\draw[-, thick](6.7,-.25)--(6.7,1.95);
\draw[-, thick](8.8,-.25)--(8.8,1.95);
\draw[-, thick](6.7,2.05)--(6.7,4.25);
\draw[-, thick](8.8,2.05)--(8.8,4.25);
\draw[-, thick](8.8,4.14)--(8.7,4.14);
\draw[-, thick](8.8,2.16)--(8.7,2.16);
\draw[-, thick](6.7,4.14)--(6.8,4.14);
\draw[-, thick](6.7,2.16)--(6.8,2.16);
\draw[-, thick](8.8,1.84)--(8.7,1.84);
\draw[-, thick](8.8,-.135)--(8.7,-.135);
\draw[-, thick](6.8,1.84)--(6.7,1.84);
\draw[-, thick](6.8,-.135)--(6.7,-.135);

\node[draw=none](X)at(6.3,.9){\texttt{Y}=};
\node[draw=none](y)at(6.3,3.15){\texttt{X}=};

\node[draw=none](point1)at(-.3, -.6){\texttt{x}=\big[0,};
\node[draw=none, node distance=2.35cm](point2)
    [right of=point1]{1,};
\node[draw=none, node distance=2cm](point3)
    [right of=point2]{2\big]};
\node[draw=none, rotate=270](point4)at(4.6,4.25)
    {\texttt{y}=\big[2,};
\node[draw=none, rotate=270, node distance=2.35cm](point5)
    [right of=point4]{1,};
\node[draw=none, rotate=270, node distance=2cm](point6)
    [right of=point5]{0\big]};
\end{tikzpicture}
\caption{\li{np.meshgrid(x, y)}, returns the arrays \li{X} and \li{Y}.
The returned arrays give the $x$- and $y$-coordinates of the points in the grid formed by \li{x} and \li{y}.
Specifically, the arrays \li{X} and \li{Y} satisfy \li{(X[i,j], Y[i,j]) = (x[i],y[j])}.}
\label{fig:meshgrid}
\end{figure}

\begin{lstlisting}
>>> x, y = [0, 1, 2], [3, 4, 5]     # A rough domain over [0,2]x[3,5].
>>> X, Y = np.meshgrid(x, y)        # Combine the 1-D data into 2-D data.
>>> for xrow, yrow in zip(X,Y):
...     print(xrow, yrow, sep='\t')
...
[0 1 2]    [3 3 3]
[0 1 2]    [4 4 4]
[0 1 2]    [5 5 5]
\end{lstlisting}

With a 2-dimensional domain, $g(x,y)$ is usually visualized with two kinds of plots.

\begin{itemize}
\item A \emph{heat map} assigns a color to each point in the domain, producing a 2-dimensional colored picture describing a 3-dimensional shape.
Darker colors typically correspond to lower values while lighter colors typically correspond to higher values.

Use \li{plt.pcolormesh()} to create a heat map.

\item A \emph{contour map} draws several \emph{level curves} of $g$ on the $2$-dimensional domain.
A level curve corresponding to the constant $c$ is the collection of points $\left\{(x,y)\mid c = g(x,y)\right\}$.
Coloring the space between the level curves produces a discretized version of a heat map.
Including more and more level curves makes a filled contour plot look more and more like the complete, blended heat map.

Use \li{plt.contour()} to create a contour plot and \li{plt.contourf()} to create a filled contour plot.
Specify either the number of level curves to draw, or a list of constants corresponding to specific level curves.
\end{itemize}

These functions each receive the keyword argument \li{cmap} to specify a color scheme (some of the better schemes are \li{"viridis"}, \li{"magma"}, and \li{"coolwarm"}).
For the list of all Matplotlib color schemes, see \url{http://matplotlib.org/examples/color/colormaps_reference.html}.

Finally, \li{plt.colorbar()} draws the color scale beside the plot to indicate how the colors relate to the values of the function.

\begin{lstlisting}
# Create a 2-D domain with np.meshgrid().
>>> x = np.linspace(-np.pi, np.pi, 100)
>>> y = x.copy()
>>> X, Y = np.meshgrid(x, y)
>>> Z = np.sin(X) * np.sin(Y)       # Calculate g(x,y) = sin(x)sin(y).

# Plot the heat map of f over the 2-D domain.
>>> plt.subplot(131)
>>> plt.pcolormesh(X, Y, Z, cmap="viridis")
>>> plt.colorbar()
>>> plt.xlim(-np.pi, np.pi)
>>> plt.ylim(-np.pi, np.pi)

# Plot a contour map of f with 10 level curves.
>>> plt.subplot(132)
>>> plt.contour(X, Y, Z, 10, cmap="coolwarm")
>>> plt.colorbar()

# Plot a filled contour map, specifying the level curves.
>>> plt.subplot(133)
>>> plt.contourf(X, Y, Z, [-1, -.8, -.5, 0, .5, .8, 1], cmap="magma")
>>> plt.colorbar()
>>> plt.show()
\end{lstlisting}

\begin{figure}[H] % heat map and contour plots.
\captionsetup[subfigure]{justification=centering}
\centering
\begin{framed}
\begin{subfigure}{.33\textwidth}
    \centering
    \includegraphics[width=\linewidth]{figures/heatmap.png}
\end{subfigure}%
\begin{subfigure}{.33\textwidth}
    \centering
    \includegraphics[width=\linewidth]{figures/contour.pdf}
\end{subfigure}%
\begin{subfigure}{.33\textwidth}
    \centering
    \includegraphics[width=\linewidth]{figures/contourf.pdf}
\end{subfigure}
\end{framed}
\end{figure}

\begin{problem} % Heat map / contour plot of a function f:R2->R.
\label{prob:heatmap}
Write a function to plot $g(x,y) = \frac{\sin(x)\sin(y)}{xy}$ on the domain $[-2\pi,2\pi] \times [-2\pi,2\pi]$.

\begin{enumerate}
\item Create 2 subplots: one with a heat map of $g$, and one with a contour map of $g$.
Choose an appropriate number of level curves, or specify the curves yourself.
\item Set the limits of each subplot to $[-2\pi,2\pi] \times [-2\pi,2\pi]$.
\item Choose a non-default color scheme.
\item Include the color scale bar for each subplot.
\end{enumerate}
\end{problem}

\begin{comment}
\begin{info} % Note about plt.imshow().
Black-and-white pictures are usually stored as a $2$-dimensional array and colord pictures are stored as a $3$-dimensional array (a stack of 2-dimensional arrays, one for each RGB value).
This kind of data does not require a domain, and is easily visualized with \li{plt.imshow()}.
\end{info}
\end{comment}

\newpage

\section*{Additional Material} % ==============================================

\subsection*{Further Reading and Tutorials} % ---------------------------------

Plotting takes some getting used to.
See the following materials for more examples.
\begin{itemize}
    \item \url{https://www.labri.fr/perso/nrougier/teaching/matplotlib/}.
    \item \url{https://matplotlib.org/users/pyplot_tutorial.html}.
    \item \url{http://www.scipy-lectures.org/intro/matplotlib/matplotlib.html}.
    \item The Matplotlib Appendix in this manual.
\end{itemize}

\subsection*{3-D Plotting} % --------------------------------------------------

Matplotlib can also be used to plot 3-dimensional surfaces.
The following code produces the surface corresponding to $g(x,y) = \sin(x)\sin(y)$.

\begin{lstlisting}
# Create the domain and calculate the range like usual.
>>> x = np.linspace(-np.pi, np.pi, 200)
>>> y = np.copy(x)
>>> X, Y = np.meshgrid(x, y)
>>> Z = np.sin(X) * np.sin(Y)

# Draw the corresponding 3-D plot using some extra tools.
>>> from mpl_toolkits.mplot3d import Axes3D
>>> fig = plt.figure()
>>> ax = fig.add_subplot(1,1,1, projection='3d')
>>> ax.plot_surface(X, Y, Z)
>>> plt.show()
\end{lstlisting}

\begin{figure}[H]
    \includegraphics[width=.7\textwidth]{figures/surface_plot.pdf}
\end{figure}

\subsection*{Animations} % ----------------------------------------------------

Lines and other graphs can be altered dynamically to produce animations.
Follow these steps to create a Matplotlib animation:
%
\begin{enumerate}
    \item Calculate all data that is needed for the animation.
    \item Define a figure explicitly with \li{plt.figure()} and set its window boundaries.
    \item Draw empty objects that can be altered dynamically.
    \item Define a function to update the drawing objects.
    \item Use \li{matplotlib.animation.FuncAnimation()}.
\end{enumerate}

The submodule \li{matplotlib.animation} contains the tools for putting together and managing animations.
The function \li{matplotlib.animation.FuncAnimation()} accepts the figure to animate, the function that updates the figure, the number of frames to show before repeating, and how fast to run the animation (lower numbers mean faster animations).

\begin{lstlisting}
from matplotlib.animation import FuncAnimation

def sine_animation():
    # Calculate the data to be animated.
    x = np.linspace(0, 2*np.pi, 200)[:-1]
    y = np.sin(x)

    # Create a figure and set the window boundaries of the axes.
    fig = plt.figure()
    plt.xlim(0, 2*np.pi)
    plt.ylim(-1.2, 1.2)

    # Draw an empty line. The comma after 'drawing' is crucial.
    drawing, = plt.plot([],[])

    # Define a function that updates the line data.
    def update(index):
        drawing.set_data(x[:index], y[:index])
        return drawing,                     # Note the comma!

    a = FuncAnimation(fig, update, frames=len(x), interval=10)
    plt.show()
\end{lstlisting}

Try using the following function in place of \li{update()}.
Can you explain why this animation is different from the original?

\begin{lstlisting}
def wave(index):
    drawing.set_data(x, np.roll(y, index))
    return drawing,
\end{lstlisting}

% \begin{comment} % Too much.
To animate multiple objects at once, define the objects separately and make sure the update function returns both objects.

\begin{lstlisting}
def sine_cosine_animation():
    x = np.linspace(0, 2*np.pi, 200)[:-1]
    y1, y2 = np.sin(x), np.cos(x)

    fig = plt.figure()
    plt.xlim(0, 2*np.pi)
    plt.ylim(-1.2, 1.2)

    sin_drawing, = plt.plot([],[])
    cos_drawing, = plt.plot([],[])

    def update(index):
        sin_drawing.set_data(x[:index], y1[:index])
        cos_drawing.set_data(x[:index], y2[:index])
        return sin_drawing, cos_drawing,

    a = FuncAnimation(fig, update, frames=len(x), interval=10)
    plt.show()
\end{lstlisting}
% \end{comment}

\begin{comment} % Too much.
Animations are very useful for describing parametrized curves, as the ``speed'' of the curve is displayed.
The code below animates the rose curve, parametrized by the angle $\theta \in [0, 2\pi]$, given by the following equations.
%
\[\begin{array}{ccc}
x(\theta) = \cos(\theta)\cos(6\theta), && y(\theta) = \sin(\theta)\cos(6\theta)
\end{array}\]

\begin{lstlisting}
def rose_animation():
    # Calculate the parametrized data.
    theta = np.linspace(0, 2*np.pi, 200)
    x = np.cos(theta)*np.cos(6*theta)
    y = np.sin(theta)*np.cos(6*theta)

    fig = plt.figure()
    plt.xlim(-1.2, 1.2)
    plt.ylim(-1.2, 1.2)
    plt.gca().set_aspect("equal")           # Make the figure exactly square.

    drawing, = plt.plot([],[])

    # Define a function that updates the line data.
    def update(index):
        drawing.set_data(x[:index], y[:index])
        return drawing,

    a = FuncAnimation(fig, update, frames=len(x), interval=10, repeat=False)
    plt.show()              # repeat=False freezes the animation at the end.
\end{lstlisting}
\end{comment}

Animations can also be 3-dimensional.
The only major difference is an extra operation to set the 3-dimensional component of the drawn object.
The code below animates the space curve parametrized by the following equations:
%
\[\begin{array}{ccccc}
x(\theta) = \cos(\theta)\cos(6\theta), &&
y(\theta) = \sin(\theta)\cos(6\theta), &&
z(\theta) = \frac{\theta}{10}
\end{array}\]

\begin{lstlisting}
def rose_animation_3D():
    theta = np.linspace(0, 2*np.pi, 200)
    x = np.cos(theta) * np.cos(6*theta)
    y = np.sin(theta) * np.cos(6*theta)
    z = theta / 10

    fig = plt.figure()
    ax = fig.gca(projection='3d')           # Make the figure 3-D.
    ax.set_xlim3d(-1.2, 1.2)                # Use ax instead of plt.
    ax.set_ylim3d(-1.2, 1.2)
    ax.set_aspect("equal")

    drawing, = ax.plot([],[],[])            # Provide 3 empty lists.

    # Update the first 2 dimensions like usual, then update the 3-D component.
    def update(index):
        drawing.set_data(x[:index], y[:index])
        drawing.set_3d_properties(z[:index])
        return drawing,

    a = FuncAnimation(fig, update, frames=len(x), interval=10, repeat=False)
    plt.show()
\end{lstlisting}

% See \url{https://matplotlib.org/2.0.0/examples/animation/index.html} for more examples.

\begin{comment} % TODO: An ORIGINAL example of using widgets
\subsection*{Interactive Plots} % ---------------------------------------------

Matplotlib plots can be made interactive by adding \emph{widgets}.
Consider the following example, TAKEN FROM THE MATPLOTLIB DOCS BASICALLY AHHH

\begin{lstlisting}
>>> from matplotlib import widgets as wg

>>> ax = plt.subplot(111)
>>> plt.subplots_adjust(bottom=.25)         # Make some space for a slider bar.
>>> t = np.arange(0., 1., .001)
>>> a0 = 5.
>>> f0 = 3.
>>> s = a0 * np.sin(2 * np.pi * f0 * t)
>>> l = plt.plot(t, s)[0]
>>> plt.axis([0, 1, -10, 10])
>>> axfreq = plt.axes([.25, .05, .65, .03])
>>> axamp = plt.axes([.25, .1, .65, .03])

# Make some slider bars.
>>> sfreq = wg.Slider(axfreq, 'Freq', .1, 30., valinit=f0)
>>> samp = wg.Slider(axamp, 'Amp', .1, 10., valinit=a0)
>>> def update(val):                        # Function for updating the plot.
...     amp = samp.val                          # Read from one slider.
...     freq = sfreq.val                        # Read from the other slider.
...     l.set_ydata(amp * np.sin(2 * np.pi * freq * t))
...     plt.draw()                              # Refresh the plot.
>>> sfreq.on_changed(update)                # Connect the sliders to update().
>>> samp.on_changed(update)
>>> plt.show()
\end{lstlisting}

\begin{figure}[H]
\includegraphics[width=.7\textwidth]{figures/interactive_plot.pdf}
\end{figure}
\end{comment}

% =============================================================================
% =============================================================================
% Stuff to move ===============================================================
% =============================================================================
% =============================================================================

\begin{comment}
\begin{info} % IPython Notebook inline plotting (move to notebook intro)
If you are executing these Matplotlib commands in an IPython shell, executing the \li{plt.show()} method will open a new window with the plot.
If you are using IPython Notebook, you have the option to display the plots within your notebook.
You may opt into this feature by running \li{\%matplotlib inline} or \li{\%matplotlib notebook} in your IPython Notebook.
The \li{inline} option shows the plot, whereas the \li{notebook} option shows the plot and provides controls to interact with the plot.
Additionally, when using this option, the plot is displayed after running the \li{plt.plot()} command; the \li{plt.show()} command is not necessary.
\end{info}
\end{comment}


\subsection{Time step selection}
The easier way to determine $\Delta t$ is to select it as a constant for all the simulation iterations.
For visualization concerns we will sometimes use a constant $\Delta t$ but, for simulation precision interests, it is better to compute a new time step for each iterations depending on the distance between the nearest bodies.
The following equation describes the variable $\Delta t$ calculation:
\begin{equation}
\label{eq:dt1}
	\|\vec{v_i}(t) . \Delta t + \frac{\vec{a_i}(t)}{2} . \Delta t^2 \| \leq 0.1 \times ||\vec{r_{ij}}||,
\end{equation}
with $j$ the nearest body to the body $i$.
For each body $i$, a time step is calculated and the smallest one is chosen.
Eq.~\ref{eq:dt1} traduces that the distance between $i(t)$ and $i(t + \Delta t)$ must be below 10\% of the $||\vec{r_{ij}}||$ distance.
This equation assures that two masses cannot be closest than 20\% between $t$ time and $t + \Delta t$ time.
However, Eq.~\ref{eq:dt1} is not directly usable: this is a $4^{th}$ degree polynomial equation in $\Delta t$.
It's why we will use the triangle inequality witch allows us to determine a new condition:
\begin{equation}
\label{eq:dt2}
	\|\vec{v_i}(t)\| . \Delta t + \frac{\|\vec{a_i}(t)\|}{2} . \Delta t^2  \leq 0.1 \times ||\vec{r_{ij}}||.
\end{equation}
Eq.~\ref{eq:dt2} is a $2^{nd}$ degree equation: this is more reasonable in term of computational time.

\subsection{Time integration}
\sout{The integrator used to update the positions and velocities is a leapfrog-Verlet integrator (Verlet 1967) because it is applicable to this problem and is computationally efficient (it has a high ratio of accuracy to computational cost).}

Body $i$ velocity characteristic at the $t + \Delta t$ time depends on the velocity and the acceleration at the $t$ time:
\begin{equation}
\label{eq:velocity}
	\vec{v_i}(t + \Delta t) = \vec{v_{i}}(t) + \vec{a_i}(t) . \Delta t.
\end{equation}
At the end, body $i$ position $q_i$ at the $t + \Delta t$ time depends on the position, the velocity and the acceleration at the $t$ time:
\begin{equation}
\label{eq:position}
	q_i(t + \Delta t) = q_{i}(t) + \vec{v_{i}}(t) . \Delta t + \frac{\vec{a_i}(t) . \Delta t^2}{2}.
\end{equation}
Thanks to Eq.~\ref{eq:acceleration}, \ref{eq:velocity} and \ref{eq:position}, it is now possible to compute the new position and the new velocity for all bodies at the $t + \Delta t$ time.


\subsubsection{Complex Eigenvalues}
\begin{theorem}
	If an $n \times n$ matrix $A$ is not defective, then for each pair of complex eigenvalues $\alpha \pm \beta i$ with corresponding eigenvectors $\vec{a} \pm i\vec{b}$, the corresponding fundamental solutions are $e^{\alpha t}\left(\cos{(\beta t)}\vec{a}-\sin{(\beta t)\vec{b}}\right)$ and $e^{\alpha t}\left(\sin{(\beta t)}\vec{a}+\cos{(\beta t)\vec{b}}\right)$.
\end{theorem}

\begin{example}
	Find the general solution to the system
	\begin{equation*}
		\vec{x}' = \begin{bmatrix}
			2 & 3 \\
			-3 & 2
		\end{bmatrix} \vec{x}.
	\end{equation*}
\end{example}
\noindent
Finding the eigenvalues by finding the roots of the characteristic polynomial of $A$,
\begin{equation*}
	p(\lambda) = \det{(A - \lambda I)} = (2-\lambda)^2 + 9 \implies \lambda = 2 \pm 3i.
\end{equation*}
Finding the eigenvectors for $\lambda = 2 + 3i$, remembering that once we have the two eigenvectors, we don't need to find them for the conjugate,
\begin{equation*}
	(A - (2+3i)I)\vec{v} = \vec{0} \implies \vec{v} = C_1\begin{bmatrix}
		0 \\
		1
	\end{bmatrix} + C_2i\begin{bmatrix}
		-1 \\
		0
	\end{bmatrix}.
\end{equation*}
So, our solution is
\begin{equation*}
	\vec{x} = C_1e^{2t}\left(\cos{(3t)}\begin{bmatrix}
		0 \\
		1
	\end{bmatrix}-\sin{(3t)}\begin{bmatrix}
		-1 \\
		0
	\end{bmatrix}\right) + C_2e^{2t}\left(\sin{(3t)}\begin{bmatrix}
		0 \\
		1
	\end{bmatrix}+\cos{(3t)}\begin{bmatrix}
		-1 \\
		0
	\end{bmatrix}\right).
\end{equation*}
We can rewrite this a little more elegantly as
\begin{equation*}
	\vec{x} = \begin{bmatrix}
		\sin{(3t)} & - \cos{(3t)} \\
		\sin{(3t)} & \cos{(3t)}
	\end{bmatrix} \begin{bmatrix}
		C_1 \\
		C_2
	\end{bmatrix} e^{2t}.
\end{equation*}


\begin{solution}
In this problem we are asked approximate the first derivative of the function
\begin{align*}
f(x)=\frac{1+2x^2\cos{x}}{x^{2.4}},
\end{align*}
at a given point $x_0=33.3$. We can calculate the derivative analytically,
\begin{align*}
f'(x)=\frac{2x^2(2\cos{x}-x\sin{x})-2.4(1+2x^2\cos{x})}{x^{3.4}},
\end{align*}
and its value at $x_0$ is $f'(x_0)=-0.466342049195729$ using double precision in \textsc{MATLAB}. We are asked to plot, in logarithmic scale, the truncation error of three different approximations versus the step $h$. The approximations to use are
\begin{itemize}
\item First order forward diffrences:
\begin{align*}
f'_i=\frac{f_{i+1}-f_i}{h}+\mathcal{O}(h).
\end{align*}
\item Second order central diffrences:
\begin{align*}
f'_i=\frac{f_{i+1}-f_{i-1}}{2h}+\mathcal{O}(h^2).
\end{align*}
\item Sixth order central differences:
\begin{align*}
f'_i=\frac{-f_{i-3}+9f_{i-2}-45f_{i-1}+45f_{i+1}-9f_{i+2}+f_{i+3}}{60h}+\mathcal{O}(h^6).
\end{align*}
\end{itemize}
Once the value of each approximation is obtained, we can compute the error for every value of the step $h$ and show it in the next figure.
\begin{figure}[H]
\centering     %%% not \center
\hspace{-0.56in}
\includegraphics[scale=0.5]{IMAGES/problem2_1_edit.eps}\caption{Error of the different approximations and reference lines.}
\end{figure}

The fact that the error describes a straight line of slope $m$ in logarithmic scale proves that that approximation is of order $m$ (since $\log{(kh^m)}=\log{k}+m\log h$, a straight line of slope $m$). In our case, it is clear in the figure that the approximations are, from top to bottom, indeed of order one, two and six, respectively. However, this linear dependence is broken in two areas of the figure.

First, when $h$ is sufficiently small, the \textit{rounding-error} is dominant and we see it as a cloud of points that seem parallel to the line of slope negative one. This is due to the fact that the rounding error is of the order of $\frac{\epsilon}{h}$, where $\epsilon$ is the well known machine epsilon. An error of that order is shown in logarithmic scale as a straight line of slope negative one (since $\log{(\frac{\epsilon}{h})}=\log{\epsilon}-\log{h}$ and $\epsilon$ is constant). The point where the rounding error becomes dominant depends, of course, of the order of approximation. The higher the order, as we make $h$ small, the powers of $h$ are even smaller and when they get of the order of $\epsilon$ the computer cannot differ well enough between numbers.

On the other hand, when $h$ is large, the terms of the error that are not the leading error term become more and more important as $h$ increases, reaching the point of not being neglectable. We can reach the point where the leading error term is not so anymore since we need $h$ to be small in order to assume that the remaining terms of the series are considerably smaller. We can see that effect in the top right corner of the figure.

\subsection*{Matlab code for the problem}
\section*{HOMEWORK 1 - FRANCISCO CASTILLO}

\subsection*{Contents}

\begin{itemize}
\setlength{\itemsep}{-1ex}
   \item Problem 2
\end{itemize}

\subsection*{Problem 2}

\begin{verbatim}
format long;clear all;close all;clc
x_0=33.3;
f = @(x) (1+2*x^2*cos(x))/(x^(2.4));
fp = @(x) (2*x^2*(2*cos(x)-x*sin(x))-2.4*(1+2*x^2*cos(x)))/(x^3.4);
for k = -3:1:25
    H(k+4) = 2^(-k);
end
for k = 1:length(H)
    h = H(k);
    df1(k) = (f(x_0+h)-f(x_0))/h;
    df2(k) = (f(x_0+h)-f(x_0-h))/(2*h);
    df6(k) = (45*(f(x_0+h)-f(x_0-h))-9*(f(x_0+2*h)-f(x_0-2*h))...
        +(f(x_0+3*h)-f(x_0-3*h)))/(60*h);
end
linewidth=2;
darkgreen=[0 0.6 0];
figure('units','normalized','outerposition',[0 0 1 1])
loglog(H,abs(df1-fp(x_0)),'*',H,abs(df2-fp(x_0)),'*')
hold on
loglog(H,abs(df6-fp(x_0)),'*','Color',darkgreen)
loglog(H,H/2,'b--',H,H.^(2)/6,'r--','linewidth',linewidth)
loglog(H,H.^(6)/140,'--','Color',darkgreen,'linewidth',linewidth)
loglog(H,eps./H,'k:','linewidth',linewidth)
set(gca,'fontsize',14)
axis([1e-8 1e1 1e-20 1e5])
grid on
xlabel('$h$ (log scale)','fontsize',20,'interpreter','latex')
ylabel('Error (log scale)','fontsize',20,'interpreter','latex')
saveas(gcf,'IMAGES/problem2_1','epsc')
saveas(gcf,'IMAGES/problem2_1','fig')
\end{verbatim}
\end{solution}


\chapter{Dual Spaces}
Consider a vector space $V$ over a field $\mathbb{F}$ with basis $\{\vec{e}_\mu\}$.
The \emph{Dual Space} of $V$, denoted $V^*$, is the set of all linear maps from $V$ to $\mathbb{F}$:
\begin{align*}
    V^* = \{\phi : \phi(\vec{v}) \in \mathbb{F}, \phi \text{ is linear}\}.
\end{align*}
Elements of $V^*$ are known as \emph{covectors}. Note that if we've created $V$, we don't need to do anything to create $V^*$; it is automatically created by $V$.

This dual space is itself a vector space, since we can give it a concept of addition and scalar multiplication, and the zero covector.
\begin{itemize}
    \item Addition: Consider covectors $\Lambda$ and $Z$ of the dual space of $V$ (so they are linear maps from $V$ to $\mathbb{F}$), and a vector $\vec{v} \in V$. We can say that $\langle \Lambda + Z, \vec{v} \rangle = \langle \Lambda,\vec{v} \rangle + \langle Z, \vec{v} \rangle$.
    \item Scalar multiplication: Again with a covector (linear map) $\Lambda$, we can say that $\langle a\Lambda, \vec{v} \rangle = a\langle \Lambda, \vec{v} \rangle$, where $a$ is a scalar from $\mathbb{F}$.
    \item Zero vector: Consider the map which sends every vector to $0_\mathbb{F}$; this can act as a `zero covector'.
\end{itemize}

\subsection{Dual Basis}
When we create a vector space $V$ with basis $\{\vec{e}_\mu\}$, we automatically create a dual space $V^*$; since the dual space is also a vector space, it must have a basis. We call this basis $\{\vec{e}^\mu\}$, similar to the basis for the original vector space, but with a superscript index instead of a subscript.
Like our choice for the basis of $V$, the choice of $\{\vec{e}^\mu\}$ is arbitrary.
But, while there isn't a specific basis created, we can choose our bases selectively.
Remember that $\vec{e}^\mu$ are \emph{linear maps} which can act upon $\vec{e}_\mu$;
We want to choose the basis for our dual space such that
\begin{align*}
    \langle \vec{e}^0, \vec{e}_0 \rangle &= 1, \\
    \langle \vec{e}^1, \vec{e}_1 \rangle &= 1, \\
    &\vdots \\
    \langle \vec{e}^\mu, \vec{e}_\mu \rangle &= 1,
\end{align*}
but
\begin{align*}
    \langle \vec{e}^0, \vec{e}_1 \rangle &= 0, \\
    &\vdots \\
    \langle \vec{e}^\mu, \vec{e}_\nu \rangle &= 0.
\end{align*}
We can generalize this statement to
\begin{align*}
    \langle \vec{e}^\mu, \vec{e}_\nu \rangle = \delta^\mu_\nu,
\end{align*}
where $\delta^\mu_\nu$ is the Kronecker delta function,
\[
    \delta^\mu_\nu =
    \begin{cases}
        1 & \mu = \nu \\
        0 & \mu \not= \nu
    \end{cases}.
\]
This choice is also rather arbitrary --- we just like dealing with the case when $\langle \vec{e}^\mu, \vec{e}_\nu \rangle = 1$ if and only if $\mu = \nu$, and is zero otherwise. It's also important to realize that exactly \emph{which} linear maps $\{\vec{e}^\mu\}$ are is not specified; although the creation of $V$ implies the creation of $V^*$, there isn't (yet) a way to relate vectors in $V$ to vectors in $V^*$.

\subsection{The Dual Dual Space}
Since the dual space $V^*$ is a vector space in its own right, it too must have a dual space, the set of all linear maps which send a vector in $V^*$ to $\mathbb{F}$.
If we look at the bracket notation for what we're really doing, it becomes obvious what this space must be:
\begin{align*}
    \langle \Lambda, \cdot \rangle &: V \to \mathbb{F} \\
    \langle \cdot, A^\mu \vec{e}_\mu \rangle &: V^* \to \mathbb{F}.
\end{align*}
If \emph{covectors} go from $V$ to $\mathbb{F}$, then \emph{vectors} go from $V^*$ to $\mathbb{F}$, so $V^{**} = V$.
Just like how we can build any vector in $V$ using Einstein summation over the basis of $V$, we can build a basis for $V^*$ in the same way. Since the basis vectors for $V^*$ are of the form $\{\vec{e}^\mu\}$, we write an arbitrary vector in the dual space as
\[ \Lambda = A_\mu \vec{e}^\mu \in V^*. \]
This makes the above definition for linear maps
\begin{align*}
    \langle A_\mu \vec{e}^\mu, \cdot \rangle &: V \to \mathbb{F}, \\
    \langle \cdot, A^\mu \vec{e}_\mu \rangle &: V^* \to \mathbb{F}.
\end{align*}

\subsection{Covariance and Contravariance}
If we start with a vector space $V$ and its corresponding dual space $V^*$ (again, which is which is a rather arbitrary choice, sense \emph{both} are vector spaces), we say that elements of the vector space $V$ are \emph{vectors}, and they are said to vary \emph{contravariantly}, while elements of the dual space $V^*$ are \emph{covectors} which vary \emph{contravariantly}.

\subsection{Arbitrary Vectors and Mappings}
Imagine we have an arbitrary covector $B^\mu \vec{e}_\mu$, and an arbitrary vector $A_\nu \vec{e}^\nu$ upon which this covector acts. We write this as
\[ \langle B_\mu \vec{e}^\mu, A^\nu \vec{e}_\nu \rangle. \]
Since these mappings are linear, we can factor out the coefficients, leaving
\[ B_\mu A^\nu \langle \vec{e}^\mu, \vec{e}_\nu \rangle. \]
Since we know that $\langle \vec{e}^\mu, \vec{e}_\nu \rangle = \delta^\mu_\nu$, we can simplify this into
\[ B_\mu A^\nu \langle \vec{e}^\mu, \vec{e}_\nu \rangle = B_\mu A^\nu \delta^\mu_\nu = B_\mu A^\mu. \]
This means that we can refer to the result of the covector-vector applications by just the coefficients, as long as we define the dual basis by the delta function.
Note also that $B_\mu A^\mu$ is a member of the field $\mathbb{F}$ over which $V$ and $V^*$ are taken.


\section{Brief primer on tensors}\label{sec:tensor}
The material here is based on \cite{lee-book-2000,dullemond-1991-tensor}.

Let \(V\) be an \(n\)-dimensional vector space over the reals. A {\em covector} on \(V\) is a real-valued linear functional \(\omega:V\rightarrow \Re\). The space of all covectors is itself a real vector space  under pointwise addition and multiplication. It is written as \(V^{\star}\) and called the {\em dual space} to \(V\).

\begin{proposition}[\cite{lee-book-2000} Proposition 4.1] For \(V\) an \(n\)-dimensional vector space and \(E_1, \ldots, E_n\) a basis for \(V\), the covectors \(\epsilon^1, \ldots, \epsilon^n\), defined by:
  \[
  \epsilon^i(E_j) = \delta^i_j = \left\{
  \begin{array}{ll}
    1 & \mbox{if \(i =j\)} \\
    0 & \mbox{if \(i\not=j\)}
    \end{array}\right.
    \]
\noindent form a basis for \(V^{\star}\), called the {\em dual basis} to \((E_i)\).
\end{proposition}
%% TODO: Define canonical isomorphism.
Note that it follows that the dimensionality of \(V^{\star}\) is the same as that of \(V\). It is also the case that \(V^{\star\star}\) is canonically isomorphic to \(V\).

\begin{definition}[Tensor] For $V$ a finite-dimensional real vector space, a {\em tensor} of rank \((k,l)\) over $V$ is a real-valued multilinear function of $k$ elements of \(V^{\star}\) and \(l\) elements of \(V\). \(k\) is said to be its {\em contravariant} rank, and \(l\) its {\em covariant} rank. The {\em rank} of the tensor is \(k+l\).
\end{definition}
A matrix \(M\) is a \((1,1)\)-tensor, a vector \(x\) a \((1,0)\)-tensor, and a covector \{a\} a \((0,1)\)-tensor.

Let \(\{{\bf e}_j\}\) be a basis for \(V\), with canonical cobasis \(\{\epsilon^i\}\) for \(V^{\star}\).
Such a tensor \(T\) can be associated with an array with \(k+l\) dimensions, whose \((i_1, \ldots, i_k, j_1, \ldots, j_l)\)'th element written \(T^{i_1\ldots i_k}_{j_1, \ldots, j_l}\) is given by \(T(\epsilon^{i_1}, \ldots, \epsilon^{i_k}, {\bf e}_{j_1}, \ldots, {\bf e}_{j_l})\).

The meaning of the indices of a tensor is usually decided beforehand; it is conventional to write a tensor with its contravariant (upper) indices first and the covariant (lower) indices last, e.g.{} \(T^{i,j}_k\). For instance, a matrix \(M\) is a \((1,1)\)-tensor, and we can write \(M_i^j\) to make its indices explicit. This is the same as \(M_j^k\) -- the identity of indices does not matter. Also, basis vectors will be written with a lower index, and components of a vector with respect to this basis with an upper index; similarly basis covectors will be written with an upper index and components of a covector with a lower index.

Denote the set of all \((k,l)\)-tensors over \(V\) by \(T^k_l\).
$T^k_l(V)$ is a vector space under point-wise addition and scalar multiplication. Specifically:
\[
\begin{array}{l}
  (\alpha T)(X_1, \ldots, X_k, Y_1, \ldots, Y_l) = \alpha(T(X_1, \ldots, X_k, Y_1, \ldots, Y_l))\\
  (S+T)(X_1, \ldots, X_k, Y_1, \ldots, Y_l)=S(X_1, \ldots, X_K, Y_1, \ldots, Y_k) + T(X_1, \ldots, X_k, Y_1, \ldots, Y_l)
\end{array}
\]

\subsection{Tensor Contraction}\label{sec:summation-convention}
In the following we shall adopt the {\em Einstein summation convention}:
\begin{quotation}
  If the same index name appears twice in any term, once as an upper index and once as a lower index, that term is understood to be summed over all possible values of that index, generally from \(1\) to the dimension of the space in question. If the indices belong to different tensors, their tensor product is taken first.
\end{quotation}
Thus for instance we can rewrite:
\[
\begin{array}{lcl}
  \Sigma_{\nu=1}^n A_{\mu\nu}v^{\nu} & \rightarrow &   A_{\mu\nu}v_{\nu}\\
  \Sigma_{\beta=1}^n \Sigma_{\gamma=1}^n A _{\alpha \beta}B^{\beta \gamma}C_{\gamma \delta} & \rightarrow & A_{\alpha \beta}B^{\beta \gamma}C_{\gamma \delta}
\end{array}
\]

The {\em contraction} of a tensor is obtained by setting one upper and one lower index equal, thus indicating a summation per the convention above. The result of contracting a \((k,l)\)-tensor  is a \((k-1,l-1)\) tensor.

The contraction operation is invariant under coordinate changes.

\subsection{Working with tensors}

Tensors can be ``partially'' evaluated. For \(T\) a tensor of rank \(k\) representing a predicate \(p\), and \(a\) a vector representing the value of argument \(i\), \(T_{1\ldots k}a^i\) represents the predicate \(\lambda x_1, \ldots, x_{i-1},x_{i+1},\ldots x_k. p(x_1, \ldots, x_{i-1}, a, x_{i+1}, \ldots, x_k)\). It can be thought of as {\em contracting} \(T\) and \(a\) on index \(i\).

\begin{example}\label{ex:tc-1}
  Consider the tensor representation of the boolean polynomial \(p(x,y) = x(1-y)\). Because \(x,y\in \{0,1\}\) with the two values independent of each other, we will embed them in the two dimensional vector space \(U=\{0,1\}^2\), with ``one hot'' basis vectors \({\bf e}_1=(1,0)\) and \({\bf e}_2=(0,1)\) representing \(0\) and \(1\) respectively. Now the tensor \(T_{1,2}\) representing the binary predicate \(\lambda x,y. p(x,y)\) is represented by the table:
  \[
  \begin{array}{l}
    T({\bf e}_1,{\bf e}_1)=(0)(1-0)=0\\
    T({\bf e}_1,{\bf e}_2)=(0)(1-1)=0\\
    T({\bf e}_2,{\bf e}_1)=(1)(1-0)=1\\
    T({\bf e}_2,{\bf e}_2)=(1)(0)=0
  \end{array}
  \]
  We can use this representation to evaluate the predicate at different points through tensor contraction. For instance, \(p(0,1)\) is given, for \(a={\bf e}_1,b={\bf e}_2\) by \(T_{1,2}a^1 b^2\), which through the Einstein convention expands out to:\footnote{Recall that for a vector \(x\) \(x^j\) represents its \(j\)th coordinate. Note that
    in the term \(T_{1,2}a^1b^2\) the super-scripts of \(a\) and \(b\) are indices, whereas in
    \(T({\bf e}_i,{\bf e_j})a^i b^j\) the super-scripts of \(a\) and \(b\) are component selections.}
  \[\begin{array}{ll}
  T_{1,2}a^1 b^2 &= \Sigma_{j=1}^2 \Sigma_{i=1}^2 T({\bf e}_i,{\bf e_j})a^i b^j \\
  &= T({\bf e}_1,{\bf e}_1)(1)(0) + T({\bf e}_1,{\bf e}_2)(1)(1) +
  T({\bf e}_2,{\bf e}_1)(0)(0) + T({\bf e}_2,{\bf e}_2)(0)(1) \\
  & =T({\bf e}_1,{\bf e}_2)\\
  & = 0
  \end{array}
  \]
\end{example}

More generally, we can compute tensor contraction symbolically. Let \(x,y\) be  unknown vectors in \(U\), and let \(S\) be a rank-2 tensor over \(U\). Then if \(S\) represents the predicate \(q\), the predication \(q(x,y)\) is represented by \(S_{1,2}x^1 y^2\) which expands out to:
\[\begin{array}{ll}
  [S(x,y)]&\defeq  S_{1,2}x^1 y^2\\
  & = \Sigma_{j=1}^2 \Sigma_{i=1}^2 S({\bf e}_i,{\bf e}_j)x^iy^j \\
  & =S({\bf e}_1,{\bf e}_1)x^1y^1 + S({\bf e}_1,{\bf e}_2)x^1y^2 +
      S({\bf e}_2,{\bf e}_1)x^2y^1 + S({\bf e}_2,{\bf e}_2)x^2y^2 \\
  \end{array}
\]

\begin{example}[Example~\ref{ex:tc-1} contd]
  Taking the value of \(S\) above to be \(T\), we get:
  \[\begin{array}{ll}
      [T(x,y)] & = x^2y^1\\
      & = [x=1][y=0]
  \end{array}
  \]
\end{example}

The representation of an arbitrary $k$-are predicate is similar, a tensor \(T_k\) represented by \(n^k\) numbers, for \(U=\{0,1\}^n\).


\section*{Problem 4 Solution}

The number density of material $i$ can be found using the formula
$$ n_i = \frac{\rho_i N_A}{M_i} $$
where $\rho_i$ is the partial density of material $i$, $M_i$ is the molar mass of $i$, and $N_A$ is Avogadro's number. We can reverse this formula to find the partial density of a material from the atomic density.
$$ \rho_i = \frac{N_i M_i}{N_A} $$
We can use this formula for the three isotopes we are considering. We also note the following:
\begin{itemize}
\item $n_{\text{O}} = 2(n_{\text{U5}} + n_{\text{U5}})$
\item $M_{\text{U5}} = 235.04\text{ g/mol}$
\item $M_{\text{U8}} = 238.05\text{ g/mol}$
\item $M_{\text{O}} = 16.00\text{ g/mol}$
\end{itemize}

\begin{multicols}{2}
$$ \rho_{\text{U5}} = \frac{n_{\text{U5}}  M_{\text{U5}} }{N_A} $$
$$ \rho_{\text{U5}} = \frac{(2.5\times10^{21}\text{ atoms/cm}^3)(235.04\text{ g/mol}) }{6.022\times10^{23}\text{ atoms/mol}} $$
$$\boxed{ \rho_{\text{U5}} = 0.976\text{ g/cm}^3 }$$

$$ \rho_{\text{U8}} = \frac{n_{\text{U8}}  M_{\text{U8}} }{N_A} $$
$$ \rho_{\text{U8}} = \frac{(2.0\times10^{22}\text{ atoms/cm}^3)(238.05\text{ g/mol}) }{6.022\times10^{23}\text{ atoms/mol}} $$
$$\boxed{ \rho_{\text{U8}} = 7.91\text{ g/cm}^3 }$$

\end{multicols}

$$ \rho_{\text{O}} = \frac{n_{\text{O}}  M_{\text{O}} }{N_A} $$
$$ \rho_{\text{O}} = \frac{2(n_{\text{U5}} + n_{\text{U5}})  M_{\text{O}} }{N_A} $$
$$ \rho_{\text{O}} = \frac{2(2.25\times10^{22}\text{ atoms/cm}^{3})(16.00\text{ g/mol}) }{6.022\times10^{23}\text{ atoms/mol}} $$
$$\boxed{ \rho_{\text{O}} = 1.20\text{ g/cm}^3 }$$

The enrichment of $^{235}$U is therefore
$\frac{\rho_{\text{U5}}}{\rho_{\text{U5}}+\rho_{\text{U8}}} = 0.1098 \quad\Rightarrow \quad\boxed{10.98\%}$


%!TEX root=ClassNotes.tex

\section{Taylor Series}
Taylor series is a technique used to approximate functions using {\it polynomials}.

\begin{definition}
  \label{def:Taylor_series}
For a positive integer $n$, a real number $a$, and an infinitely differentiable function $f$, the {\bf n$^{th}$ Taylor polynomial/approximation centered at $a$}, denoted $T_nf (x)$, is a degree $n$ polynomial defined as\\
  \begin{align*}
    T_nf (x) &= f(a)
    + f'(a) \cdot \dfrac{(x-a)}{1}
    + f''(a) \cdot \dfrac{(x-a)^2}{2!}
    + \dots
    + f^{(n)}(a) \cdot \dfrac{(x-a)^n}{n!}\\
  \end{align*}
  where $f^{(n)}(a)$ denotes the $n^{th}$ derivative of $f$ at $a$.\footnote{Recall that $n! = n \cdot (n-1) \cdot (n-2) \cdots 2 \cdot 1 $.}
The limit $n \rightarrow \infty$ of the above series is called the {\bf Taylor series $Tf(x)$}.\\
\begin{align*}
  Tf(x) &= f(a)
  + f'(a) \cdot \dfrac{(x-a)}{1}
  + f''(a) \cdot \dfrac{(x-a)^2}{2!}
  + f^{(3)}(a) \cdot \dfrac{(x-a)^3}{3!}
  + \dots\\
\end{align*}
\end{definition}

\begin{remark}
  The Taylor series defined above is just a {\it formal series}.
  It is not always possible to plug in a value for $x$ because of convergence issues.
  We'll discuss this in the later sections.
\end{remark}

We'll mostly be interested in the Taylor series centered at $a = 0$, \\
\begin{align*}
  Tf(x)
  &=
  f(0)
  + f'(0) \cdot \dfrac{x}{1}
  + f''(0) \cdot \dfrac{x^2}{2!}
  + f^{(3)}(0) \cdot \dfrac{x^3}{3!}
  + \dots\\
\end{align*}
In this case, $Tf(x)$ is called the $n^{th}$ {\bf Maclaurin series}.

\begin{exercise}
  For each of the following functions compute $f^{(n)}(0)$, for positive integers $n$, and use these to compute the Maclaurin series.
  \begin{multicols}{2}
  \begin{enumerate}
    \item $e^x$
    \item $\sin x$
    \item $\cos x$
    \item $\ln {(1+x)}$
    \item $\dfrac{1}{1-x}$
    \item (Optional) $\tan^{-1} x$
  \end{enumerate}
  \end{multicols}
\end{exercise}

\begin{exercise}
  This problem explains why the Definition \ref{def:Taylor_series} is the ``correct'' definition for Taylor series.
  \begin{enumerate}
    \item Let $f(x) = x^k$. Compute $T_n f(x)$ centered at $0$ for
    \begin{enumerate}
      \item $n < k$
      \item $n \ge k$
    \end{enumerate}
    \item More generally, let
    \begin{align*}
      f(x) = a_0 + a_1 x + a_2 x^2 + \dots + a_k x^k
    \end{align*}
    Using the previous part, compute $T_n f(x)$ for
    \begin{enumerate}
      \item $n < k$
      \item $n \ge k$
    \end{enumerate}
     What is the Maclaurin series for this $f(x)$?
  \end{enumerate}
\end{exercise}
The above statement is more generally for all Taylor series centered at any point $a$.
\begin{exercise}{\bf (Optional)}
  Show that the Taylor series of $f(x) = x^n$, centered at a real number $a$, equals $x^n$. Argue that this is more generally true for an arbitrary polynomial $f(x)$.
\end{exercise}

\subsection{Remainder Term}
As mentioned earlier, Definition \ref{def:Taylor_series} defines a \textit{formal series} and it not possible to make sense of $Tf(x)$ for a real number $x$.
The two important questions that we need to answer are:
\begin{enumerate}
  \item  Does the limit $\lim \limits_{n \rightarrow \infty}T_n f(x)$ exist?
  \item Does the limit $\lim \limits_{n \rightarrow \infty}T_n f(x)$ equal $f(x)$?
\end{enumerate}
Unless the answer to both the questions is {\it yes} it is not possible to use Taylor polynomials for approximating the function $f(x)$.

Both the questions are in generally difficult to answer.
To tackle the first question we need techniques from series and sequences.
In this section, we'll focus on answering the second question which can be done using basic Calculus.

\begin{definition}
  For a smooth function $f$ and real numbers $x$, $a$, the {\bf $n^{th}$ error term} or the {\bf $n^{th}$ remainder term $R_nf(x)$} is defined as
  \begin{align*}
    R_nf(x)
    &= f(x) - T_nf(x)
  \end{align*}
  where $T_n f(x)$ is the $n^{th}$ Taylor approximation of $f$ centered at $a$, so that $f(x) = T_nf(x) + R_nf(x)$.
Thus we can say that
\begin{align*}
  \lim \limits_{n \rightarrow \infty}T_n f(x) = f(x)
\end{align*}
if and only if
\begin{align*}
  \lim \limits_{n \rightarrow \infty}R_n f(x) = 0.
\end{align*}
\end{definition}

\newpage

The following Theorem allows us to compute this remainder term using integrals.
\begin{theorem}
  \label{thm:remainder_term}
  With the notation as above, the remainder term is given by
  \begin{align*}
    R_nf(x) = \dfrac{1}{n!} \cdot \int_a^x {(x-t)^n \cdot {f^{(n+1)}(t)} } \: dt
  \end{align*}
\end{theorem}

\begin{exercise}
  \begin{enumerate}
    \item Using integration by parts (if necessary), compute
    \begin{enumerate}
      \item $\int_0^x {f'(t)} \: dt$
      \item $\int_0^x (x-t) \cdot {f''(t)} \: dt$
      \item $\int_0^x (x-t)^2 \cdot {f^{(3)}(t)} \: dt$
    \end{enumerate}
    \item{\bf (Optional)} By repeatedly applying integration by parts, prove that
    \begin{align*}
      \dfrac{1}{n!} \cdot \int_0^x {(x-t)^n \cdot {f^{(n+1)}(t)}} \: dt
    \end{align*}
    equals
    \begin{align*}
      f(x) - \left( f(0)
      + f'(0) \cdot \dfrac{x}{1}
      + f''(0) \cdot \dfrac{x^2}{2!}
      + \dots
      + f^{(n)}(0) \cdot \dfrac{x^n}{n!}
      \right)
    \end{align*}
    thereby proving Theorem \ref{thm:remainder_term} for $a=0$.
  \end{enumerate}
\end{exercise}

\begin{exercise}{\bf (Optional)}
  Prove Theorem \ref{thm:remainder_term} for arbitrary real number $a$.
\end{exercise}

\newpage
\subsection{Computing using Taylor Series}
We can use the Taylor series (centered at 0) to do computations if
\begin{enumerate}
  \item we can compute all the derivatives $f^{(n)}(0)$ for all positive integers $n$
  \item $ \lim \limits_{n \rightarrow \infty}R_n f(x) = 0$.
\end{enumerate}
The condition $ \lim \limits_{n \rightarrow \infty}R_n f(x) = 0$ is highly non-trivial and not checking it leads to absurd results.

\begin{exercise}
  Let $f(x) = \dfrac{1}{1-x}$.
  What happens to the value of the Maclaurin series $Tf(x)$ for $x=2$? What is $f(2)$?
\end{exercise}
For $f(x) = \dfrac{1}{1-x}$ we can show that $ \lim \limits_{n \rightarrow \infty}R_n f(2) = \infty$ (and not 0) and hence the difference between the Taylor series $Tf(2)$ and the function $f(2)$ blows up to infinity.
In the next section, we'll prove the following theorem which says that this does not happen for exponential and trigonometric functions.
\begin{theorem}
  \label{thm:Taylor_series_exponential}
  If $f(x) = e^x$, $\sin x$, and $\cos x$, then $\lim \limits_{n \rightarrow \infty}R_n f(x) = 0$ for \textit{all real numbers} x.
\end{theorem}

Hence, for all real numbers $x$, $\lim \limits_{n \rightarrow \infty}T_n f(x) = f(x)$ for exponential and trigonometric functions and we can use the Taylor series to approximate.

\begin{exercise}
  Use the Maclaurin series of $e^x$ to compute the value of $e$ correct up to 2 decimal places.
\end{exercise}

\begin{exercise}
  \begin{enumerate}
    \item Theorem \ref{thm:Taylor_series_exponential} is also true for $\tan^{-1} x$, the proof is easy but technical. The Maclaurin series of $\tan^{-1} x$ is given by
    \begin{align*}
      x - \dfrac{x^3}{3} + \dfrac{x^5}{5} - \dfrac{x^7}{7} + \dfrac{x^9}{9} + - \dots
    \end{align*}
    Using this find an expression (as an infinite sum) for $\pi$.\hint{Use $x = 1$.}
    \item Use the first 10 terms of this sum to find an approximate value for $\pi$.
    This method for computing $\pi$ is not used in practice as the \textit{rate of convergence} of the Maclaurin series is very slow.
  \end{enumerate}
\end{exercise}

\begin{exercise}
  Theorem \ref{thm:Taylor_series_exponential} is true even if $x$ is a complex number (the proof requires complex analysis).
  Compute the Taylor series of $e^{i\theta}$, $\cos \theta$, $\sin \theta$. Use these to prove the {\it Euler's identity},
\begin{align*}
    e^{i\theta} &= \cos \theta + i \sin \theta
\end{align*}
\end{exercise}

\subsection{Estimating the Remainder Term}
Finally, we  want to prove Theorem \ref{thm:Taylor_series_exponential}.

\begin{exercise} {\bf (Optional)}
  Let $x$ be a positive real number.
   For each of the following functions $f(x)$, show that there is a constant $M$ such that for all $ t \in (0,x)$  and all positive integers $n$ we have $|f^{(n)}(t)| < M$. (Note that $M$ can depend on $x$ but not on $n$ or $t$.)
   \begin{multicols}{2}
     \begin{enumerate}
       \item $e^x$
       \item $\sin x$
       \item $\cos x$
     \end{enumerate}
   \end{multicols}
\end{exercise}
Using the above problem, the proof of Theorem \ref{thm:Taylor_series_exponential} will be complete once we prove the following Proposition.
\begin{prop}
  Let $x$ be a positive real number. If there is a real number $M$ such that for all $ t \in (0,x)$  and all positive integers $n$ we have $|f^{(n)}(x)| < M$ then $R_n f(x) \rightarrow 0$ as $n \rightarrow \infty$.
\end{prop}
\begin{proof}
  By definition,
  \begin{align*}
    R_n f(x) = \dfrac{1}{n!} \cdot \int_0^x {(x-t)^n \cdot {f^{(n+1)}(t)}} \: dt
  \end{align*}
  Because $(x-t)^n < x^n$ and $|f^{(n+1)}(t)| < M$ for all $0 < t < x$  and all positive integers $n$, we get
  \begin{align*}
    |R_n f(x)|
    &=
    \left|\dfrac{1}{n!} \cdot \int_0^x {(x-t)^n \cdot {f^{(n+1)}(t)}} \: dt \right|\\
    &< \left|\dfrac{1}{n!} \cdot \int_0^x x^n \cdot M \: dt \right| \\
    &=  \left|\dfrac{1}{n!} \cdot x^n \cdot M \int_0^x 1 \: dt \right| \\
    &=  \left|\dfrac{1}{n!} \cdot x^n \cdot M x \right| \\
    &= \dfrac{M x^{n+1}}{n!}
  \end{align*}
  One can show that for any real number $x$, $\lim \limits_{n \rightarrow \infty} x^{n+1} / n! = 0$ (this is easy, see if you can work out the details) so that
\begin{align*}
    \lim \limits_{n \rightarrow \infty} |R_n f(x)|
    &<
    \lim \limits_{n \rightarrow \infty} \dfrac{M x^{n+1}}{n!}
    \\
    &= {M}\cdot \lim \limits_{n \rightarrow \infty} \dfrac{x^{n+1}}{n!} \\
    &= M \cdot 0 = 0
\end{align*}
\end{proof}

To summarize, Taylor series provides us a tool for approximating functions using polynomials (in the cases where the remainder term tends to 0).
This is a very common technique in analysis: we try to approximate a function by a series of simpler functions and show that the difference between the two tends to 0.
Fourier series, for example, does this using trigonometric functions.


%----------------------------------------------------------------------------------------
%	CHAPTER 2
%----------------------------------------------------------------------------------------

\chapter{In-text Elements}

\section{Theorems}\index{Theorems}

This is an example of theorems.

\subsection{Several equations}\index{Theorems!Several Equations}
This is a theorem consisting of several equations.

\begin{theorem}[Name of the theorem]
In $E=\mathbb{R}^n$ all norms are equivalent. It has the properties:
\begin{align}
& \big| ||\mathbf{x}|| - ||\mathbf{y}|| \big|\leq || \mathbf{x}- \mathbf{y}||\\
&  ||\sum_{i=1}^n\mathbf{x}_i||\leq \sum_{i=1}^n||\mathbf{x}_i||\quad\text{where $n$ is a finite integer}
\end{align}
\end{theorem}

\subsection{Single Line}\index{Theorems!Single Line}
This is a theorem consisting of just one line.

\begin{theorem}
A set $\mathcal{D}(G)$ in dense in $L^2(G)$, $|\cdot|_0$.
\end{theorem}

%------------------------------------------------

\section{Definitions}\index{Definitions}

This is an example of a definition. A definition could be mathematical or it could define a concept.

\begin{definition}[Definition name]
Given a vector space $E$, a norm on $E$ is an application, denoted $||\cdot||$, $E$ in $\mathbb{R}^+=[0,+\infty[$ such that:
\begin{align}
& ||\mathbf{x}||=0\ \Rightarrow\ \mathbf{x}=\mathbf{0}\\
& ||\lambda \mathbf{x}||=|\lambda|\cdot ||\mathbf{x}||\\
& ||\mathbf{x}+\mathbf{y}||\leq ||\mathbf{x}||+||\mathbf{y}||
\end{align}
\end{definition}

%------------------------------------------------

\section{Notations}\index{Notations}

\begin{notation}
Given an open subset $G$ of $\mathbb{R}^n$, the set of functions $\varphi$ are:
\begin{enumerate}
\item Bounded support $G$;
\item Infinitely differentiable;
\end{enumerate}
a vector space is denoted by $\mathcal{D}(G)$.
\end{notation}

%------------------------------------------------

\section{Remarks}\index{Remarks}

This is an example of a remark.

\begin{remark}
The concepts presented here are now in conventional employment in mathematics. Vector spaces are taken over the field $\mathbb{K}=\mathbb{R}$, however, established properties are easily extended to $\mathbb{K}=\mathbb{C}$.
\end{remark}

%------------------------------------------------

\section{Corollaries}\index{Corollaries}

This is an example of a corollary.

\begin{corollary}[Corollary name]
The concepts presented here are now in conventional employment in mathematics. Vector spaces are taken over the field $\mathbb{K}=\mathbb{R}$, however, established properties are easily extended to $\mathbb{K}=\mathbb{C}$.
\end{corollary}

%------------------------------------------------

\section{Propositions}\index{Propositions}

This is an example of propositions.

\subsection{Several equations}\index{Propositions!Several Equations}

\begin{proposition}[Proposition name]
It has the properties:
\begin{align}
& \big| ||\mathbf{x}|| - ||\mathbf{y}|| \big|\leq || \mathbf{x}- \mathbf{y}||\\
&  ||\sum_{i=1}^n\mathbf{x}_i||\leq \sum_{i=1}^n||\mathbf{x}_i||\quad\text{where $n$ is a finite integer}
\end{align}
\end{proposition}

\subsection{Single Line}\index{Propositions!Single Line}

\begin{proposition}
Let $f,g\in L^2(G)$; if $\forall \varphi\in\mathcal{D}(G)$, $(f,\varphi)_0=(g,\varphi)_0$ then $f = g$.
\end{proposition}

%------------------------------------------------

\section{Examples}\index{Examples}

This is an example of examples.

\subsection{Equation and Text}\index{Examples!Equation and Text}

\begin{example}
Let $G=\{x\in\mathbb{R}^2:|x|<3\}$ and denoted by: $x^0=(1,1)$; consider the function:
\begin{equation}
f(x)=\left\{\begin{aligned} & \mathrm{e}^{|x|} & & \text{si $|x-x^0|\leq 1/2$}\\
& 0 & & \text{si $|x-x^0|> 1/2$}\end{aligned}\right.
\end{equation}
The function $f$ has bounded support, we can take $A=\{x\in\mathbb{R}^2:|x-x^0|\leq 1/2+\epsilon\}$ for all $\epsilon\in\intoo{0}{5/2-\sqrt{2}}$.
\end{example}

\subsection{Paragraph of Text}\index{Examples!Paragraph of Text}

\begin{example}[Example name]
\lipsum[2]
\end{example}

%------------------------------------------------

\section{Exercises}\index{Exercises}

This is an example of an exercise.

\begin{exercise}
This is a good place to ask a question to test learning progress or further cement ideas into students' minds.
\end{exercise}

%------------------------------------------------

\section{Problems}\index{Problems}

\begin{problem}
What is the average airspeed velocity of an unladen swallow?
\end{problem}

%------------------------------------------------

\section{Vocabulary}\index{Vocabulary}

Define a word to improve a students' vocabulary.

\begin{vocabulary}[Word]
Definition of word.
\end{vocabulary}


%-----------------------------------
\subsection{The conic frustrum}
%-----------------------------------
The derivation of the surface area of conic frustrum.
The edge length $l$ is defined
\begin{equation}
    l = \sqrt{(x_r - x_l)^2 + (a_r - a_l)^2} = \sqrt{\Delta x^2 + \Delta a^2}.
\end{equation}
The lateral area of the surface is found by integrating along surface of rotation:
\begin{align}
    \sigma_{\text{lateral}}
        &= \int_{0}^{l} {2\pi a(s)} \deriv{s} \nonumber \\
        &= 2\pi \int_{0}^{l} {a_{\ell} + \frac{s}{l}\left( a_r - a_\ell \right)} \deriv{s} \nonumber \\
        &= 2\pi \left[ a_{\ell}s + \frac{s^2}{2l}\left( a_r - a_\ell \right) \right]_0^l \nonumber \\
        &= \pi l \left( a_{\ell} + a_r \right) \nonumber \\
        &= \pi \left( a_{\ell} + a_r \right) \sqrt{\Delta x^2 + \Delta a^2}. \label{eq:frustrum_area}
\end{align}

There are two degenerate cases of interest. The first is the \emph{cylinder}, for which the radii at each end are euqal, i.e. $a_\ell = a_r = a$. In this case the lateral area of the surface is
\begin{equation}
    \sigma_{\text{lateral}} = 2\pi a \Delta x.
\end{equation}
The second is a cone, for which $a_\ell=0$ and $a_r=a$:
\begin{equation}
    \sigma_{\text{lateral}} = \pi a \sqrt{\Delta x^2 + a^2}.
\end{equation}