\lab{Predator-Prey and Weight Change Models}{Weight change and Predator-Prey Models}
\label{lab:Weightchange}
\objective{We introduce built-in methods for solving Initial Value Problems and apply the methods to two dynamical systems.
The first  system looks at the relationship between a predator and its prey.
The second model is a weight change model based on thermodynamics and kinematics.}

% \section*{ODE Solvers}
% Initial Value Problems (IVPs) are a systems of one or more ordinary differential equations (ODEs) with defined initial conditions. In some cases, these can be solved by hand, but in real life it is more practical to use numerical solvers. For this lab you will use the  \li{solve_ivp} solver from the \li{scipy.integrate} library.

% \li{solve_ivp} solves a system of ODEs given by $dy/dt = f(t, y),\quad y(t_0)=y_0$, where $y$ can be a vector. The solver takes as parameters the callable function $f$, the time boundaries \li{(t0,tf)}, the initial condition \li{y_0}, and an optional keyword argument \li{t_eval} that designates the times at which the solver will store the solution. Then \li{solve_ivp} returns a bunch object containing an array \li{y} with shape \li{(len(y_0), len(t))}, where each column gives the \li{y} values for one time point. The syntax for \li{solve_ivp} is shown below.
% \begin{lstlisting}
% from scipy.integrate import solve_ivp
% sol = solve_ivp(f, (t0,tf), y0, t_eval=t)
% \end{lstlisting}
% Assuming that $f$, $y0$, $t_0$, $t_f$, and $t$ are previously defined as explained above, \li{sol.y} is a vector containing the solution to the IVP and can be visualized by plotting each row of \li{sol.y} against the time domain or by plotting the rows against each other.

\section*{Predator-Prey Model}
ODEs are commonly used to model relationships between predator and prey populations. For example, consider the populations of wolves, the predator, and rabbits, the prey, in Yellowstone National Park. Let $r(t)$ and $w(t)$ represent the rabbit and wolf populations respectively at time $t$, measured in years.
We will make a few assumptions to simplify our model:

\begin{itemize}
\item In the absence of wolves, the rabbit population grows at a positive rate proportional to the current population. Thus when $w(t) = 0$, $dr/dt = \alpha r(t)$, where $\alpha > 0$.
\item In the absence of rabbits, the wolves die out. Thus when $r(t) = 0$, $dw/dt = -\delta w(t)$, where $\delta > 0$.
\item The number of encounters between rabbits and wolves is proportional to the product of their populations. The wolf population grows proportional to the number of encounters by $\beta r(t)w(t)$ (where $\beta > 0$), and the rabbit population decreases proportional to the number of encounters by $-\gamma r(t)w(t)$ (where $\gamma > 0$).
\end{itemize}

This leads to the following system of ODEs:
\begin{align}
	\begin{split}
	&\frac{dr}{dt} = \alpha r - \beta r w = r(\alpha - \beta w)\\
	&\frac{dw}{dt} = -\delta w + \gamma r w = w(-\delta + \gamma r)
	\end{split}\label{eqn: Pred-Prey}
\end{align}

\begin{figure}[H]
\centering
\includegraphics[width=\textwidth]{figures/Predator_Prey.png}
\caption{The solution to the system found in \eqref{eqn: Pred-Prey}}
\label{fig: Pred-Prey}
\end{figure}

\begin{problem}
Define the function \li{predator_prey()} that accepts the current $r(t)$ and $w(t)$ values as a 1d array $y$, and the current time $t$,
%a 1d array $y$ representing the current rabbit and wolf populations and a float $t$ representing the current time.
and returns the right hand side of \eqref{eqn: Pred-Prey} as an ndarray.
Use $\alpha=1.0$, $\beta=0.5$, $\delta=0.75$, and $\gamma=0.25$ as your growth parameters.\\
Hint: you will want to use \li{solve_ivp}.
%\begin{lstlisting}
%def predator_prey(y, t):
%	'''
%	Parameters:
%	--------------
%	t:	time variable.
%	y:	an array of length len(y0) representing current wolf and rabbit populations at time t.
%
%	Return:
%	--------
%	Return a tuple corresponding to the Predator-Prey model.
%	'''
%	pass
%\end{lstlisting}

\end{problem}

%Import the \li{odeint} method and define the initial conditions and time array for the predator-prey model using the following code:
%\begin{lstlisting}
%# Initialize populations
%r0 = 5
%w0 = 3
%y0 = [r0, w0]

%# Initialize time array
%t = np.linspace(0, 20, 100)
%\end{lstlisting}

\begin{problem}
Use \li{solve_ivp} to solve \eqref{eqn: Pred-Prey} with initial conditions $(r_0, w_0) = (5, 3)$ and time ranging from $0$ to $20$ years.
Display the resulting rabbit and wolf populations over time (stored as rows in the attribute \li{y} of the output of \li{solve_ivp}) on the same plot. Your graph should match the graph in figure \ref{fig: Pred-Prey}.
\end{problem}

\begin{comment}
\objective{We use IVP methods to study two dynamical systems.
The first  system is a weight change model based on thermodynamics and kinematics.
The second model looks at the relationship between a predator and its prey. }

\section*{ODE solvers}
Initial Value Problems, or IVPs, are a system of one or more ordinary differential equations (ODEs) with initial values.
In more basic math courses, these problems can be solved by hand, but in real life that is very much not the case.
For more complicated IVPs, numerical solvers are required.

In the previous lab, you built your own numerical solvers. For this lab you will use two built in solvers from the \li{scipy.integrate} library, \li{ode} and \li{odeint}. The \li{ode} solver solves a single equation of the form $u'(t)=f(t,u)$ and takes the function $f$ as a parameter. This solver can be implemented with various numerical approximations. We will use the \li{dopri5} method, which runs RK4 iterative ODE solver (Runge-Kutta method of order 4). The \li{odeint} solver is similar but solves a system of ODEs rather than a single equation.

In later labs we will build our own numerical solvers but for this lab you will learn how to use two methods built in to Python. You will be expected to use these methods to solve ODEs in future labs.

The solvers used in this lab are contained in the \li{scipy.integrate} library. The first solver, \li{scipy.integrate.ode}, solves the equation $u'(t)=f(t,u)$ and takes the function $f$ as a parameter.

The \li{ode} method can use many numerical approximations to solve.
We will use the \li{dopri5} method, which runs the RK4 (Runge-Kutta method of order 4) iterative ODE solver.

At the end of this lab you will see a similar method, \li{scipy.integrate.odeint} which solves a system of ODEs rather than a single ODE.

The \li{scipy.integrate} library contains two solvers that we will use in this lab. We will first introduce the basic numerical solver \li{scipy.integrate.ode}.
We will introduce basic numerical s \li{ode} method in \li{scipy.integrate} and work through an example so you can understand how ODE solvers work to solve IVP problems.
At the end of this lab you will see a similar method, \li{odeint}, in the same package.

The \li{ode} method can use many numerical approximations to solve.
We will use the \li{dopri5} method, which runs the RK4 (Runge-Kutta method of order 4) iterative ODE solver.

Below you will see sample code for solving a differential equation.

\section*{ODE solvers}
Inital Value Problems, or IVPs, are a system of one or more ordinary differential equations (ODEs) with initial values.
In more basic math courses, these problems could be solved by hand, but in real life that is very much not the case.
For more complicated IVPs, numerical solvers are required.
We will introduce the basic \li{ode} method in \li{scipy.integrate} and work through an example so you can understand how ODE solvers work to solve IVP problems.
At the end of this lab you will see a similar method, \li{odeint}, in the same package.

The \li{ode} method can use many numerical approximations to solve.
We will use the \li{dopri5} method, which runs the RK4 (Runge-Kutta method of order 4) iterative ODE solver.

Below you will see sample code for solving a differential equation.

\subsection*{Predator-Prey Model}
One common problem to solve is the predator-prey model which involves two species, where one species (the prey) is the food source of the other species (the predator).
For this example we will consider the predator to be wolves and the prey to be rabbits in Yellowstone National Park.
Let \li{t} represent time, \li{r(t)} represents the rabbit population at time \li{t}, and \li{w(t)} represents the wolf population at time \li{t}.

We need to make a few assumptions in this model:
\begin{itemize}
\item In the absence of wolves, the rabbit population grows at a positive rate proportional to the current population.
Thus $dr/dt = ar(t)$ when $w(t) = 0$, where $a>0$.
\item In the absence of rabbits, the wolves die out.
Thus $dw/dt = -cw(t)$ when $r(t) = 0$, where $c>0$.
\item The number of encounters between rabbits and wolves is proportional to the product of their populations.
Encounters encourage the growth of the wolf population and a decrease in the rabbit population.
The growth rate of rabbits is decreased by some $-\alpha r(t) w(t)$ and the growth rate of wolves is increased by $\gamma r(t) w(t)$
\end{itemize}

This leads us to the following system of ODEs (for simplicity of notation we will drop off \li{t}:
\begin{align}
	\begin{split}
	&dr/dt = ar - \alpha r w = r(a - \alpha w)\\
	&dw/dt = -cw + \gamma r w = w(-c + \gamma r)
	\end{split}\label{eqn: Pred-Prey}
\end{align}

Now we will run through this example.
Start with the necessary imports.

\begin{lstlisting}
from scipy.integrate import ode
import numpy as np
import matplotlib.pyplot as plt
\end{lstlisting}

Establish our initial conditions

\begin{lstlisting}
r0 = 5 # Initial rabbit population
w0 = 3 # Initial wolf population

# Define rabbit growth paramters
a = 1.0
alpha = 0.5

# Define wolf growth parameters
c = 0.75
gamma = 0.25

t_f = 20 # How long we want to run the model
y0 = [r0, w0]

# Initialize time and output arrays needed for the ode solver
t = np.linspace(0, t_f, 5*t_f)
y = np.zeros((len(t), len(y0)))
y[0,:] = y0
\end{lstlisting}

\begin{problem}
Finish the following code box. You will create the function that takes as input the time, current \li{r} and \li{w} values, and all growth parameters.
\begin{lstlisting}
def predator_prey(t, y, a, alpha, c, gamma):
	'''
	Parameters:
	--------------
	t:	time variable.
	y:	an array of length len(y0) representing current wolf and rabbit populations at time t.
	a, alpha, c, gamma:	growth parameters. These are keyword arguments and can be of any length.

	Return:
	--------
	Return a list corresponding to the Predator-Prey model.
	'''
	pass
\end{lstlisting}
\end{problem}

We need to set up our ODE solver to use the RK4 numerical integrator and give it the correct initial values.
Also note that the \li{predator_prey} function above must be turned into a \li{lambda} function.

\begin{lstlisting}
predator_prey_ode = lambda t, y:predator_prey(t, y, a, alpha, c, gamma)
p_p_solver = ode(predator_prey_ode).set_integrator('dopri5') # set the numerical integrator
p_p_solver.set_initial_value(y0, 0) # Set the initial values. The second argument is the initial time, which we set to 0
\end{lstlisting}

The \li{ode} solver has an \li{integrate} method which solves one time step at a time.
Iterate through the time array and update the \li{y} values at each step.
\begin{lstlisting}
for j in range(1, len(t)):
	y[j,:] = p_p_solver.integrate((t[j]))
\end{lstlisting}

The following code can be used to graph the resulting system. See Figure \ref{fig: Pred-Prey}.

\begin{lstlisting}
plt.plot(t, y[:,0], label='rabbit')
plt.plot(t, y[:,1], label='wolf')
plt.legend()
plt.xlabel('Time')
plt.ylabel('Population')
plt.show()
\end{lstlisting}

\begin{figure}
\centering
\includegraphics[width=\textwidth]{Predator_Prey.pdf}
\caption{The solution to the system found in \eqref{eqn: Pred-Prey}}
\label{fig: Pred-Prey}
\end{figure}

\begin{problem}
Graph the wolf-rabbit model given in \eqref{eqn: Pred-Prey}.
It should look like Figure \ref{fig: Pred-Prey}.
\end{problem}
\end{comment}

\section*{Variations on the Predator-Prey}
\subsection*{The Lotka-Volterra model}
The representation of the predator-prey relationship found in \eqref{eqn: Pred-Prey} is called the Lotka-Volterra predator-prey model and is typically given by %. This well-known system of ODEs is typically given by
%This type of problem has a special name.
%The Lotka-Volterra predator-prey model is a well-known
%system of ODEs given by
\begin{align*}
	\frac{du}{dt} &= \alpha u - \beta uv,\\
	\frac{dv}{dt} &= -\delta v + \gamma uv.
\end{align*}
where $u$ and $v$ represent the prey and predator populations, respectively. Here $\alpha$, $\beta$, $\delta$, and $\gamma$ are the same as before but now for an arbitrary prey and predator.% represents the rate of growth of the prey, and $bu$ the amount of prey being eaten.
%Similarly, $c$ represents the rate of natural predator death, and $du$ the growth of the predator population due to the quantity of prey eaten.

The equlibria (fixed points) of a system occur when the derivatives are zero.
In this example, that occurs at $(u,v)=(0,0)$ and $(u,v)=(\frac{c}{d},\frac{a}{b})$.
%Notice also that if $v=0$ (there are no predators), the population of prey will grow exponentially.
Visualizing the phase portrait helps to give more insight into the dynamics of a system. We will do this by first nondimensionalzing our system to reduce the number of parameters.
\begin{comment}
First we note that there are exactly two equilibria (fixed points): either $(u,v) = (0,0)$ corresponding to the extinction of both species, or $(u,v) = (\frac{\delta}{\gamma},\frac{\alpha}{\beta})$.
Furthermore, from the ODEs we can see that if $v=0$ (there is an absence of any predators) then the population of prey will grow exponentially.

To get a better idea of the dynamics of this system we will graph its phase portrait.
We begin by nondimensionalizing the system to reduce the number of parameters:\end{comment}
Let $U = \frac{\gamma}{\delta}u,$ $V = \frac{\beta}{\alpha}v$, $\bar{t} = \alpha t,$ and $\eta = \frac{\gamma}{\alpha}$.
Substituting into the original ODEs we obtain the nondimensional system of equations
\begin{align}
	\begin{split}
	\frac{dU}{d\bar{t}} &= U(1-V),\\
	\frac{dV}{d\bar{t}} &= \eta V (U-1).
	\end{split}\label{lotka_volterra}
\end{align}
\begin{figure}
\centering
\includegraphics[width=\textwidth]{figures/LV_Phase_Portrait.png}
\caption{The phase portrait for the nondimensionalized Lotka-Volterra predator-prey equations with parameters $\eta = 1/3$.
%The portrait includes the direction field, the two equilibrium points, and the graph of the solution with initial conditions $(U,V) = (3/4, 3/4)$.
 }
\label{fig: lotka-phase}
\end{figure}

%\begin{figure}
%\centering
%\includegraphics[width=\textwidth]{Lotka_Volterra.pdf}
%\caption{The solution of the nondimensionalized Lotka-Volterra predator-prey equations with parameter $\alpha = 1/3$.
%This solution has initial conditions $(U,V) = (3/4, 3/4)$.}
%\label{fig: lotka-phase}
%\end{figure}

\begin{problem}
Similar to problem 1, define the function \li{Lotka_volterra()} that takes in the current predator and prey populations as a 1d array $y$ and the current time as a float $t$ and returns the right hand side of the system \eqref{lotka_volterra} with $\eta=1/3$.
%\begin{lstlisting}
%def Lotka_Volterra(y, t):
%    """
%    Parameters:
%    _______________
%    y:    an array of length len(Y0) representing current (nondimensionalized) predator and prey populations at time t.
%    t:    time variable.

%    Return:
%    _______________
%    Return a tuple corresponding the the Lotka Volterra Predator-Prey model.
%    """
%    pass
%\end{lstlisting}
The following three lines of code plot the phase portrait of \eqref{lotka_volterra}.
For more documentation on quiver plots see \href{https://matplotlib.org/api/_as_gen/matplotlib.pyplot.quiver.html}{the documentation}.
\begin{lstlisting}
Y1, Y2 = np.meshgrid(np.linspace(0, 4.5, 25), np.linspace(0, 4.5, 25))
dU, dV = Lotka_Volterra(0, (Y1, Y2))
Q = plt.quiver(Y1[::3, ::3], Y2[::3, ::3], U[::3, ::3], V[::3, ::3])
\end{lstlisting}
Using \li{solve_ivp}, solve \eqref{lotka_volterra} with three different initial conditions $y_0 = (1/2, 1/3)$, $y_0=(1/2, 3/4)$, and $y_0=(1/16, 3/4)$ and time domain $t = [0,13]$. Plot these three solutions on the same graph as the phase portrait and the equilibria $(0,0)$ and $(1,1)$.

Since your solutions are being plotted with the phase portrait, plot the two populations against each other (instead of both individually against time). Your plot should match \ref{fig: lotka-phase}.
\end{problem}
\begin{comment}
In the following code we plot the phase portrait of \eqref{lotka_volterra} along with a example trajectory, see Figures  \ref{fig:pred-prey_Lotka_Voterra} and \ref{fig:pred-prey_Lotka_Voterra_Phase_Portrait}.
We will use \li{scipy.integrate.odeint} which acts similar to the \li{ode} function used earlier but integrates over all the time steps at once.
To plot the direction field for the equations we use \li{numpy}'s \li{meshgrid} function and \li{matplotlib}'s \li{quiver} function.

\begin{lstlisting}
from scipy.integrate import odeint
a, b = 0., 13.                    # (Nondimensional) Time interval for one 'period'
alpha = 1. / 3                    # Nondimensional parameter
dim = 2                           # dimension of the system
y0 = np.array([1 / 2., 1 / 3.])   # initial conditions

# Note: swapping order of arguments to match the calling convention
# used in the built in IVP solver.
def Lotka_Volterra(y, x):
    return np.array([y[0] * (1. - y[1]), alpha * y[1] * (y[0] - 1.)])

subintervals = 200
# Using the built in ode solver
Y = odeint(Lotka_Volterra, y0, np.linspace(a, b, subintervals))

# Plot the direction field
Y1, Y2 = np.meshgrid(np.arange(0, 4.5, .2), np.arange(0, 4.5, .2), sparse=True, copy=False)
U, V = Lotka_Volterra((Y1, Y2), 0)
Q = plt.quiver(Y1[::3, ::3], Y2[::3, ::3],  U[::3, ::3],  V[::3, ::3], pivot='mid', color='b', units='dots',width=3.)
# Plot the 2 Equilibrium points
plt.plot(1, 1, 'ok', markersize=8)
plt.plot(0, 0, 'ok', markersize=8)
# Plot the solution in phase space
plt.plot(Y[:,0], Y[:,1], '-k', linewidth=2.0)
plt.plot(Y[::10,0], Y[::10,1], '*b')

plt.axis([-.5, 4.5, -.5, 4.5])
plt.title("Phase Portrait of the Lotka-Volterra Predator-Prey Model")
plt.xlabel('Prey',fontsize=15)
plt.ylabel('Predators',fontsize=15)
plt.show()
\end{lstlisting}

\begin{problem}
Compute the solutions $(U,V)$ of \eqref{lotka_volterra}
% \begin{align*}
% 	\frac{dU}{d\bar{t}} &= U(1-V),\\
% 	\frac{dV}{d\bar{t}} &= \alpha V (U-1).
% \end{align*}
for initial conditions $(1/2, 3/4)$, $(1/16, 3/4)$, and $(1/40, 3/4)$.
Add these solutions to the phase portrait of the Lotka-Volterra model.
Can you see any limitations of this model?
\end{problem}
\end{comment}
%\begin{figure}
%\centering
%\includegraphics[width=\textwidth]{LV_Phase_Portrait.png}
%\caption{The phase portrait for the nondimensionalized Lotka-Volterra predator-prey equations with parameters $\alpha = 1/3$.
%The portrait includes the direction field, the two equilibrium points, and the graph of the solution with initial conditions $(U,V) = (3/4, 3/4)$.
% }
%\label{fig:pred-prey_Lotka_Voterra_Phase_Portrait}
%\end{figure}

\subsection*{The Logistic model}
Notice that the Lotka-Volterra equations predict prey populations will grow exponentially in the absence of predators. The logistic predator-prey equations change this dynamic by adding a carrying capacity $K$ to the prey population:%term to give the prey population a carrying capacity $K$:
\begin{comment}
We have already noticed that in the absence of predators, the Lotka-Volterra equations predict that the prey population will grow exponentially.
The logistic predator-prey equations change this dynamic by adding a term to give the prey population a carrying capacity $K$:
\end{comment}
\begin{align*}
	\frac{du}{dt} &= \alpha u\left(1 -\frac{u}{K}\right) - \beta uv,\\
	\frac{dv}{dt} &= -\delta v + \gamma uv.
\end{align*}
We can again do dimensional analysis on this system to simplify parameters. Let $U = \frac{u}{K},$ $V = \frac{\beta}{\alpha}v$, $\bar{t} = \alpha t,$  $\eta = \frac{\gamma K}{\alpha}$, and $\rho = \frac{\delta}{\gamma K}$.
Then the nondimensional logistic equations are
\begin{align}
	\begin{split}
	\frac{dU}{d\bar{t}} &= U(1-U-V),\\
	\frac{dV}{d\bar{t}} &= \eta V (U-\rho).
	\end{split} \label{logistic_pred_prey}
\end{align}

\begin{problem}
Define a new function \li{Logistic_Model()} that takes in the current predator and prey populations $y$ and the current time $t$ and returns the right hand side of \eqref{logistic_pred_prey} as a tuple. Use \li{solve_ivp} to compute solutions $(U,V)$ of \eqref{logistic_pred_prey}
for initial conditions $(1/3, 1/3)$ and $(1/2, 1/5)$ with $(t0,tf)=(0,13)$.
Do this for parameter values $\eta$, $\rho = 1$, $0.3$ and also for values $\eta$, $\rho = 1$, $1.1$.

Create a phase portrait for the logistic equations using both sets of parameter values.
Plot the direction field, all equilibrium points, and both solution orbits on the same plot for each set of parameter values.
\end{problem}

\section*{A Weight Change Model}
The main idea behind weight change is simple. If a person takes in more energy than they expend, they gain weight. If they take in less than they expend, they lose weight. Let \emph{energy balance} $EB$ be the difference between \emph{energy intake} $EI$ and \emph{energy expenditure} $EE$, so that $$EB = EI - EE.$$
If the balance is positive, weight is gained and similarly if the balance is negative, weight is lost.

A person's body weight at a time $t$ can be expressed as the sum of the weight of their fat tissue $F(t)$ and the weight of their lean tissue $L(t)$; that is, $BW(t) = F(t) + L(t)$. Using this, the change in body weight can be expressed as the following system of ODEs:
\begin{align}
        \begin{split}
                \dfrac{dF}{dt} &= \frac{(1-p(t)) EB(t)}{\rho_F},\\
                \dfrac{dL}{dt} &= \frac{p(t) EB(t)}{\rho_L},
        \end{split}\label{eqn:compartment}
\end{align}
where $(1-p(t))$ and $p(t)$ represent the proportion of the energy balance ($EB(t)$) that results in a change in the quantity of fatty or lean tissue, respectively. The constants $\rho_F$ and $\rho_L$ represent the energy density of fatty and lean tissue, approximated as $\rho_F=9400$ kcal/kg and $\rho_L=1800$ kcal/kg.

To solve this system, we first need to express $p(t)$ and $EB(t)$ in terms of $F$ and $L$. These functions will also depend on physical activity level, $PAL$, and energy intake, $EI$, which vary among individuals.% along with other constant parameters.

We will find an expression for $p(t)$ using Forbes' Law% \cite{Fo.2}
 \footnote{\emph{Lean body mass-body fat interrelationships in humans}, Forbes, G.B.; \emph{ Nutrition reviews}, pgs 225-231, 1987.}
which states that $$\frac{dF}{dL}=\frac{F}{10.4}.$$ Notice
\[
\dfrac{F}{10.4} = \dfrac{dF}{dL} = \dfrac{dF/dt}{dL/dt} = \dfrac{\dfrac{(1-p(t)) EB(t)}{\rho_F}}{\dfrac{p(t) EB(t)}{\rho_L}} = \dfrac{\rho_L}{\rho_F} \dfrac{1-p(t)}{p(t)}.
\]
Solving for $p(t)$ gives Forbes' equation
\begin{equation}
\label{eqn:Forbes2}
p(t) = \dfrac{C}{C+F(t)}\quad\mbox{where}\quad C=10.4\dfrac{\rho_L}{\rho_F}.
\end{equation}
We will now find an expression for $EB(t)$. Recall $EB(t)=EI-EE$. We will use the following expression for energy expenditure ($EE$) to define $EB(t)$.
\begin{equation}
\label{eqn:EE1}
EE=PAL \times RMR
\end{equation}
%\begin{equation}
%\label{eqn:EE}
%EE = \underbrace{\delta BW}_\text{\parbox{1cm}{physical\\activity}} + \underbrace{\beta_{tef} EI}_\text{\parbox{1cm}{thermic\\effect of\\eating}} + \underbrace{\beta_{at} EI + \gamma_F F + \gamma_L L + \eta_F \dfrac{dF}{dt} + \eta_L \dfrac{dL}{dt}  + K}_\text{resting metabolic rate (RMR)},
%EE = \delta BW + \beta_{tef}EI + RMR
%\end{equation}
where $PAL$ is physical activity level (as previously mentioned) and $RMR$ is resting metabolic rate.
Physical activity level can be determined using the table above.
\begin{table}[h]
\begin{center}
\begin{tabular}{|l|l|}
\hline
1.40--1.69 & People who are sedentary and do not exercise regularly, spend \\
& most of their time sitting, standing, with little body displacement
\\
\hline
1.70--1.99 & People who are active, with frequent body displacement throughout  \\
& the day or who exercise frequently\\
\hline
2.00--2.40 & People who engage regularly in strenuous work or exercise for \\
& several hours each day\\
\hline
\end{tabular}
\caption{This is a rough guide for physical activity level (PAL).
% For more detailed estimates, see \cite{Heym} and Appendix \ref{PAL_appendix}.
}
\end{center}\label{tab:PAL_table}
\end{table}

We will use the following equation for computing $RMR$,
\begin{equation}
RMR = K + \gamma_F F(t) + \gamma_L L(t) + \eta_F \dfrac{dF}{dt} + \eta_L \dfrac{dL}{dt}  + \beta_{at} EI ,
\label{eqn:RMR}
\end{equation}
where $\gamma_F = 3.2$ kcal/kg/d, $\gamma_L = 22$ kcal/kg/d, $\eta_F = 180$ kcal/kg, and $\eta_L = 230$ kcal/kg
\footnote{\emph{Modeling weight-loss maintenance to help prevent body weight regain}; Hall, K.D. and Jordan, P.N.; \emph{The American journal of clinical nutrition}, pg 1495, 2008}
\footnote{\emph{Quantification of the effect of energy imbalance on bodyweight}; Hall, K.D. et al.; \emph{The Lancet}, pgs 826-837, 2011}.
% \cite{Hall.2, Hall.4}.
Further, we let $\beta_{at}=0.14$ denote the coefficient for adaptive thermogenesis.
%The parameter $\delta$ is the coefficient representing the amount of energy expended from physical activity per kilogram of body mass.
%Notice that $\gamma_L$ is significantly larger than $\gamma_F$.
%This means that lean tissue metabolizes energy much faster than fatty tissue.
%As a result, there are instances where one may want to increase their lean body mass through resistance training so that they are better able to support a higher caloric intake without significant weight gain.
Finally, we remark that the constant $K$ can be tuned to an individual's body type directly through RMR and fat measurement, and is assumed to remain constant over time.

\begin{comment}
The main idea behind weight change is simple.
If a person's energy intake is more than their energy expended, then they gain weight.
If their intake is less, then they lose weight.
Let the \emph{energy balance} $EB$ be the difference between \emph{energy intake} $EI$ and \emph{energy expenditure} $EE$, so that
\begin{equation}
\label{eqn:EB}
EB = EI - EE.
\end{equation}
When the energy intake is greater than the energy expended, the balance is positive and weight is gained.
Similarly, the balance is negative and weight is lost if the energy intake is less than the energy expended.

Body weight at time $t$ is the sum of the weight of fat and lean tissue; that is,  $BW(t) = F(t) + L(t).$
These quantities can be described by the compartmental model
% \begin{subequations}
% \label{eqn:compartment}
% \begin{align}
% \rho_F \dfrac{dF(t)}{dt} &= (1-p(t)) EB(t),\label{eqn:compartment:a}\\
% \rho_L \dfrac{dL(t)}{dt} &= p(t) EB(t),\label{eqn:compartment:b}
% \end{align}
% \end{subequations}

\begin{align}
	\begin{split}
		\rho_F \dfrac{dF(t)}{dt} &= (1-p(t)) EB(t),\\
		\rho_L \dfrac{dL(t)}{dt} &= p(t) EB(t),
	\end{split}\label{eqn:compartment}
\end{align}
where $p(t)$ and $1-p(t)$ represent the proportion of the energy balance ($EB(t)$) that results in a change in the quantity of lean or fatty tissue, respectively.
Constants $\rho_L$ and $\rho_F$ represent the energy density of lean and fatty tissue (about $1800$ and $9400$ kcal/kg).

Next we need to find expressions for $p(t)$ and $EB(t)$ in terms of $L$ and $F$ (the dependent variables), $PAL$ and $EI$ (possibly varying parameters), and other constant parameters.

 The proportion $p(t)$ will vary with $F$ and $L$; from Forbes' Law
 % \cite{Fo.2}
 \footnote{\emph{Lean body mass-body fat interrelationships in humans}, Forbes, G.B.; \emph{ Nutrition reviews}, pgs 225-231, 1987.}
 we have that
\begin{equation}
\label{eqn:forbes}
\dfrac{dF}{dL} = \dfrac{F}{10.4}.
\end{equation}
Hence,
\[
\dfrac{F}{10.4} = \dfrac{dF}{dL} = \dfrac{dF/dt}{dL/dt} = \dfrac{\dfrac{(1-p(t)) EB(t)}{\rho_F}}{\dfrac{p(t) EB(t)}{\rho_L}} = \dfrac{\rho_L}{\rho_F} \dfrac{1-p(t)}{p(t)}.
\]
Solving for $p(t)$ gives Forbes' equation
\begin{equation}
\label{eqn:Forbes2}
p(t) = \dfrac{C}{C+F(t)}\quad\mbox{where}\quad C=10.4\dfrac{\rho_L}{\rho_F}.
\end{equation}
We will use two expressions for energy expenditure (EE).
First, we have the formula
\begin{equation}
\label{eqn:EE0}
EE = PAL \times RMR,
\end{equation}
where $PAL$ is your physical activity level and $RMR$ your resting metabolic rate.
Your resting metabolic rate can be determined by using the Mifflin equation.
This equation is an estimate based on a population study and is widely used in the literature.
It takes into account your gender, age (A) in years, and height (H) in meters:
\begin{equation}
\label{eqn:RMR}
RMR = \begin{cases} 9.99 W + 625 H + 5 A + 5 & \mbox{if male}\\ 9.99 W + 625 H + 5 A -161 & \mbox{if female.}\end{cases}
\end{equation}
Your physical activity level can be determined by using the table below.
\begin{table}[h]
\begin{center}
\begin{tabular}{|l|l|}
\hline
1.40--1.69 & People who are sedentary and do not exercise regularly, spend \\
& most of their time sitting, standing, with little body displacement
\\
\hline
1.70--1.99 & People who are active, with frequent body displacement throughout  \\
& the day or who exercise frequently\\
\hline
2.00--2.40 & People who engage regularly in strenuous work or exercise for \\
& several hours each day\\
\hline
\end{tabular}
\caption{This is a rough guide for physical activity level (PAL).
% For more detailed estimates, see \cite{Heym} and Appendix \ref{PAL_appendix}.
}
\end{center}\label{tab:PAL_table}
\end{table}

The second expression for energy expenditure comes from decomposing more precisely the different ways that energy is expended:
\begin{equation}
\label{eqn:EE}
EE = \underbrace{\delta BW}_\text{\parbox{1cm}{physical\\activity}} + \underbrace{\beta_{tef} EI}_\text{\parbox{1cm}{thermic\\effect of\\eating}} + \underbrace{\beta_{at} EI + \gamma_F F + \gamma_L L + \eta_F \dfrac{dF}{dt} + \eta_L \dfrac{dL}{dt}  + K}_\text{resting metabolic rate (RMR)},
\end{equation}
where $\gamma_F = 3.2$ kcal/kg/d, $\gamma_L = 22$ kcal/kg/d, $\eta_F = 180$ kcal/kg, and $\eta_L = 230$ kcal/kg
\footnote{\emph{Modeling weight-loss maintenance to help prevent body weight regain}; Hall, K.D. and Jordan, P.N.; \emph{The American journal of clinical nutrition}, pg 1495, 2008}
\footnote{\emph{Quantification of the effect of energy imbalance on bodyweight}; Hall, K.D. et al.; \emph{The Lancet}, pgs 826-837, 2011}.
% \cite{Hall.2, Hall.4}.
Further, we let $\beta_{tef}=0.10$ and $\beta_{at}=0.14$ denote the coefficients for the thermic effect of feeding and adaptive thermogenesis, respectively.
The parameter $\delta$ is the coefficient representing the amount of energy expended from physical activity per kilogram of body mass.
Notice that $\gamma_L$ is significantly larger than $\gamma_F$.
This means that lean tissue metabolizes energy much faster than fatty tissue.
As a result, there are instances where one may want to increase their lean body mass through resistance training so that they are better able to support a higher caloric intake without significant weight gain.
Finally, we remark that the constant $K$ can be tuned to an individual's body type directly through RMR and fat measurement, and is assumed to remain constant over time.
\end{comment}
% Assumptions made/Areas to improve:
% include more accurate approximation of PAL (given in appendix), BMI (show to vary with race), account for variation in body type.

Thus, since the input $EI$ is assumed to be known, we can use \eqref{eqn:EE1}, \eqref{eqn:RMR} and \eqref{eqn:Forbes2} to write \eqref{eqn:compartment} in terms of $F$ and $L$, thus allowing us to close the system of ODEs.

Specifically, we have
\begin{align*}
RMR = \frac{EE}{PAL}&= K + \gamma_F F(t) + \gamma_L L(t) + \eta_F \dfrac{dF}{dt} + \eta_L \dfrac{dL}{dt}  + \beta_{at} EI\\
% &= K + \gamma_F F(t) + \gamma_L L(t) + \dfrac{\eta_F}{\rho_F} (1-p(t)) EB(t) + \dfrac{\eta_L}{\rho_L} p(t) EB(t)  + \beta_{at} EI,\\
\dfrac{1}{PAL}\left(EE - EI + EI \right) &= K + \gamma_F F(t) + \gamma_L L(t) \\
&\quad+ \left(\dfrac{\eta_F}{\rho_F} (1-p(t)) + \dfrac{\eta_L}{\rho_L} p(t) \right) EB(t) + \beta_{at} EI.\\
\left(\dfrac{1}{PAL}-\beta_{at}\right) EI &= K + \gamma_F F(t) + \gamma_L L(t) \\
&\quad+ \left(\dfrac{\eta_F}{\rho_F} (1-p(t)) + \dfrac{\eta_L}{\rho_L} p(t) + \dfrac{1}{PAL}\right) EB(t).
\end{align*}
% Thus,
% \[
% \left(\dfrac{1}{PAL}-\beta_{at}\right) EI = K + \gamma_F F(t) + \gamma_L L(t) + \left(\dfrac{\eta_F}{\rho_F} (1-p(t)) + \dfrac{\eta_L}{\rho_L} p(t) + \dfrac{1}{PAL}\right) EB(t).
% \]
Solving for $EB(t)$ in the last equation yields
\begin{equation}
\label{eqn:EB2}
EB(t) = \dfrac{\left( \dfrac{1}{PAL} - \beta_{at} \right) EI - K - \gamma_F F(t) - \gamma_L L(t)}{\dfrac{\eta_F}{\rho_F} (1-p(t)) + \dfrac{\eta_L}{\rho_L} p(t) + \dfrac{1}{PAL}}.
\end{equation}
% To find $K$, we note that
% \begin{equation}
% \label{eqn:K}
% K = \left(\dfrac{1}{PAL}-\beta_{at}\right) EI - \gamma_F F(t) - \gamma_L L(t) - \eta_F \dfrac{dF}{dt} - \eta_L \dfrac{dL}{dt}  - \dfrac{1}{PAL} EB.
% \end{equation}
In equilibrium ($EB = 0$), this gives us
\begin{equation}
\label{eqn:K2}
K = \left(\dfrac{1}{PAL}-\beta_{at}\right) EI - \gamma_F F - \gamma_L L.
\end{equation}
Thus, for a subject who has maintained the same weight for a while, one can determine $K$ by using \eqref{eqn:K2}, if they know their average caloric intake and amount of fat (assume $L=BW-F$).
%The function \li{weight_odesystem} in the following code implements \eqref{eqn:compartment}.

%The following code defines the constants as given above and defines functions representing \eqref{eqn:Forbes2} and \eqref{eqn:EB2} respectively.

\begin{problem}
Write a function \li{forbes()} which takes as input \li{F}, the weight of fat tissue at a given time (i.e. the function $F(t)$ evaluated at a certain time), and returns Forbe's equation given in \eqref{eqn:Forbes2}.
Also write the function \li{energy_balance()} which takes as input \li{F}, \li{L}, \li{PAL}, and \li{EI} and returns the energy balance as given in \eqref{eqn:EB2}.
In \li{energy_balance()} we also have that \li{F} is the fat tissue weight at a given time, and \li{L} is the lean tissue weight at a given time.

Using \li{forbes()} and \li{energy_balance()}, define the function \li{weight_odesystem()} which takes as input the current time as a float $t$ and the current fat and lean weights as an array $y$ and returns the right hand side of \eqref{eqn:compartment} as a tuple.

Use $\rho_F = 9400$, $\rho_L = 1800$, $\gamma_F = 3.2$, $\gamma_L = 22$, $\eta_F = 180$, $\eta_L = 230$, $K=0$ and $\beta_{AT} = 0.14$.
%These constants should be implemented using keyword arguments in the functions that need them.

Hint: The functions \li{forbes()} and \li{energy_balance()} are not time dependent in the same way equations \eqref{eqn:Forbes2} and \eqref{eqn:EB2} are.
The time dependent portions of these functions, $F(t)$ and $L(t)$, are determined by what will be input from the \li{y} argument of \li{weight_odesystem()}.
\end{problem}
%\begin{lstlisting}
%# Fixed Constants:
%rho_F, rho_L = 9400., 1800.
%gamma_F, gamma_L = 3.2, 22.
%eta_F, eta_L = 180., 230.
%C = 10.4                         # Forbes constant
%beta_AT = 0.14                   # Adaptive Thermogenesis

%def forbes(F):
%    C1 = C * rho_L / rho_F
%    return C1 / (C1 + F)

%def energy_balance(F, L, EI, PAL):
%    p = forbes(F)
%    a1 = (1. / PAL - beta_AT) * EI - K - gamma_F * F - gamma_L * L
%    a2 = (1 - p) * eta_F / rho_F + p * eta_L / rho_L + 1. / PAL
%    return a1 / a2

%\end{lstlisting}
\begin{comment}
def weight_odesystem(t, y, EI, PAL):
    F, L = y[0], y[1]
    p, EB = forbes(F), energy_balance(F, L, EI, PAL)
    return np.array([(1 - p) * EB / rho_F , p * EB / rho_L])

def fat_mass(BW, age, H, sex):
    BMI = BW / H**2.
    if sex == 'male':
        return BW * (-103.91 + 37.31 * log(BMI) + 0.14 * age) / 100
    else:
        return BW * (-102.01 + 39.96 * log(BMI) + 0.14 * age) / 100
\end{comment}

\begin{figure}
\centering
\includegraphics[width=\textwidth]{figures/weightloss_graph.png}
\caption{The solution of the weight change model for problem 6.}
\label{fig:weightloss}
\end{figure}

\begin{problem}
%Define the function \li{weight_odesystem()} as given in \eqref{eqn:compartment} using the functions \li{forbes()} and \li{energy_balance()} provided.

Consider the initial value problem corresponding to \eqref{eqn:compartment}.
The following function returns the fat mass of an individual based on body weight (kg), age (years), height (meters), and sex. Use this function to define initial conditions $F_0$ and $L_0$ for the IVP above: $F_0= fat\_mass(args^*)$, $L_0 = BW - F_0$.%Using the result of this function and the provided body weight, you can define initial conditions $F_0$ and $L_0$ for the IVP above, with $F_0 =$\li{fat_mass(args^*)} and $L_0 = BW - F_0$.
\begin{lstlisting}
def fat_mass(BW, age, H, sex):
    BMI = BW / H**2.
    if sex == 'male':
        return BW * (-103.91 + 37.31 * log(BMI) + 0.14 * age) / 100
    else:
        return BW * (-102.01 + 39.96 * log(BMI) + 0.14 * age) / 100
\end{lstlisting}
%To solve this IVP for a specific individual we need initial conditions $F_0$ and $L_0.$
%The function \li{fat_mass} given earlier calculates $F_0$ based on an individual's body weight (kg), age, height (meters), and gender.
%$L_0$ is then given by $L_0 = BW - F_0$.

Suppose a 38 year old female, standing 5'8'' and weighing 160 lbs, reduces her intake from 2143 to 2025 calories/day, and increases her physical activity from little to no exercise (PAL=1.4) to exercising to 2-3 days per week (PAL=1.5).

Use \eqref{eqn:K2} and the original intake and phyical activity levels to compute $K$ for this system. Then use \li{solve_ivp} to solve the IVP. Graph the solution curve for this single-stage weightloss intervention over a period of 5 years. Your plot should match figure \ref{fig:weightloss}.
%Using \li{scipy.integrate.ode}, find and graph the solution curve for this single-stage weightloss intervention over a period of 5 years.

Note the provided code requires quantities in metric units (kilograms, meters, days) while our graph is converted to units of pounds and days.
Use the conversions $1$ lb $=2.204$ kg, $1$ ft $=0.305$ m, and $1$ yr $=365$ days.
\end{problem}

\begin{problem}
Modify the preceding problem to handle a two stage weightloss intervention:
Suppose for the first 16 weeks intake is reduced from 2143 to 1600 calories/day and physical activity is increased from little to no exercise (PAL=1.4) to an hour of exercise 5 days per week (PAL=1.7).
The following 16 weeks intake is increased from 1600 to 2025 calories/day, and exercise is limited to only 2-3 days per week (PAL=1.5).

You will need to recompute $F_0$, and $L_0$ at the end of the first 16 weeks, but $K$ will stay the same.
Find and graph the solution curve over the 32 week period.
\end{problem}

\begin{comment}
\section*{Variations on the Predator-Prey}
\subsection*{The Lotka-Volterra model}
Reconsider \eqref{eqn: Pred-Prey}. This representation of the predator-prey relationship is called the Lotka-Volterra predator-prey model. This well-known system of ODEs is typically given by
%This type of problem has a special name.
%The Lotka-Volterra predator-prey model is a well-known
%system of ODEs given by
\begin{align*}
	\frac{du}{dt} &= au - buv,\\
	\frac{dv}{dt} &= -cv + duv.
\end{align*}
where $u$ and $v$ represent the prey and predator populations, respectively. Here $a$ represents the rate of growth of the prey, and $bu$ the amount of prey being eaten.
Similarly, $c$ represents the rate of natural predator death, and $du$ the growth of the predator population due to the quantity of prey eaten.

Let us look at the dynamics of this system. The equlibria (fixed points) of a system occur when the derivatives are zero, for our system this occurs at $(u,v)=(0,0)$ and $(u,v)=(\frac{c}{d},\frac{a}{b})$.
%Notice also that if $v=0$ (there are no predators), the population of prey will grow exponentially.
Visualizing the phase portrait helps to give more insight into the dynamics of a system. We will do this by first nondimensionalzing our system to reduce the number of parameters.
First we note that there are exactly two equilibria (fixed points): either $(u,v) = (0,0)$ corresponding to the extinction of both species, or $(u,v) = (\frac{c}{d},\frac{a}{b})$.
Furthermore, from the ODEs we can see that if $v=0$ (there is an absence of any predators) then the population of prey will grow exponentially.

To get a better idea of the dynamics of this system we will graph its phase portrait.
We begin by nondimensionalizing the system to reduce the number of parameters:
Let $U = \frac{d}{c}u,$ $V = \frac{b}{a}v$, $\bar{t} = at,$ and $\alpha = \frac{d}{a}$.
Substituting into the original ODEs we obtain the nondimensional system of equations
\begin{align}
	\begin{split}
	\frac{dU}{d\bar{t}} &= U(1-V),\\
	\frac{dV}{d\bar{t}} &= \alpha V (U-1).
	\end{split}\label{lotka_volterra}
\end{align}
In the following code we plot the phase portrait of \eqref{lotka_volterra} along with a example trajectory, see Figures  \ref{fig:pred-prey_Lotka_Voterra} and \ref{fig:pred-prey_Lotka_Voterra_Phase_Portrait}.
We will use \li{scipy.integrate.odeint} which acts similar to the \li{ode} function used earlier but integrates over all the time steps at once.
To plot the direction field for the equations we use \li{numpy}'s \li{meshgrid} function and \li{matplotlib}'s \li{quiver} function.

\begin{figure}
\centering
\includegraphics[width=\textwidth]{Lotka_Volterra.pdf}
\caption{The solution of the nondimensionalized Lotka-Volterra predator-prey equations with parameter $\alpha = 1/3$.
This solution has initial conditions $(U,V) = (3/4, 3/4)$.}
\label{fig:pred-prey_Lotka_Voterra}
\end{figure}

\begin{lstlisting}
from scipy.integrate import odeint
a, b = 0., 13.                    # (Nondimensional) Time interval for one 'period'
alpha = 1. / 3                    # Nondimensional parameter
dim = 2                           # dimension of the system
y0 = np.array([1 / 2., 1 / 3.])   # initial conditions

# Note: swapping order of arguments to match the calling convention
# used in the built in IVP solver.
def Lotka_Volterra(y, x):
    return np.array([y[0] * (1. - y[1]), alpha * y[1] * (y[0] - 1.)])

subintervals = 200
# Using the built in ode solver
Y = odeint(Lotka_Volterra, y0, np.linspace(a, b, subintervals))

# Plot the direction field
Y1, Y2 = np.meshgrid(np.arange(0, 4.5, .2), np.arange(0, 4.5, .2), sparse=True, copy=False)
U, V = Lotka_Volterra((Y1, Y2), 0)
Q = plt.quiver(Y1[::3, ::3], Y2[::3, ::3],  U[::3, ::3],  V[::3, ::3], pivot='mid', color='b', units='dots',width=3.)
# Plot the 2 Equilibrium points
plt.plot(1, 1, 'ok', markersize=8)
plt.plot(0, 0, 'ok', markersize=8)
# Plot the solution in phase space
plt.plot(Y[:,0], Y[:,1], '-k', linewidth=2.0)
plt.plot(Y[::10,0], Y[::10,1], '*b')

plt.axis([-.5, 4.5, -.5, 4.5])
plt.title("Phase Portrait of the Lotka-Volterra Predator-Prey Model")
plt.xlabel('Prey',fontsize=15)
plt.ylabel('Predators',fontsize=15)
plt.show()
\end{lstlisting}

\begin{problem}
Compute the solutions $(U,V)$ of \eqref{lotka_volterra}
% \begin{align*}
% 	\frac{dU}{d\bar{t}} &= U(1-V),\\
% 	\frac{dV}{d\bar{t}} &= \alpha V (U-1).
% \end{align*}
for initial conditions $(1/2, 3/4)$, $(1/16, 3/4)$, and $(1/40, 3/4)$.
Add these solutions to the phase portrait of the Lotka-Volterra model.
Can you see any limitations of this model?
\end{problem}

\begin{figure}
\centering
\includegraphics[width=\textwidth]{Lotka_Volterra_Phase_Portrait.pdf}
\caption{The phase portrait for the nondimensionalized Lotka-Volterra predator-prey equations with parameters $\alpha = 1/3$.
The portrait includes the direction field, the two equilibrium points, and the graph of the solution with initial conditions $(U,V) = (3/4, 3/4)$. }
\label{fig:pred-prey_Lotka_Voterra_Phase_Portrait}
\end{figure}

\subsection*{The Logistic model}
We have already noticed that in the absence of predators, the Lotka-Volterra equations predict that the prey population will grow exponentially.
The logistic predator-prey equations change this dynamic by adding a term to give the prey population a carrying capacity $K$:
\begin{align*}
	\frac{du}{dt} &= au\left(1 -\frac{u}{K}\right) - buv,\\
	\frac{dv}{dt} &= -cv + duv.
\end{align*}
Let $U = \frac{u}{K},$ $V = \frac{b}{a}v$, $\bar{t} = at,$  $\alpha = \frac{dK}{a}$, and $\beta = \frac{c}{dK}$.
Then the nondimensional logistic equations are
\begin{align}
	\begin{split}
	\frac{dU}{d\bar{t}} &= U(1-U-V),\\
	\frac{dV}{d\bar{t}} &= \alpha V (U-\beta).
	\end{split} \label{logistic_pred_prey}
\end{align}

\begin{problem}
Compute the solutions $(U,V)$ of \eqref{logistic_pred_prey}
for initial conditions $(1/3, 1/3)$ and $(1/2, 1/5)$.
Do this for parameter values $\alpha, \beta = 1, .3$ and also for values $\alpha, \beta = 1, 1.1$.
Create a phase portrait for the logistic equations using both sets of parameter values.
Remember to plot the direction field, all equilibrium points, and the orbits of the solutions.
\end{problem}
\end{comment}


%!TEX root =  ../main.tex

\subsection{Initial and Terminal}

\objective{Simplify angles and their coterminal synonyms, and apply them to the three basic trigonometric functions}

Angles are a measure of turning.  Since Babylonian times, it has been customary to divide
the circle into 360 parts, beginning directly off to the right, and proceeding counter-clockwise.
The beginning ray pointing right is known as the \textbf{initial side}, whereas the ray pointing
off where the angle has turned to is called the \textbf{terminal side}.

Because one direction of spin has been designated as positive, it is therefore true that
there exist negative angles.  These also begin at the initial side of $0^\circ$, but proceed
\emph{clockwise}.  Very quickly, there will be multiple names for the same angle.
Angle that end in the same place are called \textbf{coterminal}, after the Latin for the same.
Finding coterminal angles which are the same as a given angle is simply a matter of
adding or subtracting $360^\circ$ as many or as few times as desired.

Some processes in mathematic produce very large angle measures, which can become
cumbersome if dealt with by hand.  While it might be easy in some cases to simply
add or subtract $360^\circ$ until the angle is reasonable, this can become time prohibitive.
It is most efficient to find the remainder when an angle is divided by 360.

Degree/Minutes/Seconds will be dealt with in section §16.3, on sexigesimal numbers.

\subsection{Reference Angles}
Every angle can be thought of as a turn from the closest horizontal axis.  In the
first quadrant, this is the angle itself, without modification.  In the fourth quadrant,
this is reversed, a certain distance down from $0^\circ$, or better, back from
$360^\circ$.  For example, $330^\circ$ is an upside-down version of a $30^\circ$
angle, which is to say, the reference angle for $330^\circ$ is $30^\circ$.

In the second quadrant, things are not upside down, but mirrored.  What is the reference
angle for $150^\circ$?  Well the closest horizontal axis is not $0^\circ/360^\circ$, but
$180^\circ$.  The reference angle for $150^\circ$ is also $30^\circ$.  The third quadrant
is the hardest, being both flipped left-right, and up-down.  But $30^\circ$ past
$180^\circ$ is $210^\circ$.

\begin{figure}[h]
\begin{center}
\includegraphics{\chapdir/pics/reference}
\caption{Reference angles, sometimes call $\theta'$ (nothing to do with derivatives!)}
\end{center}
\end{figure}

\subsection{Trigonometric functions}
Also since ancient times, it has been exceedingly helpful to reference the ratios of
various components of an angle.  On a right triangle, these ratios are often memorized with
the helpful acronym S.O.H.C.A.H.T.O.A., short for sine = opposite/hypotenuse , cosine =
adjacent/hypotenuse, tangent = opposite over adjacent.

\begin{figure}[h]
\includegraphics[scale=0.5]{\chapdir/pics/TrigonometryTriangle.png}
\caption{The names of the sides of a right triangle}
\end{figure}

These definitions can be extended via reference angles to the other quadrants.  In
such a context, the sine of an angle
becomes the signed vertical displacement over the exact distance, cosine of an
angle becomes the signed horizontal displacement over the exact distance,
and tangent of the angle becomes its slope.

While no longer of much use or interest, there are names for the reciprocals of
the three main trigonometric functions.  The reciprocal of cosine is called
secant, the reciprocal of sine is called cosecant, and the reciprocal of tangent
is called cotangent.  Of these, only secant is commonly used (outside of math
classrooms!).


\subsection{Belief functions and exchangeability}
\begin{frame}{Belief functions}
Let $F, G$ and $H \in \mathcal{S}$ be three (possibly overlapping) statements about the world.
For example, consider the following statements about a person:
\begin{itemize}
 \item [F] = \{votes for a left-wing candidate\} ;
 \item [G] = \{is in the 10\% lower income bracket\} ;
 \item [H] = \{lives in a large\} ;
\end{itemize}

 \begin{defn}[Belief function]
 \label{def:belief_function}
 For $A, B \in \mathcal{S}$, a belief function $\be : \mathcal{S} \to \mathbb{R}$ assigns numbers to statements such that $\be(A) < \be(B)$ implies one is more confident in $B$ than in $A$.
 \end{defn}
\end{frame}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{frame}{Belief functions: properties}
It is useful to think of $\be$ as~\textbf{preferences over bets}:
 \begin{itemize}
  \item $\be(F) > \be(G)$ means we would bet on $F$ being true over $G$ being true;
  \item $\be(F\mid H) > \be(G \mid H)$ means that, \textbf{conditional} on knowing $H$ to be true, we would bet on $F$ over $G$;
  \item $\be(F\mid G) > \be(F \mid H)$ means that if we were forced to be on $F$, we would be prefer doing so if $G$ were true than $H$.
 \end{itemize}
\end{frame}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{frame}{Belief functions: axioms}
 In order for $\be$ to be \textbf{coherent}, it must adhere to a certain set of properties/axioms.
 A self-sufficient collection is:
 \begin{itemize}
  \item [A1]  (boundedness of complete [dis]belief): $$\be(\lnot H \mid H) \leq \be(F \mid H) \leq \be(H \mid H),\, \forall\: F \in \mathcal{S};$$
  \item [A2]  (monotonicity):
  $$\be(F \, \text{or} \, G \mid H) \geq \max \left\{ \be(F \mid H), \be(G \mid H) \right\};$$
  \item [A3] (sequentiality): There exists $f: \mathbb{R}^2 \to \mathbb{R}$ such that
  $$ \be(F\, \text{and} \, G \mid H) = f\left(\be(G\mid H), \be(F \mid G\, \text{and} \, H) \right).$$
 \end{itemize}
\end{frame}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{frame}{Probabilities can be beliefs!}
 \begin{exercise}[Probabilities and beliefs]
  Show that the axioms of belief functions map one-to-one to the axioms of probability:
  \begin{itemize}
   \item[P1.] $0 \leq \pr(E), \forall E \in \mathcal{S}$;
   \item[P2.] $\pr(\mathcal{S}) = 1$;
   \item[P3.] For any countable sequence of disjoint statements $E_1, E_2, \ldots \in \mathcal{S}$ we have
   $$ \pr \left(\bigcup_{i=1}^\infty E_i \right) = \sum_{i=1}^\infty \pr(E_i).$$
  \end{itemize}
 \end{exercise}
Hint: derive the consequences (e.g. monotonicity) of these axioms and compare them with the axioms of belief functions.
\end{frame}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{frame}{Useful probability laws}
\begin{defn}[Partition]
 \label{def:partition}
 If $H = \{H_1, H_2, \ldots, H_k\}$, $H_i \in \mathcal{S}$, such that $H_i \cap H_j = \emptyset$  for all $i \neq j$ and $\bigcup_{k=1}^K = \mathcal{S}$, we say $H$ is a partition of $\mathcal{S}$.
\end{defn}
For any $H \in \mathcal{D}(\mathcal{S})$:
 \begin{itemize}
  \item \textbf{Total probability}: $\sum_{k=1}^K \pr(H_k) = 1$;
  \item \textbf{Marginal probability}: $$\pr(E) = \sum_{k=1}^K = \pr(E \cap H_k) =  \sum_{k=1}^K \pr(E \mid H_k)\pr(H_k),$$
  for all $E \in \mathcal{S}$;
  \item Consequence $\implies$ Bayes's rule:
$$ \pr(H_j \mid E) = \frac{\pr(E \mid H_j)\pr(H_j)}{\sum_{k=1}^K \pr(E \mid H_k)\pr(H_k)}.$$
  \end{itemize}
\end{frame}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{frame}{Independence}
We will now state a central concept in probability theory and Statistics.
 \begin{defn}[ (Conditional) Independence]
  For any $F, G \in \mathcal{S}$, we say $F$ and $G$ are~\textbf{conditionally independent} given $A$ if
  $$ \pr(F \cap G \mid A) = \pr(F\mid A)\pr(G\mid A).$$
 \end{defn}
\begin{remark}
 \label{rmk:conditional_indep}
 If $F$ and $G$ are conditionally independent given $A$, then
 $$ \pr(F \mid A \cap G) = \pr(F \mid A).$$
\end{remark}
\begin{proof}
 First, notice that the axioms P1-P3 imply $\pr(F \cap G \mid A) = \pr(G\mid A)\pr(F \mid A \cap G)$.
 Now use conditional independence to write
 \begin{align*}
  \pr(G \mid A) \pr(F \mid A \cap G) &= \pr(F \cap G \mid A) = \pr(F\mid A)\pr(G\mid A),\\
  \pr(G\mid A) \pr(F \mid A \cap G) &= \pr(F\mid A) \pr(G \mid A).
 \end{align*}
\end{proof}
\end{frame}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{frame}{Exchangeability}
\begin{defn}[Exchangeable]
 \label{def:exchangeable}
We say a sequence of random variables $\boldsymbol{Y} = \{ Y_1, Y_2, \ldots, Y_n \}$ are \textbf{exchangeable} if
$$ \pr(Y_1, Y_2, \ldots Y_n) = \pr(Y_{\xi_1}, Y_{\xi_2}, \ldots Y_{\xi_n}),$$
for all \textbf{permutations} $\boldsymbol{\xi}$ of the labels of $\boldsymbol{Y}$.
\end{defn}
\begin{example}[Uma vez Flamengo... continued]
 Suppose we survey 12 people and record whether they cheer for Flamengo $Y_i = 1$ or not $Y_i = 0$, $i=1, 2,\ldots, 12$.
 What value shoud we assign to :
 \begin{itemize}
  \item $p_1 := \pr(1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1)$;
  \item $p_2 :=\pr(1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1)$;
  \item $p_3 := \pr(1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0)$?
 \end{itemize}
If your answer is $p_1 = p_2 = p_3$ then you are saying the $Y_i$ are (at least partially) exchangeable!
\end{example}
\end{frame}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{frame}{An application of conditional independence}
For $\theta \in (0, 1)$, consider the following sequence of probability statements:
\begin{align*}
\pr(Y_{12} = 1 \mid \theta) &= \theta,\\
\pr(Y_{12} = 1 \mid Y_1, \ldots Y_{11}, \theta) & = \theta,\\
\pr(Y_{11} = 1 \mid Y_1, \ldots Y_{10}, Y_{12}, \theta) &= \theta.
\end{align*}
These imply that the $Y_i$ are conditionally independent and identically distributed (iid), and in particular:
\begin{align*}
 \pr(Y_1 = y_1, \ldots, Y_{12} = y_{12} \mid \theta) &= \prod_{i=1}^{12} \theta^{y_i} (1-\theta)^{1-y_i},\\
 &= \theta^{S} (1-\theta)^{12-S},
\end{align*}
with $S := \sum_{i=1}^{12} y_i$.
Also, under a uniform prior,
$$ \pr(Y_1, \ldots Y_{12}) = \int_{0}^1 t^{S} (1-t)^{12-S} \pi(t)\,dt = \frac{(S + 1)!(12-S +1)!}{13!} = \binom{13}{S + 1}^{-1}.$$
\end{frame}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{frame}{Relaxing exchangeability (a bit)}
 Sometimes total symmetry can be a burden.
 We can relax this slightly by introducing the concept of \textbf{partial exchangeability}:
 \begin{defn}[Partially exchangeable]
  \label{def:partially_exchangeable}
  Let $\boldsymbol{X} = \{ X_1, \ldots, X_n\}$ and $\boldsymbol{X} = \{ Y_1, \ldots, Y_m\}$ be two sets of random variables.
  We say $\boldsymbol{X}$ and $\boldsymbol{Y}$ are \textbf{partially} exchangeable if
  $$ \pr\left(X_1, \ldots, X_n ; Y_1, \ldots, Y_m\right) = \pr\left(X_{\xi_1}, \ldots, X_{\xi_n} ; Y_{\sigma_1}, \ldots, Y_{\sigma_m}\right),$$
 \end{defn}
 for any two permutations $\boldsymbol{\xi}$ and $\boldsymbol{\sigma}$ of $1, \ldots, n$ and $1, \ldots, m$, respectively.
 \begin{example}[Uma vez Flamengo...continued]
  To see how exchangeability can be relaxed into partial exchangeability, consider $\boldsymbol{X}$ and $\boldsymbol{Y}$ as observations coming from populations from Rio de Janeiro and Ceará, respectively.
  If the covariate ``state'' were deemed to not matter, then we would have complete exchangeability.
 \end{example}
\end{frame}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{frame}{A statistically useful remark}
 \begin{remark}[Exchangeability from conditional independence]
  \label{rmk:pre_deFinetti}
  Take $\theta \sim \pi(\theta)$, i.e., represent uncertainty about $\theta$ using a probability distribution.
  If $ \pr(Y_1 = y_1, \ldots, Y_{n} = y_n \mid \theta) = \prod_{i=1}^{n} \pr(Y_i = y_i \mid \theta)$, then $Y_1, \ldots, Y_{n}$ are exchangeable.
 \end{remark}
 \begin{proof}
  Sketch:
  Use
  \begin{itemize}
   \item Marginalisation;
   \item Conditional independence;
   \item Commutativity of products in $\mathbb{R}$;
   \item Definition of exchangeability.
  \end{itemize}
 \end{proof}
\end{frame}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{frame}{A fabulous theorem!}
 \begin{theo}[De Finetti's theorem\footnote{Technically, the theorem stated here is more general than the representation theorem proven by De Finetti in his seminal memoir, which concerned binary variables only.}]
  If $\pr\left(Y_1, \ldots, Y_n\right) = \pr\left(Y_{\xi_1}, \ldots, Y_{\xi_n}\right)$ for all permutations $\boldsymbol{\xi}$ of $1, \ldots, n$, then
  \begin{equation}
   \pr\left(Y_1, \ldots, Y_n\right) = \pr\left(Y_{\xi_1}, \ldots, Y_{\xi_n}\right) = \int_{\boldsymbol{\Theta}} \pr\left(Y_1, \ldots, Y_n \mid t\right) \pi(t)\,dt,
  \end{equation}
for some choice of triplet $\{ \theta,  \pi(\theta), f(y_i \mid \theta) \}$, i.e., a parameter, a prior and a sampling model.
 \end{theo}
 See Proposition 4.3 in \cite{Bernardo2000} for a proof outline.
 Here we shall prove the version from~\cite{DeFinetti1931}.
\end{frame}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{frame}{Consequences}
  This theorem has a few important implications, namely:
 \begin{itemize}
  \item $\pi(\theta)$ represents our beliefs about $\lim_{n\to\infty} \sum_i (Y_i \leq c)/n$ for all $c \in \mathcal{Y}$;
  \item \{ $Y_1, \ldots, Y_n \mid \theta $ are i.i.d \} + \{ $\theta \sim \pi(\theta)$ \} $\iff$ \{ $Y_1, \ldots, Y_n$ are exchangeable for all $n$ \};
  \item If $Y_i \in \{0, 1\}$, we can also claim that:
  \begin{itemize}
   \item If the $Y_i$ are assumed to be independent, then they are distributed Bernoulli conditional on a random quantity $\theta$;
   \item $\theta$ has a prior measure $\Pi \in \mathcal{P}( (0, 1) )$;
   \item By the strong law of large numbers (SLLN), $\theta = \lim_{n \to \infty} (\frac{1}{n}\sum_{i=1}^n Y_i)$, so $\Pi$ can be interpreted as a ``belief about the limiting relative frequency of 1's''.
  \end{itemize}
 \end{itemize}
\end{frame}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{frame}{The soul of Statistics}
 As the exchangeability results above clearly demonstrate, being able to use conditional independence is a handy tool.
 More specifically, knowing on what to condition so as to make things exchangeable is key to statistical analysis.
 \begin{idea}[Conditioning is the soul of Statistics\footnote{This idea is due to Joe Blitzstein, who did his PhD under no other than the great Persi Diaconis.}]
 Knowing on what to condition can be the difference between an unsolvable problem and a trivial one.
 When confronted with a statistical problem, always ask yourself ``What do I know for sure?'' and then ``How can I create a conditional structure to include this information?''.
 \end{idea}
\end{frame}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{frame}{Recommended reading}
\begin{itemize}
  \item[\faBook] \cite{Hoff2009} Ch. 2 and $^\ast$\cite{Schervish2012} Ch.1;
 \item $^\ast$Paper: \cite{Diaconis1980} explains why if $n$ samples are taken from an exchangeable population of size $N \gg n$ without replacement, then the sample $Y_1, \ldots Y_n$ can be modelled as approximately exchangeable;
 \item[\faForward] Next lecture: \cite{Robert2007} Ch. 3.
 \end{itemize}
\end{frame}


%\chapter{Differential Equations}
Many physical phenomena can be modeled using the
language of calculus. For example, observational evidence suggests
that the temperature of a cup of tea (or some other liquid) in a
room of constant temperature will cool over time at a rate
proportional to the difference between the room temperature  and the
temperature of the tea.

In symbols, if $t$ is the time, $M$ is the room temperature,
and $f(t)$ is the temperature of the tea at time $t$ then $f'(t) =
k(M-f(t))$ where $k>0$ is a constant which will depend on the kind of tea
(or more generally the kind of liquid) but not on the room temperature
or the temperature of the tea. This is \dfont{Newton's law of
  cooling} and the equation that we
just wrote down is an example of a \dfont{differential
  equation}.  Ideally we would like to
solve this equation, namely, find the function $f(t)$ that describes
the temperature over time, though this often turns out to be
impossible, in which case various approximation techniques must be
used.  The use and solution of differential equations is an important
field of mathematics; here we see how to solve some simple but useful
types of differential equation.

Informally, a differential equation is an equation in which one or
more of the derivatives of some function appears. Typically, a
scientific theory will produce a differential equation (or a system of
differential equations) that describes or governs some physical
process, but the theory will not produce the desired function or
functions directly.


\section{The Gradient}
\noindent
If you have a surface $f: \mathbb{R}^2 \to \mathbb{R}$, what direction $\langle \Delta x, \Delta y \rangle$ should I go to maximize the change if $f$?\\
We saw earlier that $\Delta z\approx \langle f_x, f_y \rangle \cdot \langle \Delta x, \Delta y \rangle$. To maximize a dot product, $\langle \Delta x, \Delta y \rangle$ should be in the same direction as $\langle f_x, f_y \rangle$. This directional vector is called the gradient: the direction of steepest ascent.\\
Notated mathematically,
\begin{equation*}
	\nabla f(x,y) = \langle f_x, f_y \rangle
\end{equation*}

[INSERT IMAGE]

\input{./differentialMultivariableCalculus/gradientProperties}
\input{./differentialMultivariableCalculus/linearApproximationsGradient}
\input{./differentialMultivariableCalculus/gradientCLevelCurves}


\section{Hamming Distance}
\subsection{Theory}
Hamming distance of two integers, each 32 bits, is the number of changes that are necessary to change one integer to another. In other words, if A and B are two 32 bits integer, the hamming distance between the two, denoted by $hamdist(A,B)$ is defined as follows:
\begin{equation}\label{hammingdist}
		hamdist(A,B) = \sum_{i=0}^{31}\left[A(i) \neq B(i)\right],
\end{equation}
where $A(i)$ represents the $i^{th}$ bit of A. Hamming distance is bounded between 0 (in the case that $\forall i, A(i)==B(i)$) and 32 (in the case that $\forall i, A(i)\neq B(i)$). Hamming distance has the following properties:
\begin{itemize}

\item{}
Hamming distance is a symmetric operator as the hamming distance of A and B is the same as hamming distance of B and A:
\begin{equation}\label{symmetry}
		hamdist(A, B) == hamdist(B,A)
\end{equation}

\item{}
The hamming distance of a 32 bit integer is bounded between 0 and 32. In general, the hamming distance of two n-bit numbers is bounded between 0 and n:
\begin{equation}\label{bounded}
	\forall A,B \in \left[0, 2^n-1 \right], \mbox{where}\ A, B \in \mathbb{N}, 0 \leq hamdist(A, B) \leq n
\end{equation}

\item{}
The hamming distance of any integer with it self is zero.

\begin{equation}\label{ZReflect}
		hamdist(A, A) == 0
\end{equation}
\end{itemize}

In the following section, we use the above-mentioned properties to compute the minimum hamming distance of an array of integers.

\subsection{Minimum Hamming Distance of an array of 32-bit integers}
The minimum hamming distance of an array is the minimum hamming distance of any two distinct integers of the array. The minimum hamming distance of array $A$ is defined as follows:
\begin{equation}\label{HammingDistArray}
	\begin{gathered}
         i, j, n \in \mathbb{N}\\
        \forall i \in \left[0, n\right]\\
        \forall j \in \left[0, n\right]\\
        d = min(hamdist(A(i), A(j)))
	\end{gathered}
\end{equation}

Here, we use the properties of hamming distance operator in order to further improve the algorithm.

\begin{equation}\label{HammingDistArrayOpt}
	\begin{gathered}
         i, j, n \in \mathbb{N}\\
        \forall i \in \left[0, n\right]\\
        \forall j \in \left[i+1, n\right]\\
        d = min(hamdist(A(i), A(j)))
	\end{gathered}
\end{equation}

The above algorithm reduces the number of iterations required for finding the minimum distance. We used \ref{symmetry} to avoid computing hamming distance of $hamdist(A(i), A(j))$ when $hamdist(A(j), A(i))$ has already been computed. We used \ref{ZReflect} to avoid computing hamming distance when $i==j$. These two improvements were achieved by starting $j$ from $i+1$. Since we are looking for minimum hamming distance, we used \ref{bounded} to exit the loop as soon as a minimum distance of 0 is computed.

\subsection{Source Code And Results}
With the algorithm defined in the previous section, we have attempted to implement it using C++. The source code for this project can be founded in this github repository: \href{https://github.com/hossein1387/random_sw_experiments/tree/master/hamming_distance}{GitHub Repository For Min Hamming Distance}.
\markdownInput{Hamming.md}


% Section 4: Algorithms
\section{Algorithms}

\subsection{ADMM method for dual problem}
For convenience, introducing relaxation variables, we reformulate the dual problem as:

\begin{equation}
  \begin{array}{rl}
    {\mathrm{(dual)}} & {\min -_{u,v} \sum_{i=1}^{m} \mu_{i} u_{i}-\sum_{j=1}^{n} \nu_{j} v_{j}} + I_{\mathbb{R}_+^{m\times n}}(\xi)\\
    {\text { subject to }} & {c_{ij} - u_i - v_j -\xi_{ij}= 0\qquad\forall i=1, \ldots, m \quad j = 1,\cdots,n}
    \end{array}
\end{equation}

Then we have the augmented Lagrangian:

\begin{equation}
  \begin{aligned}L(u, v, \xi, w)=&-\sum_{i=1}^{m} \mu_{i} u_{i}-\sum_{j=1}^{n} \nu_{j} v_{j} + I_{\mathbb{R}_+^{m\times n}}(\xi)\\&+\sum_{i=1}^{m} \sum_{j=1}^{n} w_{i j}\left(c_{i j}-u_{i}-v_{j}-\xi_{i j}\right)+\frac{\rho}{2} \sum_{i=1}^{m} \sum_{j=1}^{n}\left(c_{i j}-u_{i}-v_{j}-\xi_{i j}\right)^{2}\end{aligned}
\end{equation}

$\partial_{\xi_{ij}} L = 0$ gives:

\begin{equation}
  \xi_{ij} = (c_{ij} - u_i - v_j + \frac{w_{ij}}{\rho})_+
\end{equation}

$\partial_{u_i}L = 0$ gives:

\begin{equation}
  u_i = \frac{1}{n}\left(\frac{\mu_{i}+\sum_{j=1}^{n} w_{i j}}{\rho}+\sum_{j=1}^{n}\left(c_{i j}-v_{j}-\xi_{i j}\right)\right)
\end{equation}

$\partial_{v_j} L = 0$ gives:
\begin{equation}
  v_j = \frac{1}{n}\left(\frac{\nu_{j}+\sum_{i=1}^{m} w_{i j}}{\rho}+\sum_{i=1}^{m}\left(c_{i j}-u_{j}-\xi_{i j}\right)\right)
\end{equation}

\vspace{2ex}
    \begin{algorithm}[htbp]
        \SetAlgoNoLine
        \caption{ADMM method for dual problem}
        \KwIn{parameters $\mu$, $\nu$, $c$}
        \KwIn{step size $\alpha$, penalty $\rho$}
        Initialize variables $u, v = \boldsymbol{0}$\\
        Initialize variables $\xi, w = \boldsymbol{0}$\\
        \While{ stopping criterion not met }
        {
            Update $u$: $\boldsymbol{u} \leftarrow \operatorname{argmin}_{u} L(u, v, \xi, w)$\\
            Update $\pi^{\dagger}$: $\boldsymbol{\pi}^{\dagger} \leftarrow \operatorname{argmin}_{u} L(u, v, \xi, w)$\\
            Update $\xi$: $\boldsymbol{\xi} \leftarrow \operatorname{argmin}_{\xi} L(u, v, \xi, w)$\\
            Update $w$: $\boldsymbol{w} \leftarrow w + \rho\cdot \alpha (\pi - \pi^{\dagger})$\\
        }
    \end{algorithm}

\subsection{Entropic Regularization Methods}
The Kullback-Leibler divergence is defined as

\begin{equation}
  \mathbf{K L}(\mathbf{P} | \mathbf{Q}) \stackrel{\text { def. }}{=} \sum_{i, j} \mathbf{P}_{i, j} \log \left(\frac{\mathbf{P}_{i, j}}{\mathbf{Q}_{i, j}}\right)-\mathbf{P}_{i, j}+\mathbf{Q}_{i, j}
\end{equation}

with the convention $0 \log(0) = 0$ and $\mathbf{K L}(\mathbf{P} | \mathbf{Q}) = +\infty$ if there exists some $(i, j)$ such that $\mathbf{Q}_{i,j} = 0$ but $\mathbf{P}_{i,j} \neq 0$. The special case $\mathbf{K L}(\mathbf{P} | \mathbf{1})$ corresponds to minus the Shannon-Boltzmann entropy. The function $\mathbf{K L}(\cdot | \mathbf{Q})$ is strongly convex, because its hessian is $\partial^{2} \mathbf{K L}(\mathbf{P} | \mathbf{Q})=\operatorname{diag}\left(1 / \mathbf{P}_{i, j}\right)$ and $\mathbf{P}_{i,j} \leq 1$.

The idea of the entropic regularization of optimal transport is to use $\mathbf{KL}$ as a regularizing function to obtain approximate solutions to the original transport problem:

\begin{equation}
  \label{eq:entropy_regularization}
  \mathrm{L}_{\mathbf{C}}^{\varepsilon}(\mathbf{\mu}, \mathbf{\nu}) \stackrel{\text { def. }}{=} \min _{\mathbf{P} \in \mathbf{U}(\mathbf{\mu}, \mathbf{\nu})}\langle\mathbf{P}, \mathbf{C}\rangle+\varepsilon \mathbf{K L}(\mathbf{P} | \mathbf{\mu} \otimes \mathbf{\nu})
\end{equation}

Here we used as a reference measure for the relative entropy $\mathbf{\mu} \otimes \mathbf{\nu}=\left(\mathbf{\mu}_{i} \mathbf{\nu}_{j}\right)_{i, j}$. This choice of normalization, specially in this discrete setting, has no importance for the selection of the optimal $\mathbf{P}$ since it only affects the objective by a constant, indeed for $\mathbf{P} \in \mathbf{U}(\mathbf{\mu}, \mathbf{\nu})$, one has

\begin{equation}
  \mathbf{K L}(\mathbf{P} | \mathbf{\mu} \otimes \mathbf{\nu})=\mathbf{K} \mathbf{L}\left(\mathbf{P} | \mathbf{\mu}^{\prime} \otimes \mathbf{\nu}^{\prime}\right)+\mathbf{K} \mathbf{L}\left(\mathbf{\mu}^{\prime} \otimes \mathbf{\nu}^{\prime} | \mathbf{\mu} \otimes \mathbf{\nu}\right)
\end{equation}

At this time, the approximate optimal transport problem has the $\epsilon$-strongly convex objective function, so it has a unique solution. Theoretically, As $\epsilon$ approaches 0, the optimal solution of the approximate optimal transport problem $\mathbf{P}_{\epsilon}$ converges to the optimal solution of the Kantorovich optimal transport problem. At this time, we can use the Sinkhorn algorithm to solve this problem with entropy regularization.

\begin{figure}[htbp]
  \centering
  \includegraphics[width=0.9\linewidth]{img/regularized}
  \label{fig:regularized}
  \caption{Impact of $\epsilon$ on the optimization of a linear function on the simplex}
\end{figure}

\subsection{Sinkhorn Algorithm}
The following theorem [4] shows that the solution of \ref{eq:entropy_regularization} has a specific form, which can be parameterized
using $m + n$ variables. That parameterization is therefore essentially dual, in the sense that a coupling $\mathbf{P}$ in
$\mathbf{U}(a, b)$ has $nm$ variables but $n + m$ constraints.

\paragraph{Theorem}
  $\mathbf{P}$ is the unique solution to \ref{eq:entropy_regularization} if and only if there exists $(u, v) \in R$ such that

  \begin{equation}
    \label{eq:thm1}
    \forall(i, j) \in [m] \times [n], \quad \mathbf{P}_{i, j}=\mathbf{u}_{i} \mathbf{K}_{i, j} \mathbf{v}_{j}
  \end{equation}
  and $\mathbf{P} \in \mathcal{U}(\mathbf{\mu}, \mathbf{\nu})$.

This can be proved by introducing two dual variables $\mathbf{f} \in \mathbb{R}^{m}, \mathbf{g} \in \mathbb{R}^{n}$ for each marginal constraint, the Lagrangian of \ref{eq:entropy_regularization}
reads

\begin{equation}
  \mathcal{E}(\mathbf{P}, \mathbf{f}, \mathbf{g})=\langle\mathbf{P}, \mathbf{C}\rangle+\varepsilon \mathbf{K} \mathbf{L}(\mathbf{P} | \mathbf{\mu} \otimes \mathbf{\nu})+\left\langle\mathbf{f}, \mathbf{\mu}-\mathbf{P} \mathbf{1}_{m}\right\rangle+\left\langle\mathbf{g}, \mathbf{\nu}-\mathbf{P}^{\mathrm{T}} \mathbf{1}_{n}\right\rangle
\end{equation}

Considering first order conditions (where we ignore the positivity constraint, which can be made rigorous by
showing the associated multiplier vanishes), we have

\begin{equation}
  \label{eq:partial}
  \frac{\partial \mathcal{E}(\mathbf{P}, \mathbf{f}, \mathbf{g})}{\partial \mathbf{P}_{i, j}}=\mathbf{C}_{i, j}+\varepsilon \log \left(\frac{\mathbf{P}_{i, j}}{\mathbf{\mu}_{i} \mathbf{\nu}_{j}}\right)-\mathbf{f}_{i}-\mathbf{g}_{j}=0
\end{equation}

which results, for an optimal $\mathbf{P}$ coupling to the regularized problem, in the expression $\mathbf{P}_{i, j}=\mathbf{\mu}_{i} \mathbf{\nu}_{j} e^{\frac{\mathbf{f}_{i}+\mathbf{g}_{j}-\mathbf{C}_{i, j}}{\varepsilon}}$
which can be rewritten in the form provided in the proposition using non-negative vectors
\begin{equation}
  \mathbf{u} \stackrel{\text { def. }}{=}\left(\mathbf{\mu}_{i} e^{\mathbf{f}_{i} / \varepsilon}\right)_{i}, \qquad \text{and} \qquad \mathbf{v} \stackrel{\text { def. }}{=}\left(\mathbf{\nu}_{j} e^{\mathbf{g}_{j} / \varepsilon}\right)_{j}
\end{equation}

The factorization of the optimal solution exhibited in Equation \ref{eq:thm1} can be conveniently rewritten in
matrix form as $P = diag(u)K diag(v)$. $\mathbf{u}, \mathbf{v}$ must therefore satisfy the following non-linear equations which
correspond to the mass conservation constraints inherent to $\mathbf{U}(a, b)$,

\begin{equation}
\operatorname{diag}(\mathbf{u}) \mathbf{K} \operatorname{diag}(\mathbf{v}) \mathbf{1}_{n}=\mathbf{\mu}, \quad \text { and } \quad \operatorname{diag}(\mathbf{v}) \mathbf{K}^{\top} \operatorname{diag}(\mathbf{u}) \mathbf{1}_{m}=\mathbf{\nu}
\end{equation}

These two equations can be further simplified, since $\operatorname{diag}(v) \mathbf{1}_n$ is $v$, and the multiplication of $\operatorname{diag}(u)$ times $\mathbf{Kv}$ is

\begin{equation}
  \label{eq:2}
  \mathbf{u} \odot(\mathbf{K} \mathbf{v})=\mathbf{\mu} \quad \text { and } \quad \mathbf{v} \odot\left(\mathbf{K}^{\mathrm{T}} \mathbf{u}\right)=\mathbf{\nu}
\end{equation}

where $\odot$ corresponds to entry-wise multiplication of vectors. That problem is known in the numerical analysis
community as the matrix scaling problem. An intuitive way to try to solve these equations is to solve them iteratively, by modifying first $u$ so that it satisfies the left-hand side of
Equation \ref{eq:2} and then $\mathbf{v}$ to satisfy its right-hand side. These two updates define Sinkhorn's algorithm

\begin{equation}
  \label{eq:sinkhorn}
  \mathbf{u}^{(\ell+1)} \stackrel{\text { def. }}{=} \frac{\mathbf{\mu}}{\mathbf{K} \mathbf{v}^{(\ell)}} \quad \text { and } \quad \mathbf{v}^{(\ell+1)} \stackrel{\text { def. }}{=} \frac{\mathbf{\nu}}{\mathbf{K}^{\mathrm{T}} \mathbf{u}^{(\ell+1)}}
\end{equation}

\vspace{2ex}
    \begin{algorithm}[htbp]
        \SetAlgoNoLine
        \caption{Sinkhorn algorithm}
        \KwIn{parameters $\mu$, $\nu$, $c$}
        \KwIn{epsilon $\epsilon$}
        Initialize variables $u, v = \boldsymbol{1}$\\
        Initialize  $\mathbf{K} = \exp^{-c/\epsilon}$\\
        \While{ stopping criterion not met }
        {
          Update $u$: $\boldsymbol{u} \leftarrow \frac{\mathbf{\mu}}{\mathbf{K} \mathbf{v}}$\\
          Update $v$: $\boldsymbol{v} \leftarrow \frac{\mathbf{\nu}}{\mathbf{K}^T \mathbf{u}}$\\

        }
        Calculate $\mathbf{P} = (\operatorname{diag}{\mathbf{u}}) \mathbf{K} (\operatorname{diag}{\mathbf{v}})$\\
    \end{algorithm}

\subsection{Block Coordinate Ascent Method}
In practice, the Sinkhorn algorithm suffers from numerical
overflow when the regularization parameter $\epsilon$ is small compared to the entries of the cost
matrix $\mathbf{C}$. This concern can be alleviated to some extent by carrying out computations
in the log domain. The relevance of this approach is made more clear by considering
the dual problem associated to \ref{eq:entropy_regularization}, in which these log-domain computations arise
naturally.

From equation \ref{eq:partial} we have
\begin{equation}
  \mathbf{P}_{i, j}=e^{\mathbf{f}_{i} / \varepsilon} e^{-\mathbf{C}_{i, j} / \varepsilon} e^{\mathbf{g}_{j} / \varepsilon}
\end{equation}

Substituting the optimal $\mathbf{P}$ in the Lagrangian $E(P,f, g)$ of Equation \ref{eq:entropy_regularization} as a function of $\mathbf{f}$ and $\mathbf{g}$, we obtain that the Lagrangian dual function equals

\begin{equation}
  \label{eq:fg}
  \mathbf{f}, \mathbf{g} \mapsto\left\langle e^{\mathbf{f} / \varepsilon},(\mathbf{K} \odot \mathbf{C}) e^{\mathbf{g} / \varepsilon}\right\rangle-\varepsilon \mathbf{H}\left(\operatorname{diag}\left(e^{\mathbf{f} / \varepsilon}\right) \mathbf{K} \operatorname{diag}\left(e^{\mathbf{g} / \varepsilon}\right)\right)
\end{equation}

The neg-entropy of $\mathbf{P}$ scaled by $\epsilon$, namely $\varepsilon\left\langle\mathbf{P}, \log \mathbf{P}-\mathbf{1}_{n \times m}\right\rangle$, can be stated explicitly as a function as $\mathbf{f}$, $\mathbf{g}$, $\mathbf{C}$,

\begin{equation}
  \begin{aligned}
    &\left\langle\operatorname{diag}\left(e^{\mathbf{f} / \varepsilon}\right) \mathbf{K} \operatorname{diag}\left(e^{\mathbf{g} / \varepsilon}\right), \mathbf{f} \mathbf{1}_{m}^{\mathrm{T}}+\mathbf{1}_{n} \mathbf{g}^{\mathrm{T}}-\mathbf{C}-\varepsilon \mathbf{1}_{n \times m}\right\rangle\\
    &=-\left\langle e^{\mathbf{f} / \varepsilon},(\mathbf{K} \odot \mathbf{C}) e^{\mathbf{g} / \varepsilon}\right\rangle+\langle\mathbf{f}, \mathbf{\mu}\rangle+\langle\mathbf{g}, \mathbf{\nu}\rangle-\varepsilon\left\langle e^{\mathbf{f} / \varepsilon}, \mathbf{K} e^{\mathbf{g} / \varepsilon}\right\rangle
    \end{aligned}
\end{equation}

therefore, the first term in \label{eq:fg} cancels out with the first term in the entropy above, then we have

\begin{equation}
  \label{eq:problem4.4}
  \mathrm{L}_{\mathrm{C}}^{\varepsilon}(\mathbf{\mu}, \mathbf{\nu})=\max _{\mathbf{f} \in \mathbb{R}^{n} \mathbf{g} \in \mathbb{R}^{m}}\langle\mathbf{f}, \mathbf{\mu}\rangle+\langle\mathbf{g}, \mathbf{\nu}\rangle-\varepsilon\left\langle e^{\mathbf{f} / \varepsilon}, \mathbf{K} e^{\mathbf{g} / \varepsilon}\right\rangle
\end{equation}

The optimal ($\mathbf{f}$, $\mathbf{g}$) are linked to scalings ($\mathbf{u}$, $\mathbf{v}$) through

\begin{equation}
  (\mathbf{u}, \mathbf{v})=\left(e^{\mathbf{f} / \varepsilon}, e^{\mathbf{g} / \varepsilon}\right)
\end{equation}

A simple approach to solving the unconstrained maximization problem \ref{eq:problem4.4} is to use an exact
\textbf{block coordinate ascent} strategy, namely to update alternatively $\mathbf{f}$ and $\mathbf{g}$ to cancel the
respective gradients in these variables of the objective of \ref{eq:problem4.4}. Indeed, one can notice
after a few elementary computations that, writing Q(f, g) for the objective of \ref{eq:problem4.4}

\begin{equation}
  \begin{array}{l}
    {\left.\nabla\right|_{\mathbf{f}} Q(\mathbf{f}, \mathbf{g})=\mathbf{\mu}-e^{\mathbf{f} / \varepsilon} \odot\left(\mathbf{K} e^{\mathbf{g} / \varepsilon}\right)} \\
    {\left.\nabla\right|_{\mathbf{g}} Q(\mathbf{f}, \mathbf{g})=\mathbf{\nu}-e^{\mathbf{g} / \varepsilon} \odot\left(\mathbf{K}^{\mathrm{T}} e^{\mathbf{f} / \varepsilon}\right)}
    \end{array}
\end{equation}

Block coordinate ascent can therefore be implemented in a closed form by applying
successively the following updates, starting from any arbitrary $\mathbf{g}^{(0)}$, for $l \geq 0$:

\begin{equation}
  \begin{array}{l}
    {\mathbf{f}^{(\ell+1)}=\varepsilon \log \mathbf{\mu}-\varepsilon \log \left(\mathbf{K} e^{\mathbf{g}^{(\ell)} / \varepsilon}\right)} \\
    {\mathbf{g}^{(\ell+1)}=\varepsilon \log \mathbf{\nu}-\varepsilon \log \left(\mathbf{K}^{\mathrm{T}} e^{\mathbf{f}^{(\ell+1)} / \varepsilon}\right)}
    \end{array}
\end{equation}

Such iterations are mathematically equivalent to the Sinkhorn iterations \ref{eq:sinkhorn}. Indeed, we recover that at
any iteration

\begin{equation}
  \left(\mathbf{f}^{(\ell)}, \mathbf{g}^{(\ell)}\right)=\varepsilon\left(\log \left(\mathbf{u}^{(\ell)}\right), \log \left(\mathbf{v}^{(\ell)}\right)\right)
\end{equation}

Given a vector $\mathbf{z}$ of real numbers we write $min_{\epsilon} \mathbf{z}$ for the soft-minimum of its coordinates, namely

\begin{equation}
  \min _{\varepsilon} \mathbf{z}=-\varepsilon \log \sum_{i} e^{-\mathbf{z}_{i} / \varepsilon}
\end{equation}

\begin{figure}[htbp]
  \centering
  \includegraphics[width=0.9\linewidth]{img/min_eps}
  \label{fig:ot}
  \caption{Soft-minimum}
\end{figure}

Using this notation,

\begin{equation}
  \begin{array}{l}
    {\left(\mathbf{f}^{(\ell+1)}\right)_{i}=\min _{\varepsilon}\left(\mathbf{C}_{i j}-\mathbf{g}_{j}^{(\ell)}\right)_{j}+\varepsilon \log \mathbf{\mu}_{i}} \\
    {\left(\mathbf{g}^{(\ell+1)}\right)_{j}=\min _{\varepsilon}\left(\mathbf{C}_{i j}-\mathbf{f}_{i}^{(\ell)}\right)_{i}+\varepsilon \log \mathbf{\nu}_{j}}
    \end{array}
\end{equation}

To simplify notations, we introduce an operator that
takes a matrix as input and outputs now a column vector of the soft-minimum values
of its columns or rows. Namely, for any matrix $\mathbf{A} \in \mathbb{R}^{m \times n}$, we define

\begin{equation}
  \begin{array}{l}
    {\operatorname{Min}_{\varepsilon}^{\mathrm{row}}(\mathbf{A}) \stackrel{\text { def. }}{=}\left(\min _{\varepsilon}\left(\mathbf{\mu}_{i, j}\right)_{j}\right)_{i} \in \mathbb{R}^{m}} \\
    {\operatorname{Min}_{\varepsilon}^{\mathrm{col}}(\mathbf{A}) \stackrel{\mathrm{def}}{=}\left(\min _{\varepsilon}\left(\mathbf{\nu}_{i, j}\right)_{i}\right)_{j} \in \mathbb{R}^{n}}
    \end{array}
\end{equation}

Using this notation, Sinkhorn's iterates read

\begin{equation}
  \begin{array}{l}
    {\mathbf{f}^{(\ell+1)}=\operatorname{Min}_{\varepsilon}^{\mathrm{row}}\left(\mathbf{C}-\mathbf{1}_{m} \mathbf{g}^{(\ell)^{\mathrm{T}}}\right)+\varepsilon \log \mathbf{\mu}} \\
    {\mathbf{g}^{(\ell+1)}=\operatorname{Min}_{\varepsilon}^{\mathrm{col}}\left(\mathbf{C}-\mathbf{f}^{(\ell)} \mathbf{1}_{n}^{\mathrm{T}}\right)+\varepsilon \log \mathbf{\nu}}
    \end{array}
\end{equation}

While mathematically equivalent to the Sinkhorn
updates \ref{eq:sinkhorn}, iterations above suggest using the log-sum-exp stabilization
trick to avoid underflow for small values of $\epsilon$. Writing $\underline{z}=\min \mathbf{z}$, that trick suggests
evaluating $\min_{\varepsilon} z$ as

\begin{equation}
  \operatorname{min}_{\varepsilon} \mathbf{z}=\underline{z}-\varepsilon \log \sum e^{-\left(\mathbf{z}_{i}-\underline{Z}\right) / \varepsilon}
\end{equation}

Instead of substracting $\mathbf{z}$ to stabilize the log-domain iterations as above, one can actually substract the previously computed scalings. This leads to the stabilized iteration

\begin{equation}
  \begin{array}{l}
    {\mathbf{f}^{(\ell+1)}=\operatorname{Min}_{\varepsilon}^{\mathrm{row}}\left(\mathbf{S}\left(\mathbf{f}^{(\ell)}, \mathbf{g}^{(\ell)}\right)\right)-\mathbf{f}^{(\ell)}+\varepsilon \log (\mathbf{\mu})} \\
    {\mathbf{g}^{(\ell+1)}=\operatorname{Min}_{\varepsilon}^{\mathrm{col}}\left(\mathbf{S}\left(\mathbf{f}^{(\ell+1)}, \mathbf{g}^{(\ell)}\right)\right)-\mathbf{g}^{(\ell)}+\varepsilon \log (\mathbf{\nu})}
    \end{array}
\end{equation}

where we defined

\begin{equation}
  \mathbf{S}(\mathbf{f}, \mathbf{g})=\left(\mathbf{C}_{i, j}-\mathbf{f}_{i}-\mathbf{g}_{j}\right)_{i, j}
\end{equation}

In contrast to the original iterations \ref{eq:sinkhorn}, these log-domain iterations
are stable for arbitrary $\epsilon$, because the quantity $\mathbf{S}(\mathbf{f}, \mathbf{g})$ stays bounded during the
iterations. The downside is that it requires nm computations of exp at each step. Computing a $\mathrm{Min}_{\varepsilon}^{\mathrm{row}}$ is typically substantially slower than matrix multiplications
and requires computing line by line soft-minima of matrices $\mathbf{S}$. There is therefore no
efficient way to parallelize the application of Sinkhorn maps for several marginals simultaneously. In Euclidean domains of small dimension, it is possible to develop efficient
multiscale solvers with a decaying $\epsilon$ strategy to significantly speed up the computation
using sparse grids.

\vspace{2ex}
    \begin{algorithm}[htbp]
        \SetAlgoNoLine
        \caption{Block Coordinate Ascent algorithm for regularized problem}
        \KwIn{parameters $\mu$, $\nu$, $c$}
        \KwIn{epsilon $\epsilon$}
        Initialize variables $\mathbf{f}, \mathbf{g} = \boldsymbol{1}$\\
        Initialize  $\mathbf{K} = \exp^{-c/\epsilon}$\\
        \While{ stopping criterion not met }
        {
          Update $\mathbf{S}$: $\mathbf{S}(\mathbf{f}, \mathbf{g})=\left(\mathbf{C}_{i, j}-\mathbf{f}_{i}-\mathbf{g}_{j}\right)_{i, j}$\\
          Update $\mathbf{f}$: ${\mathbf{f}^{(\ell+1)}=\operatorname{Min}_{\varepsilon}^{\mathrm{row}}\left(\mathbf{S}\left(\mathbf{f}^{(\ell)}, \mathbf{g}^{(\ell)}\right)\right)-\mathbf{f}^{(\ell)}+\varepsilon \log (\mathbf{\mu})}$\\
          Update $\mathbf{S}$: $\mathbf{S}(\mathbf{f}, \mathbf{g})=\left(\mathbf{C}_{i, j}-\mathbf{f}_{i}-\mathbf{g}_{j}\right)_{i, j}$\\
          Update $\mathbf{g}$: ${\mathbf{g}^{(\ell+1)}=\operatorname{Min}_{\varepsilon}^{\mathrm{col}}\left(\mathbf{S}\left(\mathbf{f}^{(\ell+1)}, \mathbf{g}^{(\ell)}\right)\right)-\mathbf{g}^{(\ell)}+\varepsilon \log (\mathbf{\nu})}$\\
        }
        Calculate $\mathbf{u} = \exp(\mathbf{f}/\epsilon)$\\
        Calculate $\mathbf{v} = \exp(\mathbf{g}/\epsilon)$\\
        Calculate $\mathbf{P} = (\operatorname{diag}{\mathbf{u}}) \mathbf{K} (\operatorname{diag}{\mathbf{v}})$\\
    \end{algorithm}


\subsection{Row Reduction}
\noindent
Row reduction is a way of solving a system of linear equations by representing the system as a matrix and altering the rows of the matrix until we get as close as possible to an identity matrix.\\

\noindent
Below is a list of legal row operations. Doing these does not change the solution to the system of equations.
\begin{enumerate}[label=]
	\item Multiplying or dividing each item in a row by a scalar.
		\begin{equation*}
			\begin{bmatrix}
				1 & 3 & 7 \\
				0 & 2 & -1 \\
				2 & 7 & 9
			\end{bmatrix}
			\stackrel{R_2 = R_2/2}{\to}
			\begin{bmatrix}
				1 & 3 & 7 \\
				0 & 1 & -1/2 \\
				2 & 7 & 9
			\end{bmatrix}
		\end{equation*}
	\item Adding a multiple of one row to another row.
		\begin{equation*}
			\begin{bmatrix}
				1 & 3 & 7 \\
				0 & 2 & -1 \\
				2 & 7 & 9
			\end{bmatrix}
			\stackrel{R_3 = R_3 - 2R_1}{\to}
			\begin{bmatrix}
				1 & 3 & 7 \\
				0 & 2 & -1 \\
				0 & 1 & -5
			\end{bmatrix}
		\end{equation*}
	\item Swapping two rows.
		\begin{equation*}
			\begin{bmatrix}
				1 & 3 & 7 \\
				0 & 2 & -1 \\
				0 & 1 & -5
			\end{bmatrix}
			\stackrel{\text{swap } R_2 \text{, } R_3}{\to}
			\begin{bmatrix}
				1 & 3 & 7 \\
				0 & 1 & -5 \\
				0 & 2 & -1
			\end{bmatrix}
		\end{equation*}
\end{enumerate}

\noindent
Using these rules, we solve a system of linear equations using a process called Gauss-Jordan Elimination.\\

\noindent
A system may have a contradiction, meaning no solution exists. This will look like a row of 0's on the left and a non-zero term on the far right of the row.
\begin{equation*}
	\left[
		\begin{array}{cc|c}
		1 & 0 & 1 \\
		0 & 1 & 0
		\end{array}
	\right]
	\implies
	\text{No solution}
\end{equation*}

\noindent
A system may be underdetermined, meaning one or more variables can be any number. This will look a non-zero column on the left without a leading 1 (bolded).
\begin{equation*}
	\left[
		\begin{array}{ccccc|c}
			1 & \textbf{-2} & 0 & 0 & \textbf{-3} & 2 \\
			0 & \textbf{0} & 1 & 0 & \textbf{1} & 5 \\
			0 & \textbf{0} & 0 & 1 & \textbf{2} & 4 \\
			0 & \textbf{0} & 0 & 0 & \textbf{0} & 0
		\end{array}
	\right]
	\implies
	\begin{bmatrix}
		x_1 \\
		x_2 \\
		x_3 \\
		x_4 \\
		x_5 \\
	\end{bmatrix} = \begin{bmatrix}
		2 \\
		0 \\
		5 \\
		4 \\
		0
	\end{bmatrix} + \alpha \begin{bmatrix}
		2 \\
		1 \\
		0 \\
		0 \\
		0
	\end{bmatrix} + \beta \begin{bmatrix}
		3 \\
		0 \\
		-4 \\
		-2 \\
		1
	\end{bmatrix} \text{, }\alpha\text{, }\beta \in \R
\end{equation*}

\ifodd\includeBackgroundReviewExamples\input{./backgroundReview/matrices/rowReduction_example.tex}\fi


%---------------------------Taper-----------------------------
\section{Taper}

Taper is the maximum ratio of cross derivative magnitude to principal axis magnitude:
\[
q = \frac {\normvec{X_{12}}} {\min \left\{ \normvec{X_1}, \normvec{X_2} \right\}}
\]

Note that if $\normvec{X_1}$ or $\normvec{X_2} < DBL\_MIN$, we set $q = DBL\_MAX$.

\quadmetrictable{taper}%
{$1$}%                                      Dimension
{$[0,0.7]$}%                                Acceptable range
{$[0,DBL\_MAX]$}%                           Normal range
{$[0,DBL\_MAX]$}%                           Full range
{$0$}%                                      Unit square
{Adapted from \cite{rob:87}}%               Citation
{v\_quad\_taper}%                           Verdict function name


\
% This seems to work.
\paragraph{Better Solution: }
Let the key be ${\bf k}= k_0k_1\dots k_{127}$.
Note since $F$ has only $10$ inputs, it is possible to calculate a full truth
table for $F$. Also note that there is a fixed linear transformation $L_m$ taking
the vector ${\bf s_0}$ to the $m$-th input vector of $F$, ${\bf y_m}$. Our goal is to determine
$128$ linear equations in $k_0,k_1,\dots,k_{127}$ and then Gauss reduce. For each
bit of keystream, we determine $10$ such equations, so we expect to use $13$ bits
of keystream (more if some of these equations turn out to be degenerate).
Switching a bit in the IV will switch a bit in some easily calculable
subset of the entries in the input vector of $F$, since the input vector is a
linear map of ${\bf s_0}$. Also, for a fixed IV and value $\alpha$
of the $m$-th keystream bit, we know that the input vector of $F$ for this bit
lies in $F^{-1}(\alpha)$, and, if the IV is ${\bf v}$, then $L_m{\bf k}$ lies in
the set $F^{-1}(\alpha_v)-L_m{\bf v}$ (since ${\bf s_0} ={\bf k} \oplus {\bf v}$).
By intersecting these sets over several IVs, we can determine a unique value of
$L_m{\bf k}$, which gives $10$ linear equations in the $k_i$. Repeating for different
values of $m$ will give a complete set of linear equations, which can then be solved
for ${\bf k}$. In general, computing $L_m$ will take about $128^3$ steps (and this
must be done about $128/10$ times), trying each
initialization vector will take about $128^2$ steps, and intersecting the sets of
possible values for $L_m{\bf k}$ will take about $2^{10}$ steps. Solving a set of
$128$ linear equations will take about $128^3$ steps. The dominating factor is
$128^4/10 \approx 25\,000\,000 \ll 2^{128}$.
(More generally, computing a $2^N$ bit key with an $M$-tap filter
function will take about $\mathcal{O}(2^{4N}/M+2^{3N}+M(2^M+2^{2N}))$, which
is exponentially better than the brute force $\mathcal{O}(2^{2^N})$.

\paragraph{Our first stab at a solution. Simpler and slower:}
Start by setting the IV to $00\dots 0$. Then the initial state $s_0s_1\dots s_{127}$
is just the key. Now, note that there are
\[ \sum_{i=0}^{10} {\binom{128}{i}} <2^{34}\] monomials in $s_0,s_1, \dots, s_{127}$
which are linear in each variable and of total degree at most $10$. Running
the filter generator for $2^{34}$ iterations will yield $2^{34}$ linear equations
in these monomials. Gauss reduction on these equations will take approximately
$(2^{34})^3 = 2^{102}$ steps. This will solve for $s_0,s_1,\dots, s_{127}$, which
gives the key. This is an improvement by a factor of $2^{26}$ on the brute force.


\subsection{Distortion (PSNR) of Data}
%distortion of data

Peask Signal-to-Noise Ratio (PSNR) is a common metric used in graphics domain to evaluate the overall statistical distortion between the original data and the reconstructed/decompressed data. It is defined as follows.
\begin{equation}
PSNR = 20\cdot \log_{10}{(value\_range)} - 10\cdot \log_{10}{(MSE)}.
\end{equation}
where value\_range and MSE refer to data value range and the mean squared compression error respectively.

The compression factor in the rate-distortion is evaluated by \emph{bit rate}, i.e., the number of bits used to represent a data point on average after the compression. Bit rate is equal to the number of full bits used to represent each original data point divided by the overall compression factor, for example, $bit rate = \frac{64}{compression factor}$ for double-precision data.

%plot psnr