\documentclass{article}
\usepackage{amsmath,amsthm,amssymb,fullpage,enumerate,bm,hyperref}
\theoremstyle{definition}
\newtheorem{defi}{Definition}
\newtheorem{ex}{Exercise}
\title{Lecture 1\\Why didn't I learn about differential forms?}
\author{TM}
\date{\today}
\begin{document}
\section*{Introduction}
Friends, friends. I have a confession to make. I never actually taught myself any differential geometry. I'm a faker. My whole professional life is a lie. I should just stick to dumb as rocks programming and write {\tt /r/programmerhumor} memes.

But, I've never been one to stick to the sane option. So I'll do the insane thing -- teach myself differential geometry by way of giving lectures.
\section*{Motivation}
The thing is though. I have a reason to learn it. In order to actually give a full definition of modular forms in the geometrically most appropriate way, you really need to work with differential forms.

So what do I mean by the ``geometrically most appropriate way''? Well, I mean the way Nick Katz does it in his ground-breaking (or so I've been told) essay ``$p$-adic Properties of Modular Forms'' from 1972.

In order to begin to understand modular forms in his way, you need to start by viewing elliptic curves as ``tori''. Or to be more concrete, as quotients
\[\mathbb{C}/(\text{lattice in $\mathbb{C}$}).\]
What I mean by lattice in $\mathbb{C}$ here is an additive group of the form
\[\mathbb{Z}\omega_1+\mathbb{Z}\omega_2,\]
where $\omega_1$ and $\omega_2$ are points in the complex plane, not on the same line.

Now, an arbitrary point in the complex plane can be shifted in terms of integer multiples of $\omega_1$ and $\omega_2$ so that it sits inside the parallellogram spanned by $\omega_1$ and $\omega_2$. Take a look at the graphic below.
\begin{figure}[h]
  \centering
  {\tt Insert TikZ graphic here.}
\end{figure}

What this means is that $\mathbb{C}/\text{lattice}$ is topologically the same as a parallellogram with sides identified in an orientation-preserving way.

\begin{figure}[h]
  \centering
  {\tt Insert TikZ graphic here.}
\end{figure}

From topology we know this is homeomorphic to a torus. Hence, certainly $\mathbb{C}/\text{lattice}$ must be a $2$-dimensional manifold.

Is it though? (Answer: yes, of course.)
\section*{What's Spivak say?}
Spivak starts by defining a {\tt diffeomorphism}.
\begin{defi}
  Let $U,V\subseteq\mathbb{R}^n$ are open (here and henceforth in the Euclidean topology). Then a differentiable function $h:U\to V$ (here and henceforth, a $C^\infty$ function) with a differentiable inverse $h^{-1}:V\to U$ is called a {\tt diffeomorphism}.
\end{defi}
From this ey (Spivak pronoun) defines a $k$-dimensional manifold.
\begin{defi}
  Let $M\subset\mathbb{R}^n$ and $k$ a non-negative integer. Then $M$ is called a $k$-dimensional manifold if for every point $x\in M$ it holds that
  \begin{quotation}
    There exists an open set $\mathbb{R}^n\supseteq U\ni x$ and an open set $V\subseteq\mathbb{R}^n$ and a diffeomorphism $h:U\to V$ satisfying
    \[h(U\cap M)=V\cap(\mathbb{R}^k\times\{\mathbf{0}\}).\]
  \end{quotation}
\end{defi}
Spivak tells us to think of this $U\cap M$ being up to diffeomorphism the same as $\mathbb{R}^k\times\{\mathbf{0}\}$.

For funsies, let's show that $\mathbb{T}^2$ indeed is a $2$-manifold.
\begin{ex}
  Show that $\mathbb{T}^2$ is a $2$-manifold.
\end{ex}
\begin{proof}[Solution]
  First we need to settle on which definition of $\mathbb{T}^2$ we want to use. Since we want it to sit in $\mathbb{R}^n$ for some $n$, we should probably use the good ole ``donut''-definition, which makes it sit in $\mathbb{R}^3$.

  We define it parametrically:
  \[\begin{cases}
    x(\theta,\phi)=(R+r\cos\theta)\cos\phi\\
    y(\theta,\phi)=(R+r\cos\theta)\sin\phi\\
    z(\theta,\phi)=r\sin\theta.
  \end{cases}\]
  Where $0\leq\theta,\phi<2\pi$ and $R$ is ``the distance from the center of the tube to the center of the torus'' and $r$ is ``the radius of the tube''. Obviously the particular choice of $R$ and $r$ is irrelevant.

  In other words
  \[\mathbb{T}^2=\{(x(\theta,\phi),y(\theta,\phi),z(\theta,\phi)):(\theta,\phi)\in [0,2\pi)^2\}.\]

  \begin{figure}[h]
    \centering
    {\tt TikZ me!}
  \end{figure}

  Let now $(x,y,z)\in\mathbb{T}^2$ be arbitrary.
\end{proof}
\end{document}


\chapter{Techniques III: Tabling}\label{tablingchapter}

This chapter introduces \emph{tabling}, an extension of memoization to
logic programming.  We present a full implementation of tabling for
miniKanren in Chapter~\ref{tablingimplchapter}.

This chapter is organized as follows.  In section~\ref{tablingmemo} we
review memoization as used in functional programming.
Section~\ref{tablingintro} introduces tabling, explains how tabling
differs from memoization, and describes a few of the many applications
of tabling.  In section~\ref{tablingform} we present the
\scheme|tabled| form, used to create tabled relations.  In
section~\ref{tablingexamples} we examine several examples of tabled
relations, and in section~\ref{tablinglimitations} we discuss the
limitations of tabling.

\section{Memoization}\label{tablingmemo}

Consider the naive Scheme implementation of the Fibonacci function.

\schemedisplayspace
\begin{schemedisplay}
(define fib
  (lambda (n)
    (cond
      ((= 0 n) 0)
      ((= 1 n) 1)
      (else (+ (fib (- n 1)) (fib (- n 2)))))))
\end{schemedisplay}

\noindent
The call \mbox{\scheme|(fib 5)|} results in calls to
\mbox{\scheme|(fib 4)|} and \mbox{\scheme|(fib 3)|}; the resulting
call to \mbox{\scheme|(fib 4)|} also calls \mbox{\scheme|(fib 3)|}.
The call \mbox{\scheme|(fib 5)|} therefore results in two calls to
\mbox{\scheme|(fib 3)|}, the second of which performs duplicate work.
Similarly, \mbox{\scheme|(fib 5)|} results in three calls to
\mbox{\scheme|(fib 2)|}, five calls to \mbox{\scheme|(fib 1)|}, and
three calls to \mbox{\scheme|(fib 0)|}.  Due to these redundant calls,
the time complexity of \scheme|fib| is exponential in $n$.

To avoid this duplicate work, we could record each distinct call to
\scheme|fib| in a table, along with the answer returned by that call.
Whenever a duplicate call to \scheme|fib| is made, \scheme|fib| would
return the answer stored in the table instead of recomputing the
result.  This optimization technique, known as \emph{memoization}
\cite{Michie68}, can result in a lower complexity class for the
running time of the memoized function.  Indeed, the memoized version
of \scheme|fib| runs in linear rather than exponential time.

Memoization is a common technique in functional programming, since it
often improves performance of recursive functions.  In this chapter we
consider the related technique of \scheme|tabling|, which generalizes
memoization to logic programming.

\section{Tabling}\label{tablingintro}

Tabling is a generalization of memoization; tabling allows a relation
to store and reuse its previously computed results.  Tabling a
relation is more complicated than memoizing a function, since a
relation returns a potentially infinite stream of substitutions rather
than a single value.  Also, the arguments to a tabled relation can
contain unassociated logic variables or partially instantiated terms,
which complicates determining whether a call is a variant of a
previously seen call.

Tabling, like memoization, can result in dramatic performance gains
for some programs.  For example, combining tabling with Prolog's Definite
Clause Grammars~\cite{dcg86} makes it trivial to write efficient
recursive descent parsers that handle left-recursion\footnote{One
  important use of tabling by Prolog systems is to handle
  left-recursive definitions of goals; due to Prolog's incomplete
  depth-first search, calls to left-recursive goals often diverge.
  Since miniKanren uses a complete search strategy, handling
  left-recursion is not a problem.  However, we will see in
  section~\ref{tablingexamples} that there are other programs we want
  to write that terminate under tabling but diverge
  otherwise.}~\cite{DBLP:conf/padl/BecketS08}---these parsers are
equivalent to ``packrat'' parsing~\cite{packrat02}.  Tabling is also
useful for writing programs that must calculate fixed points, such as
abstract interpreters and model checkers~\cite{memoingforlp,dra09}.
However, the real reason we are interested in tabling is that many
relations that would otherwise diverge terminate under tabling, as we
will see in section~\ref{tablingexamples}.

An excellent introduction to tabling and its uses is Warren's survey~\cite{memoingforlp}.

\section{The {\bf tabled} Form}\label{tablingform}

Tabled relations are constructed using the \scheme|tabled| form:

\wspace

\mbox{\scheme|(tabled (x ...) g g* ...)|}

\wspace

\noindent For example,

\wspace

\mbox{\scheme|(define fo (tabled (z) (== z 5)))|}

\wspace

\noindent defines a top-level tabled goal constructor named
\scheme|fo|.  Each tabled goal constructor has its own local table,
which can be garbage collected once there are no live references to
the goal constructor.  Keep in mind that the table is associated with
the goal constructor, not the goal returned by the goal constructor.

Calls to a tabled relation come in two flavors: master calls and slave
calls.  A \emph{master call} is a call to a tabled relation whose
arguments are not (yet) stored in the table.  A \emph{slave call} is a
call whose arguments are found in the table; each slave call is a
\emph{variant} of some master call.

Two calls to the same tabled relation are variants of each other if
their arguments are the same, up to consistent renaming of
unassociated logic variables\footnote{In other words, the two lists of arguments
  to the relation, when reified with respect to their ``current'' substitutions,
  must be \scheme|equal?|.}. For example, consider the calls
\mbox{\scheme|(mulo y z 5)|} and \mbox{\scheme|(mulo w w x)|} in the
substitutions \mbox{\scheme|`((y . z))|} and \mbox{\scheme|`((x . 5))|},
respectively.  Taking the substitutions into account, these calls are equivalent to
\mbox{\scheme|(mulo z z 5)|} and \mbox{\scheme|(mulo w w 5)|}, which are variants of
each other.  However, the calls \mbox{\scheme|(mulo w w x)|} and \mbox{\scheme|(mulo y z z)|}
are variants only if \scheme|w| is associated with \scheme|x|, and \scheme|y| is associated with \scheme|z|,
respectively.  For the same reason,
\mbox{\scheme|(mulo w 5 6)|} and \mbox{\scheme|(mulo y z 6)|} are variants only if
\scheme|z| is associated with 5 in the substitution in place for the second call.

\section{Tabling Examples}\label{tablingexamples}

We are now ready to examine examples of tabled relations.  The
canonical example relation, \scheme|patho|\footnote{The path examples
  in this section are taken from~\citet{memoingforlp}.}, finds all
paths between two nodes in a directed graph.  The goal
\mbox{\scheme|(patho x y)|} succeeds if there is a directed edge from
\scheme|x| to \scheme|y|, or if there is an edge from \scheme|x| to
some node \scheme|z| and there is a path from \scheme|z| to
\scheme|y|.

\schemedisplayspace
\begin{schemedisplay}
(define patho
  (lambda (x y)
    (conde
      ((arco x y))
      ((exist (z)
         (arco x z)
         (patho z y))))))
\end{schemedisplay}

\noindent The goal \mbox{\scheme|(arco x y)|} succeeds if there is a
directed edge from node \scheme|x| to node \scheme|y|.

\schemedisplayspace
\begin{schemedisplay}
(define arco
  (lambda (x y)
    (conde
      ((== 'a x) (== 'b y))
      ((== 'c x) (== 'b y))
      ((== 'b x) (== 'd y)))))
\end{schemedisplay}

\noindent This definition of \scheme|arco| represents edges from
\scheme|'a| to \scheme|'b|, \scheme|'c| to \scheme|'b|, and
\scheme|'b| to \scheme|'d|.

\noindent The expression \mbox{\scheme|(run* (q) (patho 'a q))|}
returns \mbox{\scheme|'(b d)|}, indicating that only the nodes
\scheme|'b| and \scheme|'d| are reachable from \scheme|'a|.

Now let us redefine \scheme|arco| to represent a different set of
directed edges, this time with a circularity between nodes \scheme|'a|
and \scheme|'b|.

\newpage

\schemedisplayspace \begin{schemedisplay}
(define arco
  (lambda (x y)
    (conde
      ((== 'a x) (== 'b y))
      ((== 'b x) (== 'a y))
      ((== 'b x) (== 'd y)))))
\end{schemedisplay}

\noindent Using the new definition of \scheme|arco|, the expression
\mbox{\scheme|(run* (q) (patho 'a q))|} now diverges.  We can
understand the cause of this divergence if we replace \scheme|run*|
with \scheme|run10|.

\wspace

\noindent\scheme|(run10 (q) (patho 'a q))|  $\Rightarrow$ \scheme|'(b a d b a d b a d b)|

\wspace

\noindent Because of the circular path between \scheme|'a| and
\scheme|'b|, \mbox{\scheme|(patho 'a q)|} keeps finding longer and
longer paths between \scheme|'a| and the nodes \scheme|'b|, \scheme|'a|,
and \scheme|'d|.  To avoid this problem, we can table
\scheme|patho|.

\schemedisplayspace
\begin{schemedisplay}
(define patho
  (tabled (x y)
    (conde
      ((arco x y))
      ((exist (z)
         (arco x z)
         (patho z y))))))
\end{schemedisplay}

\noindent \mbox{\scheme|(run* (q) (patho 'a q))|} then converges,
returning \mbox{\scheme|'(b a d)|}.

Now let us consider a mutually recursive program.

\schemedisplayspace
\begin{schemedisplay}
(letrec ((fo (lambda (x)
               (conde
                 ((== 0 x))
                 ((go x)))))
         (go (lambda (x)
               (conde
                 ((== 1 x))
                 ((fo x))))))
  (run* (q) (fo q)))
\end{schemedisplay}

\noindent This expression diverges.  If we replace
\scheme|run*| with \scheme|run10| the program converges with the value
\mbox{\scheme|'(0 1 0 1 0 1 0 1 0 1)|}.  If we table either
\scheme|fo|, \scheme|go|, or both, \mbox{\scheme|(run* (q) (fo q))|}
converges with the value \mbox{\scheme|'(0 1)|}.

\section{Limitations of Tabling}\label{tablinglimitations}

Tabling is a remarkably useful addition to miniKanren, and can be
used to improve efficiency of relations and
(sometimes) avoid divergence.  Unfortunately, tabling is not a
panacea.  In fact, tabling can be trivially defeated by changing one
or more arguments in each call to a tabled relation.  For example,
consider the ternary multiplication relation \scheme|mulo| from
Chapter~\ref{arithchapter}.  The arguments in the call

\wspace

\noindent
\mbox{\scheme|(mulo `(1 1 . ,x) x `(0 0 0 1 . ,x))|}\footnote{This example is due to Oleg
  Kiselyov (personal communication).}

\wspace

\noindent
all share the variable \scheme|x|.
The resulting goal succeeds only if there exists a non-negative
integer $x$ that satisfies $(3 + 4x) \cdot x = 8 + 16x$.  \scheme|mulo|
enumerates all non-negative integer values for \scheme|x| until it
finds one that satisfies this equation.  However, if no such
\scheme|x| exists the call to \scheme|mulo| will diverge.  Tabling
will not help, since the value of \scheme|x| keeps changing.

Another disadvantage of tabling is that it can greatly increase the
memory consumption of a program.  This is a problem with memoization
in general.  For example, consider the tail-recursive
accumulator-passing-style Scheme definition of factorial\footnote{The
  call \mbox{\scheme|(!-aps n 1)|} calculates the factorial of
  \scheme|n|.}.

\schemedisplayspace
\begin{schemedisplay}
(define !-aps
  (lambda (n a)
    (cond
      ((zero? n) a)
      (else (!-aps (sub1 n) (* n a))))))
\end{schemedisplay}

\noindent Other than the space used to represent numbers, this
function uses a bounded amount of memory\footnote{Scheme
  implementations are required to handle tail calls properly---thus
  \scheme|!-aps| uses a constant amount of stack space}.  However, the
memoized version of \scheme|!-aps| uses an unbounded amount of memory
if \scheme|n| is negative, and otherwise uses an amount of memory
linear in \scheme|n|.

Chapter~\ref{tablingimplchapter} presents a complete implementation of
tabling for miniKanren; this implementation has several limitations.
The first limitation is that tabled relations must be closed; a tabled
goal constructor cannot contain free logic variables, since
associations for those variables would be thrown away.  This is a
consequence of not storing entire substitutions in a relation's table,
as described in section~\ref{tablingrep}.

Another limitation is that arguments passed to tabled relations must
be ``printable'' (or ``reifiable'') values.  For example, tabled
relations should never be passed functions, including goals, since all
functions reify to the same value\footnote{Pure relations should never
take functions as arguments anyway, since miniKanren does not support
higher-order unification, and cannot meaningfully construct functions
when running backwards.}.

The most significant limitation of our tabling implementation is that
it does not currently support disequality constraints, nominal
unification, or freshness constraints.  How to best combine tabling
and constraints is an open research problem~\cite{TCHR08}.


\subsection{Hats and Helmets}

\subsubsection{Knight's Helmet}
Size: M\\
Price: 100G\\
The knight's helmet is a full metal helmet with a visor.
It reduces the wearer's perception by 2, to a minimum of 1.\\
If the wearer of this helmet is subject to a critical hit from a weapon attack, the attacker must roll a d6.
On a 1, the attack does not deal additional damage from being a critical hit.\\

\subsubsection{Mages' Hat}
Size: M\\
Prices: 150G\\
The mages' hat is a signifier of a studied magister of magic.
It is pointy and made of magical silk.\\
While wearing a Mages' Hat, the wearer can remember 4 additional spells.\\

\subsubsection{Leather Helmet}
Size: M\\
Price: 20G\\
The Leather Helmet is a simple cap made of leather, with straps on the sides.\\
If the wearer of this helmet is subject to a critical hit from a weapon attack, the attacker must roll a d12.
On a 1, the attack does not deal additional damage from being a critical hit.\\

\subsubsection{Hood}
Size: M\\
Price: 5G\\
This hood protects the wearer's head of wind and rain and makes it more difficult to ee their face from the side.\\

\subsubsection{Skullcap}
Size: M\\
Price: 50G\\
This metal cap hugs the wearer's skull in order to protect it.\\
If the wearer of this helmet is subject to a critical hit from a weapon attack, the attacker must roll a d8.
On a 1, the attack does not deal additional damage from being a critical hit.\\

\subsubsection{Faceless Mask}
Size: M\\
Price: 70G\\
This special mask is completely featureless.
It blocks the user's sight, making them effectively blind.
However, it also increases their concentration.
While wearing a faceless mask, the mana costs for spell upkeep is halved.\\


\documentclass[12pt]{article}
\usepackage{design_ASC}
\usepackage[utf8]{inputenc}
\usepackage[english]{babel}
\usepackage{listings}
\usepackage{mathtools}
\DeclarePairedDelimiter\ceil{\lceil}{\rceil}
\DeclarePairedDelimiter\floor{\lfloor}{\rfloor}

\usepackage{hyperref}
\hypersetup{
    colorlinks=true,
    linkcolor=blue,
    filecolor=magenta,
    urlcolor=red,
}

\urlstyle{same}
\setlength\parindent{0pt}

\title{A SOTA Coding Problem\\ \href{https://github.com/Rishit-dagli/SOTA-Coding-Problem}{View on GitHub}}

\author{ \href{https://www.rishit.tech}{Rishit Dagli}\\
\href{https://twitter.com/rishit_dagli}{Twitter} $\vert$ \href{https://github.com/Rishit-dagli}{GitHub} $\vert$
\href{https://medium.com/@rishit.dagli}{Medium} $\vert$
\href{https://www.linkedin.com/in/rishit-dagli}{LinkedIn}
}

\date{\today}

\begin{document}
\setlength{\droptitle}{-5em}

\maketitle

\section*{Introduction}

I recently came across a State of the Art (SOTA) problem according
to me. How I define a problem to be really good-

\begin{itemize}
  \item While reading the problem it seems to be very easy
  \item It becomes hard while you try and code it (By logic and not by knowledge of coding)
  \item The optimal solution is just a few lines of code
\end{itemize}

I do not claim that the problem has been made by me in any manner. I
found this question while attempting
\href{https://foobar.withgoogle.com/}{Google FooBar}.

\section*{Dodge the Lasers! (The Problem)}
{\bfseries Someone who you earlier worked for has sent her elite
fighter pilot squadron after you - and they've opened fire!

Fortunately, you know something important about the ships trying to
shoot you down. Back when you were still her assistant, she asked
you to help program the aiming mechanisms for the ships. They
undergo rigorous testing procedures, but you were still able to slip
in a subtle bug. The software works as a time step simulation: if it is tracking a target that is accelerating away at $45$ degrees, the
software will consider the targets acceleration to be equal to the
$\sqrt{2}$, adding the calculated result to the targets end velocity
at each timestep. However, thanks to your bug, instead of storing
the result with proper precision, it will be truncated to an integer
before adding the new velocity to your current position.  This means
that instead of having your correct position, the targeting software
will erringly report your position as-
$$\sum_{i=1}^n \floor{i \cdot \sqrt{2}}$$
not far enough off to fail her testing, but enough that it might
just save your life.

If you can quickly calculate the target of the starfighters' laser
beams to know how far off they'll be, you can trick them into
shooting an asteroid, releasing dust, and concealing the rest of
your escape.  Write a function $solution(str_n)$ which, given the string representation of an integer $n$, returns the sum of
$$\floor{1 \cdot \sqrt{2}} + \floor{2 \cdot \sqrt{2}} + \ldots + \floor{n \cdot \sqrt{2}}$$
as a string. That is, for every number $i$ in the range $1$ to $n$,
it adds up all of the integer portions of $i \cdot \sqrt{2}$.

For example, if $str_n$ was $"5"$, the solution would be calculated
as-

$floor(1*sqrt(2)) +$

$floor(2*sqrt(2)) +$

$floor(3*sqrt(2)) +$

$floor(4*sqrt(2)) +$

$floor(5*sqrt(2))$

$= 1+2+4+5+7 = 19$

so the function would return $"19"$
}

\subsection*{Twist}

$n$ can have values upto $10^100$ which means it can have numbers
with 101 digits! Try solving this problem yourself first before
heading to the solution.

PS: If it was as easy as a for loop I would not have written this in
the first place

\subsection*{Hints}

This seems like a very easy problem. If you remove the story line,
all you need to calculate is-

$$\sum_{i=1}^n \floor{i \cdot \sqrt{2}}$$

The only twist is you cant use recursion for each element or use a
for loop as the numbers are too big. You need to try and simplify
the expression.

\section*{Solution}

Just some convention-

This type of sequence is called a  Beatty sequence. Beatty sequence
is the sequence of integers found by taking the floor of the
positive multiples of a positive irrational number. However, you do
not require any knowledge of it to solve the problem. \\

Let's define a function $\beta _r ^{(i)} = \floor{i \cdot r}$ for
some irrational number and

$$S(r,n) = \sum_{i=1}^n \beta _r ^{(i)}$$

if $r \geq 2$ we say $p = r - 1$ and we can also say-

\begin{align*}
S(p,n)&=S(s,n) + \sum_{i=1}^n \cdot i \\
&=S(s,n) + \frac{n(n+1)}{2}
\end{align*}

Also, if $1 < r < 2$ and $\frac{1}{p} + \frac{1}{r} = 1$ then
sequences $\beta_r$ and $\beta_p$ for $n \geq 1$ partition
$\mathbb{N}$

So,

$$S(r, n) + S(s, \lfloor \frac{\mathcal{B}_r^{(n)}}{s} \rfloor) =
\sum_i^{\mathcal{B}_r^{(n)}} i =
\frac{\mathcal{B}_r^{(n)}(\mathcal{B}_r^{(n)} + 1)}{2}$$

And also

\begin{align*}
\lfloor \frac{\mathcal{B}_r^{(n)}}{s} \rfloor &= \lfloor
\mathcal{B}_r^{(n)}(1 - \frac{1}{r}) \rfloor \\
&= \mathcal{B}_r^{(n)} - \lceil \frac{\mathcal{B}_r^{(n)}}{r} \rceil
\\ &= \mathcal{B}_r^{(n)} - n
\end{align*}

Then, letting $n^{\prime} = \lfloor (r - 1)n \rfloor =
\mathcal{B}_{r-1}^{n}$
we have
$$S(r,n) = \frac{\mathcal{B}_r^{(n)}(\mathcal{B}_r^{(n)} + 1)}{2} - S(p, n^{\prime}) = \frac{(n + n^{\prime})(n + n^{\prime} + 1)}{2} - S(p, n^{\prime})$$

Back to the problem, we have $p = \sqrt{2}$, so we start with $p = 2
+ \sqrt{2}$. We can get a recurrence formula.
Let $n^{\prime} = \lfloor (\sqrt{2} - 1)n \rfloor$

\begin{align*}
S(\sqrt{2}, n)
&= \frac{(n + n^{\prime})(n + n^{\prime} + 1)}{2} - S(2 + \sqrt{2},
n^{\prime})\\
&= \frac{(n + n^{\prime})(n + n^{\prime} + 1)}{2} -
(n^{\prime}(n^{\prime} + 1) - S(\sqrt{2}, n^{\prime}))\\
&= nn^{\prime} + \frac{n(n+1)}{2} - \frac{n^{\prime}(n^{\prime} +
1)}{2} - S(\sqrt{2}, n^{\prime})
\end{align*}

And we solved the problem, got an optimal way to solve it :)

\section*{In Code}

Let us now take a look at implementing this in code. We will just
convert all what we just talked about to code.

\begin{lstlisting}[language=Python]
minus_sqrt2 = 414213562373095048801688724209698078569671875376948 0731766797379907324784621070388503875343276415727
def n1(n):
    return (minus_sqrt2 * n) // (10 ** 100)
def s(n):
    if n == 1:
        return 1
    if n < 1:
        return 0
    return n * n1(n) + n * (n + 1) / 2 - n1(n) * (n1(n) + 1) / 2 - s(n1(n))
def solution(n):
    return str(s(int(n)))
\end{lstlisting}

In case you aren't able to view the rendered code block, navigate
down to "Try out yourself".

You can see it is just 11 lines of code to tackle this problem! I
think this is pretty cool, as just your logic was what counted here
and not knowledge of a programming language.

\subsection*{Try out for yourself}

You can try out this code for yourself using these links-
\begin{itemize}
    \item \href{https://github.com/Rishit-dagli/SOTA-Coding-Problem/blob/master/A_SOTA_Coding_problem_solution.ipynb}{Colab environment}
    - Requires a Google Account (Recommended)
    \item \href{https://repl.it/@RishitDagli/A-SOTA-Coding-Problem}{Repl.it environment}
\end{itemize}

\section*{About Me}

Hi everyone I am Rishit Dagli. This was my first time writing a blog
on a specific problem which I feel could help others develop their
logic. If you like this one and would love to see more of these kind
from me, consider
\href{https://github.com/Rishit-dagli/SOTA-Coding-Problem}{starring
the repo}

If you want to ask me some questions, report any mistake, suggest
improvements, give feedback you are free to do so by emailing me at-

\begin{itemize}
    \item rishit.dagli@gmail.com
    \item hello@rishit.tech
\end{itemize}

\end{document}


\documentclass{article}
\usepackage{graphicx}
\usepackage{amsmath}
\usepackage{tikz}
\usepackage[all]{xy}
\usetikzlibrary{positioning,chains,fit,shapes,calc}

\begin{document}

\title{Homework 10}
\author{Josh Cai}

\maketitle
\section*{Section 5.3}

\textbf{44)} Basis step: For the full binary tree of just the root $r$, this is true since $i(T)=0$ and $l(T)=1$.
\\Recursive step: For the inductive hypothesis, we assume that for two trees $T_1, T_2$ that the number of leaves of each is 1 larger than the number of internal vertices. Let $T$ be the full binary tree consisting of $T_1$ and $T_2$. The number of internal vertices is $i(T) = 1+i(T_1)+i(T_2)$. From the inductive hypothesis, the number of leaves is $l(T) = l(T_1) + l(T_2) = 2+i(T_1)+i(T_2)$. Since $l(T)$ is one more than $i(T)$, we have proved the recursive step.
\\\\\noindent\textbf{48a)} $A(1,0) = 0$

\noindent\textbf{48b)} $A(0,1) = 2$

\noindent\textbf{48c)} $A(1,1) = 2$

\noindent\textbf{48d)} $A(2,2) = A(1,A(2,1)) = A(1,2) = A(0,A(1,1)) = A(0,2) = 4$

\section*{Ch 5 Supplementary}

\noindent\textbf{59)} (()()) is in $B$ if ()() is in $B$. ()() is in $B$ if () is in $B$. () is in $B$ because $\lambda$ is in $B$, so (()()) is in $B$. (())) is in $B$ if ()) is in $B$. ()) is in $B$ if ) is in $B$, however ) isn't in $B$, so (())) isn't in $B$.
\\\\\noindent\textbf{60)} All the elements in $B$ with length 6 are ((())),()(()),()()(),(())(),(()()).
\\\\\noindent\textbf{62)} Basis step: For $\lambda$, the number of right parentheses is 0 which is equal to the number of left parentheses.
\\Recursive step: For the inductive hypothesis, we assume that for two elements in $B$, called $C$ and $D$, satisfy that the number of right parentheses is equal to the number of left parentheses. $(C)$ adds one to the left and one to the right, so the number remains equal, and the case is the same for $D$. $l(CD) = l(C)+l(D) = r(C)+r(D) = r(CD)$ so the number of left and right parentheses remain equal again, and the recursive step is done.

\section*{Section 11.2}
\noindent\textbf{2)} Attached below.
\\\\\noindent\textbf{4a)} 3 comparisons (oenology, phrenology, ornithology)

\noindent\textbf{4b)} 3 comparisons (oenology, campanaology, ichthyology)

\noindent\textbf{4c)} 3 comparisons (oenology, phrenology, ornithology)

\noindent\textbf{4d)} 3 comparisons (oenology, campanaology, ichthyology)
\\\\\noindent\textbf{6)} You could find it in one weighing if lucky, and at most two weighings are needed. Weigh 1 and 3 first, if one of them is lighter, that is the counterfeit coin. If they are balanced, weigh 2 and 4 and whichever is lighter is the counterfeit coin.

\section*{Ch 11 Supplementary}
\noindent\textbf{13)} Attached below.
\\\\\noindent\textbf{14)} $B_k$ has $2^k$ vertices. Basis step: $B_0$ has 1 vertex which is equal to $2^0$.
\\Recursive step: For the inductive hypothesis, assume that $B_k$ has $2^k$ vertices. By the definition of binomial trees, $B_{k+1}$ has two times the number of vertices $B_k$ has. Thus, $B_{k+1}$ has $2\times 2^k = 2^1\times 2^k = 2^{1+k} = 2^{k+1}$ vertices. Thus, the recursive step is done.
\\\\\noindent\textbf{16)} There are ${{k}\choose{j}}$ vertices in $B_k$ at depth $j$. Basis step: $B_0$ at depth 0 has ${{0}\choose{0}} = 1$ vertex.
\\Recursive step: For the inductive hypothesis, assume that for $B_k$, there are ${{k}\choose{j}}$ vertices at depth $j$. Then the number of vertices at depth $j$ in $B_{k+1}$ is equal to ${{k}\choose{j}}+{{k}\choose{j-1}}$ since the second $B_k$ graph is shifted down by 1. Then
\[\dbinom{k}{j}+\dbinom{k}{j-1} = \dfrac{k!}{j!(k-j)!}+\dfrac{k!}{(j-1)!(k-j+1)!}\]
\[ = \dfrac{k!(k-j+1)}{j!(k-j+1)!}+\dfrac{k!(j)}{(j)!(k-j+1)!}\]
\[ = \dfrac{k!(k-j+1+j)}{j!(k-j+1)!}\]
\[=\dfrac{(k+1)!}{j!(k+1-j)!}\]
\[= \dbinom{k+1}{j}\]
Thus, the recursive step is done, and we have proven that there are ${{k}\choose{j}}$ vertices in $B_k$ at depth $j$.

\end{document}


\documentclass[12pt,a4paper,twocolumn]{article}

\usepackage[top=0.8in, left=0.6in, right=0.6in, bottom=0.8in]{geometry}
\usepackage{natbib}
\usepackage[hidelinks]{hyperref}

\usepackage{color}

\usepackage{graphicx}
\usepackage{caption}
\usepackage{subcaption}

\usepackage{multicol}
\usepackage{multirow}

\author{Dionisio Perez-Mavrogenis}
\title{{Technical Report : Feature Selection Challenge}}

\begin{document}

\maketitle
\section{Abstract}
This paper is concerned with investigating using filter methods for selecting optimal feature subsets from a large feature space for the purpose of binary classification. The feature selection by \citep{filter_svms} is implemented, confirming their results, and feature selection is also done using the Pearson criterion. Their performance is compared using SVM classification on the GISETTE and ARCENE datasets from the NIPS 2003 challenge and by the classification error of the test set, calculated by the competition evaluation system.

\section{Classification Method}
The paper investigated was \citep{filter_svms}. In particular, \citep{filter_svms} used Equation \ref{fisher_score} for determining each feature's relevance and then kept the best $N$ features, where $N$ was the number of features that minimized the training error of an SVM, as shown in Fig.~\ref{fig:no_features}.

The SVM used in this paper is different than the one used by \citep{filter_svms},where a mixture of hard and soft-margin SVMs with a (modified) linear kernel was used. The SVM used in this paper was a soft-margin Gaussian kernel SVM as it was found to perform better. The value of $C$ and $\gamma$ was found by doing a grid-search with half of the features as described in \citep{grid_search}, using modified code from \citep{website:kitipat_heatmap}. The heat maps in Fig.~\ref{fig:heat_maps} show the optimal values for ARCENE and Fig.~\ref{fig:heat_maps_gisette} the values for GISETTE. The SVM library used was LIBSVM by \citep{libsvm}, as it was what \citep{filter_svms} used.

\begin{figure}
        \centering
        \begin{subfigure}[b]{0.5\textwidth}
                \includegraphics[width=\textwidth]{img/heat_map_huge_cv_10.png}
                \caption{Initial large heat map.}
                \label{fig:heat_map_large}
        \end{subfigure}
%        \begin{subfigure}[b]{0.55\textwidth}
%                \includegraphics[width=\textwidth]{img/heat_map_medium_10cv.png}
%                \caption{Medium heat map.}
%                \label{fig:heat_map_med}
%        \end{subfigure}
        \begin{subfigure}[b]{0.5\textwidth}
           \includegraphics[width=\textwidth]{img/heat_map_small_cv_10.png}
           \caption{Small heat map.}
	 	   \label{fig:heat_map_small}
        \end{subfigure}
        \caption{{\footnotesize Heat maps for determining $C, \gamma$ for ARCENE. Optimals found are $C=2^{3.5}$ and $\gamma = 2^{1.5}$}}
        \label{fig:heat_maps}
\end{figure}

\begin{figure}
        \centering
        \begin{subfigure}[b]{0.4\textwidth}
                \includegraphics[width=\textwidth]{img/gisette_large.png}
                \caption{Initial large heat map.}
                \label{fig:heat_map_large}
        \end{subfigure}
        \begin{subfigure}[b]{0.4\textwidth}
                \includegraphics[width=\textwidth]{img/gisette_small.png}
                \caption{Small heat map.}
                \label{fig:heat_map_med}
        \end{subfigure}

        \caption{{\footnotesize Heat maps for determining $C, \gamma$ for GISETTE. Optimum found at $C=32$ and $\gamma =1$.}}
        \label{fig:heat_maps_gisette}
\end{figure}

\section{Introduction to Feature Selection}
Feature selection is the process of identifying relevant features from the complete feature set of a dataset and working with these instead, effectively reducing the dimensionality of the data. Usually high-dimensional feature spaces contain some redundancy, as it is likely that more than one of the observed variables will describe the same property of a system but from a different perspective. As outlined in \citep{feature_selection_intro} feature selection can be viewed as a form of noise reduction. By reducing data dimensionality one is more likely to identify relationships within the data as well as gain in terms of both computational performance (less volume of data to process) and predictive power of the classifier (removing redundancy decreases the likelihood of the classifier to over-fit the data). Furthermore one might also gain in storage space or cost and transfer times as they have to deal with a reduced amount of information.

Current feature selection methods are broadly split into \emph{filter methods}, \emph{embedded methods} and \emph{wrapper methods}\citep{feature_selection_intro}\citep{filter_methods}. Although these three techniques try to achieve the same goal, they  go about their objective in different ways. Methods \emph{wrapper} and \emph{filter} are mostly similar, with the key difference between them being their evaluation criterion. \emph{Wrapper} methods usually evaluate a subset's performance by measuring the performance of a learning machine, making them computationally expensive, whereas \emph{filter} methods use statistical means for evaluation. Both can use a variety of search strategies to construct a feature subset, including greedy addition or elimination of features to a working subset, various heuristic methods or exhaustive search. \emph{Embedded} methods lie somewhere between the aforementioned  methods in terms of computational requirements and are tightly coupled to a learning machine, being incorporated as part of that machine's learning process.

\section{Datasets Considered}
The datasets used in this paper are ARCENE and GISETTE. The ARCENE dataset is non-sparse and describes a binary classification problem with continuous input variables and no missing values, having approximately 50\% non-zero entries. GISETTE is also a binary classification problem with continuous input variables and no missing values, but is sparse with approximately 13\% of entries being non-zero. Sample statistics of the datasets are given in Table~\ref{tab:pattern_info} and Table~\ref{tab:feature_info}.

The data used in this paper was pre-processed as in \citep{filter_svms} by using Equation~\ref{normalization_equation} for rescaling the data so that variables with large values will not dominate over variables with smaller values\citep{feature_selection_intro}, for example when calculating the difference of two patterns as their Euclidean distance, as well as making the data comparable with each other\citep{feature_selection_intro}.

\begin{equation}
x_k \to \frac{x_k}{1/m\sum_k||x_k||^2} \quad \forall ~ x_k , ~k= 1,\dots,m
\label{normalization_equation}
\end{equation}

\begin{table}
\center
    \caption{{\footnotesize Pattern information for the datasets considered in this paper.}}
    \label{tab:pattern_info}
    \begin{tabular}{| c | c | c | c |}

    \hline
    ~      & Set        & Positive & Negative \\ \hline
    ~      & Training   & 44           & 56           \\ \hline
    ARCENE & Validation & 44           & 56           \\ \hline
    ~      & Test       & 310          & 390          \\ \hline
    ~      & Training          & 3000            & 3000            \\ \hline
    GISETTE      & Validation          & 500            &500            \\ \hline
    ~      & Test          & 3250            & 3250 \\ \hline
    \end{tabular}
\end{table}

\begin{table}
\center
    \caption{{\footnotesize Feature information for the datasets used in this paper.}}
    \label{tab:feature_info}
    \begin{tabular}{| c | c | c |}
 \hline
    Dataset & Real Features & Probes \\ \hline
    ARCENE  & 7000          & 3000   \\ \hline
    GISETTE      & 2500             & 2500      \\ \hline
    \end{tabular}
\end{table}

\section{Algorithms Used}

We will be using filter methods for selecting optimal subsets of features and in particular correlation based approaches, namely the Fisher score criterion as used in  \cite{filter_svms} and the Pearson correlation coefficient. The feature set is greedily constructed by adding the $k$ highest ranking features to the existing set and then evaluating its training error.

A feature's Fisher score is defined for feature $j$ as

\begin{equation}
 R_j(X) = \frac{(\mu_j(X^+) - \mu_j(X^-))^2}{V_j(X^+)+ V_j(X^-)}  , \quad  j=1,\dots ,n
 \label{fisher_score}
\end{equation}

with $X$ an observation matrix, $\mu_j(X^+)$ the mean of feature $j$ over the positive instances of $X$ (accordingly for $\mu_j(X^-)$) and $V_j(X^+)  = 1/m \sum_{i=1}^m (x_{m,j}^+ - \mu_j(X^+) )^2 $, $x^+ \in X^+$ and $x_{m,j}$ denoting feature $j$ of observation $m$. Fig.~\ref{fig:scatter_bar} shows the correlation coefficients for ARCENE and confirms that many features have correlation coefficients of zero, indicating potential irrelevance, further supported by data in Fig.~\ref{fig:no_features} where one sees the cross-validation error not improving after a given number of features, implying that there is redundancy in the data and hence it is possible to reduce the data dimensionality. Fig.~\ref{fig:arcene_n} suggests using 5201 features for ARCENE and Fig.~\ref{fig:gisette_n} suggests using 801 features for GISETTE.

The Pearson correlation coefficient is defined as for a feature $j$ as

\begin{equation}
PC(j) = \frac{|\sum_{i=1}^m (x_{i,j} - \bar{x}_j)(y_i-\bar{y})|}{\sqrt{\sum_{i=1}^m(x_{i,j}-\bar{x}_j)^2\sum_{i=1}^m(y_i-\bar{y})^2}}
\label{eq:pearson}
\end{equation}

with the bar notation indicating an average over index $i$ \citep{feature_selection_intro}. A non-negative Pearson correlation coefficient indicates linear dependence while a value of 0 indicates no correlation\citep{filter_methods}.

\begin{figure}
        \begin{subfigure}[b]{0.55\textwidth}
                \includegraphics[width=\textwidth]{img/arcene_scatter.png}
                \caption{Correlation scores for each feature.},
                \label{fig:scatter}
        \end{subfigure}
        \begin{subfigure}[b]{0.55\textwidth}
                \includegraphics[width=\textwidth]{img/arcene_bar.png}
                \caption{Frequencies of correlation scores.}
                \label{fig:bar}
        \end{subfigure}
        \caption{{\footnotesize Frequencies of correlation scores for dataset ARCENE.}}
        \label{fig:scatter_bar}
\end{figure}

\begin{figure}
	\center
	\begin{subfigure}[b]{0.55\textwidth}
	        \includegraphics[width=\textwidth]{img/10f-cv.png}
			\caption{{\footnotesize ARCENE optimal value is 5201.}}
			\label{fig:arcene_n}
	\end{subfigure}

	\begin{subfigure}[b]{0.55\textwidth}
           	\includegraphics[width=\textwidth]{img/gisette_no_features.png}
	           \caption{{\footnotesize GISETTE optimal value is 801}.}
	           \label{fig:gisette_n}
        \end{subfigure}

        \caption{{\footnotesize10-fold cross validation for different number of features used. The features used were ranked by descending Fisher score.}}
        \label{fig:no_features}
\end{figure}

\begin{table*}
	\center
	\caption{{\footnotesize Performance of a Gaussian kernel SVM with Fisher scoring, trained on the validation and training sets for each dataset.A full set of information and submissions can be found at \protect\citep{website:competition_results}. }}

	\label{tab:arcene_results_all_data}

\begin{tabular}{|l|l|l|l|l|l|l|l|l|}
	\hline
	\multirow{2}{*}{Dataset}&\multicolumn{3}{|l|}{Balanced 	Error}&\multicolumn{3}{|l|}{Area Under Curve}&\multicolumn{2}{|l|}{Features}\\
	\cline{2-9}
	&Train&Valid&Test&Train&Valid&Test&\#&\%\\
	\hline
	arcene&0.0089&0.0114&0.1022&0.9821&0.9911&0.8978&5201&52.01\\
	\hline
	gisette &	0.0020 & 0.0020 &	0.0142	&0.9980	&0.9980	&0.9858&	801&	16.02 \\
	\hline
\end{tabular}

\begin{tabular}{|l|l|l|l|l|l|l|l|l|}
\hline
	\multirow{2}{*}{Dataset}&\multicolumn{3}{|l|}{Balanced 	Error}&\multicolumn{3}{|l|}{Area Under Curve}&\multicolumn{2}{|l|}{Features}\\
	\cline{2-9}
	&Train&Valid&Test&Train&Valid&Test&\#&\%\\
	\hline
arcene  & 0.0089     & 0         & 0.134     & 0.9911      & 1         & 0.866      & 5201         & 52.01         \\
\hline
gisette & 0.002      & 0.002     & 0.0166    & 0.998       & 0.998     & 0.9834     & 801          & 16.02        \\
\hline
\end{tabular}
\end{table*}

\section{Discussion}

Several figures (Fig.~\ref{fig:scatter_bar}, Fig.~\ref{fig:arcene_n}) were recreated in this paper from \citep{filter_svms} in order to familiarize the author with the problem. While \citep{filter_svms} used both hard and soft-margin SVMs with a modified linear kernel, we used a Gaussian kernel soft-margin SVM for higher performance. This paper used univariate statistical methods, Fisher score and Pearson's correlation coefficients, for ranking features according to their relevance. The advantage of correlation based approaches is that they avoid the discretization of continuous variables, probability density estimation and are easy to implement\citep{filter_methods}. However it would be equally valid to consider multivariate relevance criteria, such as the RELIEF approach, which attempt to evaluate a feature's relevance in the context of other features\citep{feature_selection_intro}, perhaps aiding in feature creation.

Table~\ref{tab:arcene_results_all_data} presents the performance of an SVM trained  on the training and validation data and tested (by the NIPS system) on the outputs it produced for the testing data and one can see that the Pearson correlation coefficient performs slightly worse than the Fisher score. The Pearson coefficient is meaningful to use if there exists a linear relationship between the variables, in this case each feature's relationship with the resulting class. If the relationship is non-linear (which we don't know) then the index would fail to capture adequately the relationship, unless the  data is transformed \citep{garcia:correlation_tutorial}, and this might explain its inferior performance.

Filter methods implemented in this paper performed reasonably well, given the information they consider and their complexity and may be used effectively as a first approach to understanding the data at hand. Perhaps in a setting where making a false prediction is associated with a large loss on should consider a more powerful approach towards understanding the data.

\bibliographystyle{plainnat}
{\footnotesize	\bibliography{aml_cw2_report} }

\appendix

\section{Source Code Listing}
Some MATLAB code was developed for this coursework and a list of files with descriptions follows. Additionally, the LIBSVM \citep{libsvm} package was used for SVM classification and code for performing grid search by \citep{website:kitipat_heatmap}.

\begin{enumerate}
\item \texttt{initialize\_arcene.m} : Load data for ARCENE.
\item \texttt{initialize\_gisette.m}: Load data for GISETTE.
\item \texttt{main.m} Loads data and computes Fisher scores.
\item \texttt{normalize.m} Normalizes a data matrix as in \citep{filter_svms}.
\item \texttt{gisette\_num\_features.m} Select number of features for GISETTE.
\item \texttt{select\_num\_features.m} Select number of features for ARCENE.
\item \texttt{arcene\_train.m} Train and produce predictions for ARCENE.
\item \texttt{c\_graph.m} Explore what happens for various values of C.
\item \texttt{g\_c\_grid\_search.m} Modified grid search code from  \citep{website:kitipat_heatmap}.
\item \texttt{pearson\_test.m} Calculate the Pearson coefficients, train and test for all datasets.
\item \texttt{fisher\_relevance.m} Computes the Fisher score of the data matrix.
\item \texttt{train\_and\_test.m} Train and test an SVM on the input data. Also produces result files for submission.

\end{enumerate}
\end{document}


\documentclass{article}
\usepackage{listings}
\usepackage{amsmath}
\usepackage{blindtext}
\usepackage{amssymb}
\usepackage{graphicx}
\usepackage[a4paper, margin=1in]{geometry}

\lstset{
	numbers=left,
 	frame=none,
	tabsize=4,
	keywordstyle=\color{blue},
}
\title{Proposal for Master Minds}
\author{
	Xinhao Su\\
	\texttt{xs2413}
	\and
	David Xu\\
	\texttt{dx2199}
}
\begin{document}
\maketitle
\section{Introduction}
Master Mind is a code breaking game that was invented in 1970 by Mordecai Meirowitz.
It resembles the earlier paper and pencil game
called Bulls and Cows that may date back a century.
The gameplay of Master Mind is straightforward:
\begin{enumerate}
	\item The codemaker picks 4 pegs (which can each be one of 6 different colors), and places them in order as the code. (Note that the code can have repeated colors, e.g. red red blue blue)
	\item The codebreaker needs to guess both the color and the order of the code within 8 turns.
	\item At each turn, the codemaker provides feedback by placing 0 to 4 pegs in response to a guess.
	A black peg indicates that one of the pegs in the guess is correct in both color and order.
	A white peg indicates that one of the pegs in the guess is correct in color but not order.
	\item The game is terminated when the codebreaker's guess is correct or 8 incorrect guesses have been made.
\end{enumerate}
\begin{figure}[h]
	\centering
	\includegraphics{mm.jpeg}
\end{figure}
Since we will use parallelism to find the solution, our project will be called \textit{Master Minds}.

\pagebreak
\section{Algorithm}

The Master Mind game can be rephrased as The Mastermind Problem:
Given a set of guesses and the feedback for each guess (number of colored and white pegs), is there at least one code that generates those exact feedback reponses?
It is interesting to note that this problem is in effect a multi-dimensional search problem.
The Mastermind Problem has been proven to be NP-Complete\footnote{Stuckman, J., \& Zhang, G. Q. (2005). Mastermind is NP-complete. \textit{arXiv preprint cs/0512049}.}.

\paragraph[]{Our project will use Donald Knuth's Five-Guess Algorithm\footnote{Knuth, D. E. (1976). The computer as master mind. \textit{Journal of Recreational Mathematics, 9}(1), 1-6.} to break the code:}

\begin{enumerate}
	\item Generate the set of possible codes, denoted as $S$. E.g., $S= \{ 6^4=1296 \ codes\}$
	\item Start with an initial guess (initial guess can be hardcoded or randomly selected from $S$)
	\item Play the guess and get response from codemaker
	\item If the feedback is all black, we have found the code.
	\item Otherwise, remove all the codes that would not produce the most recent response from $S$. For example, if our guess had two blues and the response is only one white peg, then we know the true code cannot have two blues.
	\item For the next guess, select a code (not necessarily in $S$) which minimizes the maximum possible number of remaining codes in $S$ across all possible true codes.
	\item Repeat from Step 3.
\end{enumerate}

\section{Testing Plan}
Since the Mastermind game has many variations, we intend to test our project on all or some of the following variations:
\begin{enumerate}
	\item Mastermind - 6 colors, guessing 4 pegs
	\item New Mastermind - 8 colors, guessing 4 pegs
	\item Word Mastermind - 26 letter, guessing 4 letters
	\item Grand Mastermind - 5 colors with 5 shapes, guessing 4 pegs
	\item Crazy Mastermind - 12 colors, guessing 4 pegs

\end{enumerate}
Our project could also be used to analyze which codewords minimize the maximum or average number of guesses required based on which initial guess is used for each of these variations.

\section{Opportunities for Parallelization}
\begin{enumerate}
	\item The execution of the algorithm with different initial guesses is embarrassingly parallelizable.
	\item In the process of selecting the next guess, the calculation of the worst-case (maximum possible) number of remaining codes for any given guess can be parallelized.
	\item If we desire to play multiple variations of the game at the same time, such gameplay can also be parallelized.
\end{enumerate}
\end{document}


% When using TeXShop on the Mac, let it know the root document. The following must be one of the first 20 lines.
% !TEX root = ../design.tex

\chapter[Clustering (k-means et al.)]{Clustering ($k$-Means et al.)}

\begin{moduleinfo}
\item[Author] \href{mailto:Florian.Schoppmann@emc.com}{Florian Schoppmann} (version 0.5 only)
\item[History]
	\begin{modulehistory}
		\item[v0.5] Initial revision of design document, complete rewrite of module, arbitrary user-specifyable distance and recentering functions
		\item[v0.3] Multiple seedings methods (kmeans++, random, user-specified list of centroids), multiple distance functions (corresponding recentering function hard-coded), simplified silhouette coefficient as goodness-of-fit measure
		\item[v0.1] Initial version, always use kmeans++ for seeding
	\end{modulehistory}
\end{moduleinfo}

% Abstract. What is the problem we want to solve?
Clustering refers to the problem of partitioning a set of objects into homogeneous subsets, i.e., such that objects in the same group have \emph{similar} properties. Arguably the best-known clustering problem is \emph{$k$-means}. Here, one is given $n$ points $x_1, \dots, x_n \in \R^d$, and the goal is to position $k$ centroids $c_1, \dots, c_k \in \R^d$ so that the sum of squared Euclidean distances between each point and its closest centroid is minimized. A cluster is identified by its centroid and consists of all points for which this centroid is closest. Formally, we wish to minimize the following objective function:
\begin{gather*}
    (c_1, \dots, c_k) \mapsto \sum_{i=1}^n \min_{j=1}^k \dist(x_i, c_j) \SiM,
\end{gather*}
where $\dist(x,y) := \| x - y \|_2^2$. A straightforward generalization of the above minimization problem is to choose a different metric $\dist$. Strictly speaking, this is no longer $k$-means; for instance, choosing $\dist(x,y) = \| x - y\|_1$ yields the $k$-median problem instead.

Despite certain reservations, we follow the practice of many authors and use ``$k$-means'' also to refer to a particular algorithm (as opposed to an optimization problem), as discussed below.

\section{Overview of Algorithms} \label{sec:kmeans:Algorithms}

% Explain the algorithm at a high-level -- do not talk about specific variations or implementation details. Give some theoretical background: Is the problem hard? What results can we expect?
The $k$-means problem is NP-hard in general Euclidean space (even for just two clusters) \cite{ADH09a} and for a general number of clusters (even in the plane) \cite{MNV10a}. However, the local-search heuristic proposed by \citeauthor{L82a}~\cite{L82a} performs reasonably well in practice. In fact, it is so ubiquitous today that it is often referred to as the standard algorithm or even just the $k$-means algorithm. At a high level, it works as follows:

\begin{enumerate}
	\item Seeding phase: Find initial positions for $k$ centroids $c_1, \dots, c_k$.
	\item Assign each point $x_1, \dots, x_n$ to its closest centroid. \label{enum:kmeans_abstract_points}
	\item Move each centroid $c$ to a position that minimizes the sum of distances between $c$ and each point assigned to $c$. (Note that if ``distance'' refers to the squared Euclidean distance, then this position is the barycenter/mean of all points assigned to $c$.)
	\item If convergence has been reached, stop. Otherwise, goto \eqref{enum:kmeans_abstract_points}.
\end{enumerate}

Since the value of the objective function decreases in every step, and there are only finitely many clusterings, the algorithm is guaranteed to converge to a local minimum \cite[Section~16.4]{CS08a}. While it is known that there are instances for which \citeauthor{L82a}'s heuristic takes exponentially many steps~\cite{V09a}, it has been shown that the algorithm has polynomial smoothed complexity \cite{AMR09a}---thus giving some theoretical explanation for good results in practice. With a clever seeding technique, \citeauthor{L82a}'s heuristic is moreover $O(\log k)$-competitive \cite{AV07a}.

\subsection{Algorithm Variants}

% Give an overview and references to variations that exist for this algorithm.
\paragraph{Seeding}

The quality of $k$-means is highly influenced by the choice of the seeding \cite{AV07a}. The following is a non-exhaustive list of options:
\begin{enumerate}
	\item Manual: User-specified list of initial centroid positions.
	\item Uniformly at random: Choose the $k$ centroids uniformly at random among the point set
	\item \texttt{$k$-means++}: Perform seeding so that the objective function is minimized in expectation \cite{AV07a}
	\item Use a different clustering algorithm for determining the seeding \cite{MNU00a}
	\item Run $k$-means with multiple seedings and choose the clustering with lowest cost
\end{enumerate}

\paragraph{Repositioning}

Most $k$-means formulations in textbooks do not detail the case where a centroid has no points assigned to it. It is an easy observation that moving a stray centroid in this case can only decrease the objective function. This can be done in a simple way (move onto a random point) or more carefully (e.g., move so that the objective function is minimized in expectation).

\paragraph{Convergence Criterion}

There are several reasonable convergence criteria. E.g., stop when:
\begin{enumerate}
	\item The number of repositioned centroids is below a given threshold
	\item The change in the objective drops below a given threshold
	\item The maximum number of iterations has been reached
	\item See, e.g., \textcite[Section~16.4]{CS08a} for more options.
\end{enumerate}

\paragraph{Variable Number of Clusters}

The number of clusters $k$ could be determined by the seeding algorithm (instead of being a parameter) \cite{MNU00a}. Strictly speaking, however, the algorithm should not be called $k$-means in this case.

\section{Seeding Algorithms}

In the following, we describe the seeding methods to be implemented for MADlib.

\subsection{Uniform-at-random Sampling}

Uniform-at-random sampling just uses the algorithms described in Section~\ref{sec:SampingWOReplacement}.

\subsection[k-means++]{$k$-means++}

\texttt{$k$-means++} seeding \cite{AV07a} starts with a single centroid chosen randomly among the input points. It then iteratively chooses new centroids from the input points until there are a total of $k$ centroids. The probability for picking a particular point is proportional to its minimum distance to any existing centroid. Intuitively, \texttt{$k$-means++} favors seedings where centroids are spread out over the whole range of the input points, while at the same time not being too susceptible to outliers.

\subsubsection{Formal Description}

\begin{algorithm}[$k$-means++$(k, P, \dist, C)$] \label{alg:kmeans++}
\alginput{Number of desired centroids $k$, set $P$ of points in $\R^d$, metric $\dist$, \\
	set $C$ of initial centroids}
\algoutput{Set of centroids $C$}
\begin{algorithmic}[1]
	\If{$C = \emptyset$}
		\State $C \set \{ \text{initial centroid chosen uniformly at random from } P \}$ \label{alg:kmeanspp:firstCentroid}
	\EndIf
	\While{$|C| < k$} \label{alg:kmeans++:for}
		\State $C \set C \cup \{ \text{random $p \in P$ with probability proportional to }\min_{c \in C} \dist(p,c) \}$ \label{alg:kmeanspp:nextcentroid}
	\EndWhile
\end{algorithmic}
\end{algorithm}

\begin{description}
	\item[Runtime] A naive implementation needs $\Theta(k^2 n)$ distance calculations, where $n = |P|$. A single distance calculation takes $O(d)$ time.
	\item[Space] Store $k$ centroids.
	\item[Subproblems]
		The existing \ref{sym:weighted_sample} subroutine can be used for:
		\begin{itemize}
			\item Line~\ref{alg:kmeanspp:firstCentroid}: Sample uniformly at random
			\item Line~\ref{alg:kmeanspp:nextcentroid}: Sample according to a discrete probability distribution.
		\end{itemize}
\end{description}

The number of distance calculations could be reduced by a factor of $k$ if we store, for each point $p \in P$, the distance to its closest centroid. Then, each iteration only needs $n$ distance calculations (i.e., only between the most recently added centroid and all points). In total, these are $\Theta(k n)$ distance calculations. Making this idea explicit leads to the following algorithm.

\begin{algorithm}[$k$-means++-ext$(k, P, \dist)$] \label{alg:kmeans++ext}
\alginput{Number of desired centroids $k$, set $P$ of points in $\R^d$, metric $\dist$, \\
	set $C$ of initial centroids}
\algoutput{Set of centroids $C$}
\algprecond{For all $p \in P: \delta[p] = \min_{c \in C} \dist(p, c)$ (or $\delta[p] = \infty$ if $C = \emptyset$)}
\begin{algorithmic}[1]
	\While{$|C| < k$} \label{alg:kmeans++ext:for}
		\State $\mathit{lastCentroid} \set \ref{sym:weighted_sample}(P, \delta)$ \label{alg:kmeans++ext:nextCentroid} \Comment{$\delta$ denotes the mapping $p \mapsto \delta[p]$}
		\State $C \set C \cup \{ \mathit{lastCentroid} \}$
		\For{$p \in P$} \label{alg:kmeans++ext:pointLoop}
			\If{$\dist(p, \mathit{lastCentroid}) < \delta[p]$}
				\State $\delta[p] \set \dist(p, \mathit{lastCentroid})$
			\EndIf
		\EndFor
	\EndWhile
\end{algorithmic}
\end{algorithm}

\begin{description}
	\item[Tuning] \label{kmeans++ext:tuning} The inner for-loop in line~\ref{alg:kmeans++ext:pointLoop} and \ref{sym:weighted_sample} in line~\ref{alg:kmeans++ext:nextCentroid} could be combined. With this improvement, only one pass over $P$ is necessary.
	\item[Runtime] $O(dkn)$ as explained before.
	\item[Space] Store $k$ centroids and $n$ distances.
	\item[Scalability] The outer while-loop is inherently sequential because the random variates in each iteration depend on all previous iterations. The inner loop, however, can be executed with data parallelism.
\end{description}

\subsubsection{Implementation as User-Defined Function}

In general, the performance benefit of explicitly storing points (i.e., choosing \ref{alg:kmeans++ext} over \ref{alg:kmeans++}) depends on the DBMS, the data, and the operating environment. The pattern of updating temporary state is made a bit more awkward in PostgreSQL due to its legacy of versioned storage. PostgreSQL performs an update by first inserting a new row and then marking the old row as invisible \cite[Section~23.1.2]{postgres:9.1.3}. As a result, for updates that touch many rows it is typically faster to copy the updated data into a new table (i.e., \texttt{CREATE TABLE AS SELECT} and \texttt{DROP TABLE}) rather than issue an \texttt{UPDATE}. Given these constraints, we currently choose to only implement algorithm~\ref{alg:kmeans++} (but not \ref{alg:kmeans++ext}) as the user-defined function \symlabel{kmeanspp\_seeding}{sym:kmeans++}.

\paragraph{In- and Output} The UDF expects the following arguments, and returns the following values:

\begin{center}
	\begin{tabularx}{\textwidth}{rlXl}
		\toprule%
		\textbf{Name} & \textbf{Description} & \textbf{Type}
		\\\otoprule
		In &
		\texttt{rel\_source} &
		Relation containing the points as rows &
		relation
		\\\midrule
		In &
		\texttt{expr\_point} &
		Point coordinates, i.e., the point $p$ &
		\specialcell{l}{expression\\ (floating-point vector)}
		\\\midrule
		In &
		\texttt{k} &
		Number of centroids &
		integer
		\\\midrule
		In &
		\texttt{fn\_dist} &
		Function returning the distance between two vectors &
		function
		\\\midrule
		In &
		\texttt{initial\_centroids} &
		Matrix containing the initial centroids as columns. This argument may be omitted (corresponding to an empty set $C$ of initial centroids). &
		floating-point matrix
		\\\midrule
		Out &
		&
		Matrix containing the $k$ centroids as columns &
		floating-point matrix
		\\\bottomrule
	\end{tabularx}
\end{center}

\paragraph{Components} The set of centroids $C$ is stored as a dense floating-point matrix that contains the centroids as columns vectors. Algoritm~\ref{alg:kmeans++} can be (roughly) translated into SQL as follow. We assume here that all function arguments are available as constants, and the matrix containing the centroids as columns is available as \texttt{centroids}. Line~\ref{alg:kmeanspp:firstCentroid} becomes:
\begin{lstlisting}[language=SQL,gobble=4]
    SELECT ARRAY[weighted_sample($expr_point, 1)]
    FROM $rel_source
\end{lstlisting}
Line~\ref{alg:kmeanspp:nextcentroid} is implemented using essentially the following SQL.
\begin{sql}[emph={centroids,fn_dist}]
    SELECT centroids || weighted_sample(
        $expr_point, (
            closest_column(
                centroids,
                $expr_point,
                fn_dist
        )).distance
    ) FROM $rel_source
\end{sql}
See Section~\ref{sec:matrix:closestColumn} for a description of \ref{sym:closestColumn}.

\subsubsection{Historical Implementations}

Implementation details and big-data heuristics that were used in previous versions of MADlib are documented here for completeness.

\begin{description}
	\item[v0.2.1beta and earlier] In lines~\ref{alg:kmeanspp:firstCentroid} and \ref{alg:kmeanspp:nextcentroid} of Algorithm~\ref{alg:kmeans++} use a random sample $P' \subsetneq P$.

		Here $P'$ will be a new random sample in each iteration. Under the a-priori assumption that a random point belongs to any of the $k$ (unknown) clusters with equal probability, sample enough points so that with high probability (e.g., $p = 0.999$) there is a point from each of the $k$ clusters.

		This is the classical occupancy problem (also called balls-into-bins model) \cite{F68a}: Throwing $r$ balls into $k$ bins, what is the probability that no bin is empty? The exact value is
		\begin{align*}
			u(r, k) = k^{-r} \sum_{i=0}^k (-1)^i \binom ki (k - i)^r
			\SiM.
		\end{align*}

		For $r,k \to \infty$ so that $r/k = O(1)$ we have the limiting form $u(r,k) \to (1 - e^{-r/k})^k =: \widetilde u(r, k)$. Rearranging $\widetilde u(r, k) > p$ gives $-\log(1 - \sqrt[k]p) \cdot k < r$. The smallest $r$ satisfying this inequality is chosen as the size of the sample set.
\end{description}

\section[Standard algorithm for k-means clustering]{Standard algorithm for $k$-means clustering}

The standard algorithm has been outlined in Section~\ref{sec:kmeans:Algorithms}. The formal description and our implementation are given below.

\subsection{Formal Description}

\begin{algorithm}[$k$-means$(k, P, \dist)$] \label{alg:kmeans}
\alginput{Set of initial centroids $C$, set $P$ of points, seeding strategy $\mathit{Seeding}$, metric $\dist$, \\
centroid function $\mathit{centroid}$, convergence strategy $\mathit{Convergence}$}
\algoutput{Set $C$ of final means}
\algprecond{$i = 0$}
\begin{algorithmic}[1]
	\Repeat
		\State $i \set i + 1$
		\State $C_\text{old} \set C$
		\State $C \set \bigcup_{c \in C} \{ \mathit{centroid} \{p \in P \mid \arg\min_{c' \in C} \dist(p, c') = c \} \}$ \label{alg:kmeans:MoveCentroids}
		\State $C \set \mathit{Seeding}(k, P, \dist, C)$ \label{alg:kmeans:Reseed} \Comment{Reseed ``lost'' centroids (if any)}
	\Until{$Convergence(C, C_\text{old}, P, i)$} \label{alg:kmeans:ConvergenceCond}
\end{algorithmic}
\end{algorithm}

\begin{description}
	\item[Runtime] See discussion in Section~\ref{sec:kmeans:Algorithms}.
	\item[Space] Store $2k$ centroids (both sets $C$ and $C_\text{old}$)
	\item[Scalability] The outer loop is inherently sequential. The recentering in line~\ref{alg:kmeans:MoveCentroids} is data-parallel (provided that the sets $C$ and $C_\text{old}$ are available on all computation nodes). Likewise, the convergence check in line~\ref{alg:kmeans:ConvergenceCond} is data-parallel if it only relies on distances between points $p$ and the set of centroids $C$, or the number of iterations.
\end{description}

\subsection{Implementation as User-Defined Function}

Algorithm~\ref{alg:kmeans} is implemented as the user-defined function \symlabel{kmeans}{sym:kmeans}. We choose to not make the convergence criterion a function argument but instead settle for parameters for the most typical criteria. Should the need arise, we might revoke that decision in the future. Moreover, the seeding strategy is currently not an argument, but \ref{sym:kmeans++} is always used in line~\ref{alg:kmeans:Reseed}.

\paragraph{In- and Output} The UDF expects the following arguments, and returns the following values:

\begin{center}
	\begin{tabularx}{\linewidth}{rlXl}
		\toprule%
		\textbf{Name} & \textbf{Description} & \textbf{Type}
		\\\otoprule
		In &
		\texttt{rel\_source} &
		Relation containing the points as tuples &
		relation
		\\\midrule
		In &
		\texttt{expr\_point} &
		Point coordinates, i.e., the point $p$ &
		\specialcell{l}{expression\\ (floating-point vector)}
		\\\midrule
		In &
		\texttt{initial\_centroids} &
		Matrix containing the initial centroids as columns &
		floating-point matrix
		\\\midrule
		In &
		\texttt{fn\_dist} &
		Function returning the distance between two vectors &
		function
		\\\midrule
		In &
		\texttt{agg\_centroid} &
		Aggregate returning the centroid for a set of points &
		function
		\\\midrule
		In &
		\texttt{max\_num\_iterations} &
		Convergence criterion: Maximum number of iterations &
		integer
		\\\midrule
		In &
		\texttt{min\_frac\_reassigned} &
		Convergence criterion: Convergence is reached if the fraction of points being reassigned to another centroid drops below \texttt{conv\_level} &
		floating-point
		\\\midrule
		Out & &
		Matrix containing the $k$ centroids as columns &
		floating-point matrix
		\\\bottomrule
	\end{tabularx}
\end{center}

\paragraph{Components}

The set of centroids $C$ is stored as a dense floating-point matrix that contains the centroids as columns vectors. Algoritm~\ref{alg:kmeans} can be (roughly) translated into SQL as follow. We assume here that all function arguments are available as constants, and the matrix containing the centroids is available as \texttt{centroids}. (These variables, which are unbound in the SQL statement, are shown in italic font.) Line~\ref{alg:kmeans:MoveCentroids} becomes:
%
\begin{sql}[emph={centroids,fn_dist}]
    SELECT matrix_agg(_centroid)
    FROM (
        SELECT $agg_centroid(_point) AS _centroid
        FROM (
            SELECT
                $expr_point AS _point,
                (closest_column(
                    centroids,
                    $expr_point,
                    fn_dist
                )).column_id AS _new_centroid_id
            FROM $rel_source
        ) AS _points_with_assignments
        GROUP BY _new_centroid_id
    ) AS _new_centroids
\end{sql}
See Section~\ref{sec:matrix:matrixAgg} for a description of \ref{sym:matrixAgg}.

It is a good idea to also compute the number of reassigned centroids, so that both line~\ref{alg:kmeans:MoveCentroids} and the convergence check in line~\ref{alg:kmeans:ConvergenceCond} can be computed with one pass over the data. To that end, we extend the inner-most query to also compute the previous closest centroid (i.e., we do a second \ref{sym:closestColumn} call where we pass matrix \texttt{old\_centroids} as first argument). During the aggregations in the two outer queries, we can then count (or sum up, respectively) the number of points that have been reassigned.

A caveat during testing whether a point has been reassigned is that centroid IDs are not constant over iterations: \ref{sym:closestColumn} returns a column index in the matrix \texttt{centroids}, and this matrix is the result of the \ref{sym:matrixAgg} aggregate---hence, the order of the columns is non-deterministic. We therefore cannot directly compare a column index from iteration $i$ to a column index from iteration $i - 1$, but instead need to translate the ``new'' index into an ``old'' index first. In order to do that, we extend the outermost query and also build up an array \texttt{old\_centroid\_ids}, where position $i$ will contain the column index that centroid $i$ had in the previous iteration. \Warning{A crucial assumption on the DBMS backend here is that the two aggregates \texttt{array\_agg} and \ref{sym:matrixAgg} see all tuples in the same order.} Putting everything together, the query becomes:
%
\begin{sql}[emph={centroids,old_centroids,old_centroid_ids,fn_dist}]
    SELECT
        matrix_agg(_centroid),        -- New value for: centroids
        array_agg(_new_centroid_id),  -- New value for: old_centroid_ids
        sum(_objective_fn),           -- New value for: objective_fn
        CAST(sum(_num_reassigned) AS DOUBLE PRECISION) / sum(_num_points)
                                      -- New value for: frac_reassigned
    FROM (
        SELECT
            (_new_centroid).column_id AS _new_centroid_id,
            sum((_new_centroid).distance) AS _objective_fn,
            count(*) AS _num_points,
            sum(
                CAST(
                    old_centroid_ids[(_new_centroid).column_id + 1] != _old_centroid_id
                    AS INTEGER
                )
            ) AS _num_reassigned,
            $agg_centroid(_point) AS _centroid
        FROM (
            SELECT
                $expr_point AS _point,
                closest_column(
                    centroids,
                    $expr_point,
                    fn_dist
                ) AS _new_centroid,
                (closest_column(
                    old_centroids,
                    $expr_point,
                    fn_dist
                )).column_id AS _old_centroid_id
            FROM $rel_source
        ) AS _points_with_assignments
        GROUP BY (_new_centroid).column_id
    ) AS _new_centroids
\end{sql}

Finally, line~\ref{alg:kmeans:Reseed} is simply implemented by calling function \ref{sym:kmeans++}. For a slight performance benefit, this function call should be guarded by a check if the number of centroids is lower than $k$.


\documentclass{article}[11pt,oneside]
\usepackage{graphicx}

\begin{document}
%Documentation for Seismogram

%% TITLE AND OVERVIEW
\section*{Normal Incidence Reflection Seismogram}
In seismic methods, acoustic energy in the form of pressure or shear waves is input into the ground.
Geophones are used to record the ground motions caused by the acoustic energy. In the case of reflection seismology, we focus on the energy which is reflected off of boundaries that separate layers with different physical properties.

\begin{figure}[H]
	\centering \includegraphics[width=\textwidth]{concept1.png}
\end{figure}

This example allows us to build a synthetic seismogram for a seismic wave which travels vertically. It simulates the case where the source and receiver are coincident and the geologic layers are horizontal. The time taken for the wave to travel from the source and be reflected off of these layers back to the surface depends on the velocity and thickness of each layer.

Synthetic seismograms are routinely generated from well logs (measurements made in depth) and \emph{tied} to the seismic data in order to interpret the seismic data.
Check out: http://library.seg.org/doi/pdf/10.1190/tle33060674.1 for a tutorial.

% TODO: Insert image of normal incidence reflection \& transmission on layers

\section*{Physical Properties}
\subsection*{Density, $\rho$ [kg/m$^3$]}
Density is the mass per unit volume of a material. In general, density increases with depth.

\subsection*{Seismic Velocity, $v$ [m/s]}
Seismic velocities depends on density and elastic properties of the rock. The P or compressional wave velocity is given by
$$v_p = \sqrt{\frac{K + 4/3\mu}{\rho}}$$
and the S or shear wave velocity is given by
$$v_s = \sqrt{\frac{\mu}{\rho}}$$
$K$ and $\mu$ are elastic parameters (the bulk and shear moduli). Most often, seismic velocity increases with depth. What does that imply about the magnitude of the elastic parameters?

\section*{Acoustic Impedance}

Acoustic impedance is the product of density and velocity, $Z_i = \rho_i v_i$.

\section*{Reflectivity}
At an interface energy is partitioned, some is reflected, and some is transmitted. The fraction of amplitude reflected is described by the reflection coefficient:
$$R_i = \frac{Z_{i+1} - Z_i}{Z_{i+1}+Z_i} \quad -1 \leq R_i \leq 1$$
and the amount transmitted is described by the transmission coefficient:
$$T_i = 1-R_i = \frac{2Z_1}{Z_2+Z_1} \quad 0 \leq T_i \leq 2$$

If a seismic wave, with source amplitude 1, is transmitted through the first interface, and reflected off of the second interface, what is the amplitude of the wave that arrives at the geophone?

\begin{figure}[H]
	\centering \includegraphics[width=\textwidth]{Amplitude.png}
\end{figure}

What does the polarity of an arrival imply about the physical properties of the layers?

% TODO: talk about polarity (why does it reverse, also which term tends to be more important)
% TODO: Insert image explaining this.

\section*{Depth-Time Curve}
The amount of time taken for the seismic signal to travel from the source to the interface where it is reflected and back to the geophone where it is measured depends on the thickness of the layer and its seismic velocity. The contribution from a single layer with thickness $h_i,$ and velocity $v_i$ is given by
$$t_i = \frac{2h_i}{v_i}$$.

When does the reflection from the second interface arrive?

\begin{figure}[H]
	\centering \includegraphics[width=\textwidth]{TimeTravel.png}
\end{figure}
% TODO: Insert image explaining this: show contribution from each layer and the total twt is the sum of all of the contributions.

\section*{Wavelet}
The wavelet is our input energy. Its center frequency ($f$) is related to seismic resolution, which describes how thin a layer can be before reflections from its top and bottom become indistinguishable. The theoretical minimum is $1/4 \lambda$, where $\lambda$ is the wavelength (recall $v = f\lambda$).

\section*{Seismogram}
The reflection seismogram is the convolution of the reflectivity series with the input. The relative amplitude and polarity of the reflection event is given by the reflectivity series (in the absence of attenuation).

\end{document}


\documentclass{report}

\usepackage{634format}
\usepackage{amsmath}

\usepackage{listings}
\usepackage{textcomp}

\usepackage{hyperref}

\usepackage{holtex}
\usepackage{holtexbasic}
\input{commands}

\begin{document}
\lstset{language = ML}

\title{Project 2}
\author{\textbf{Jinhao Wei}}
\date{January 29, 2019}

\maketitle{}

\begin{abstract}
This project is mainly a practice on programming in ML. In this project, we conducted several basic operations, such as function application, pattern matching, etc., in HOL. This report is basically a summary of each of the practice problems. For each of the problems, this report contains:
\begin{itemize}
\item Problem Statements
\item Relevant Code
\item Test Results (and Analysis)
\end{itemize}

Apart of being a summary on the problems, this report itself is a practice on generating and formatting of \LaTeX{} report files. This report used several packages for formatting the document, including:
\begin{itemize}
\item a style file for the course, \emph{634format.sty}
\item the \emph{listing} package for displaying and inputting ML source code
\item \emph{holtex.sty} and \emph{holtexbasic.sty}, which were provided in professor Shiu-Kai Chin's sample report
\end{itemize}

\end{abstract}

\begin{acknowledgments}
This project followed Professor Shiu-Kai Chin's sample documents' format, and used multiple \emph{.sty} files, such as \emph{634format.sty}, \emph{holtex.sty}, \emph{holtexbasic.sty}, which were provided in Professor Shiu-Kai Chin's sample report.
\end{acknowledgments}

\tableofcontents{}
\chapter{Executive Summary}
\label{cha:Executive-Summary}

\textbf{All requirements for this project are satisfied} Specifically,

\begin{description}
\item[Report Contents] \ \\
This report consists of:

\begin{enumerate}
\item[] Chapter~\ref{cha:Executive-Summary}: Executive Summary
\item[] Chapter~\ref{cha:exercise-2.5.1}: Exercise 2.5.1
    \begin{enumerate}
      \item[] Section~\ref{sec:2.5.1-problem-statement}: Problem Statement
      \item[] Section~\ref{sec:2.5.1-relevant-code}: Relevant Code
      \item[] Section~\ref{sec:2.5.1-test-results}: Test Results
    \end{enumerate}

\item[] Chapter~\ref{cha:exercise-3.4.1}
\begin{enumerate}
      \item[] Section~\ref{sec:3.4.1-problem-statement}: Problem Statement
      \item[] Section~\ref{sec:3.4.1-relevant-code}: Relevant Code
      \item[] Section~\ref{sec:3.4.1-test-results}: Test Results
    \end{enumerate}
\item[] Chapter~\ref{cha:exercise-3.4.2}
\begin{enumerate}
      \item[] Section~\ref{sec:3.4.2-problem-statement}: Problem Statement
      \item[] Section~\ref{sec:3.4.2-relevant-code}: Relevant Code
      \item[] Section~\ref{sec:3.4.2-test-results}: Test Results
    \end{enumerate}

\item[] Appendix~\ref{appendix:A}: Source Code For Exercise 2.5.1
\item[] Appendix~\ref{appendix:B}: Source Code For Exercise 3.4.1
\item[] Appendix~\ref{appendix:C}: Source Code For Exercise 3.4.2
\end{enumerate}

\item [Reproducibility in ML and \LaTeX]\ \\
All ML and \LaTeX{} source files compile well on the environment provided by this course.
\end{description}

\chapter{Exercise 2.5.1}
\label{cha:exercise-2.5.1}

\section{Problem Statement}
\label{sec:2.5.1-problem-statement}

Our basic tasks in this problem are to:
\begin{enumerate}
\item Create a new \emph{.sml} file, which contains code and test cases
\item Evaluate values using the function defined in code
\end{enumerate}

\subsection{Functions to implement}
\label{subsec:2.5.1-functions-to-implement}

Our basic goal in this exercise is to implement and test a function named \emph{timesPlus}, which takes in two integer values and returns a pair of integer values.

\begin{align*}
timesPlus~x~y = (x \times y, x+y)
\end{align*}

\subsection{Test cases}
\label{subsec:2.5.1-test-cases}

According to project requirements, we should run our functions on test cases below:
\begin{lstlisting}[frame=TB]

(******************************************************************************)
(* Test Cases                                                                 *)
(******************************************************************************)
timesPlus 100 27;
timesPlus 10 26;
timesPlus 1 25;
timesPlus 2 24;
timesPlus 30 23;
timesPlus 50 200;

\end{lstlisting}

\section{Relevant Code}
\label{sec:2.5.1-relevant-code}

We will define our function \emph{timesPlus} as below:

\lstset{frameround = fttt}
\begin{lstlisting}[frame= trBL]
(*  Name: Jinhao Wei      *)
(*  Email: jwei15@syr.edu *)
fun timesPlus x y = (x*y, x+y);
\end{lstlisting}

\section{Test Results}
\label{sec:2.5.1-test-results}

If we send the above relevant code and test cases regions in the HOL, we will see a transcipt as below
\setcounter{sessioncount}{0}
\begin{session}
\begin{scriptsize}
\begin{verbatim}

---------------------------------------------------------------------
       HOL-4 [Kananaskis 11 (stdknl, built Sat Aug 19 09:30:06 2017)]

       For introductory HOL help, type: help "hol";
       To exit type <Control>-D
---------------------------------------------------------------------
> > > > # # val timesPlus = fn: int -> int -> int * int
> > # # # val it = (2700, 127): int * int
> val it = (260, 36): int * int
> val it = (25, 26): int * int
> val it = (48, 26): int * int
> val it = (690, 53): int * int
> val it = (10000, 250): int * int
> >
*** Emacs/HOL command completed ***

>

\end{verbatim}
\end{scriptsize}
\end{session}

\chapter{Exercise 3.4.1}
\label{cha:exercise-3.4.1}
\section{Problem Statement}
\label{sec:3.4.1-problem-statement}
In this problem, we focus on pattern matching in ML. We will use pattern matching to exact values from list and tuple. Our specific tasks are to produce expressions that

\begin{enumerate}
\item assign values to $listA$, a list of pairs
\item assign values to $e1B$, a pair, and $listB$, a list of pairs, using pattern matching
\item assign values to $elC1$,  $elC1$, $elC2$, $elC3$, $elC4$ and $elC5$ as they are specified, using pattern matching
\end{enumerate}

\section{Relevant Code}
\label{sec:3.4.1-relevant-code}

According to the requirements of this problem, we will need to define \emph{listA}, then we will attempt to "extract" some values out of \emph{listA}, using pattern matching. Please refer to the code below:
\lstset{frameround = ftttt, framexrightmargin = 0em}
\begin{lstlisting}[frame = trBL]
(****************************************************************************)
(*        Exercise: 3.4.1                                                   *)
(*        Author: Jinhao Wei                                                *)
(*        Date: January 29, 2019                                            *)
(****************************************************************************)
val listA = [(0,"Alice"), (1, "Bob"), (3, "Carol"), (4,"Dan")];
val elB::listB = listA;
val (elC1, elC2) = elB;
val (elC3::(elC4::(elC5::[]))) = listB;
\end{lstlisting}

\section{Test Results}
\label{sec:3.4.1-test-results}
If we send the above region to HOL,  we will see result as below:
\setcounter{sessioncount}{0}
\begin{session}
\begin{scriptsize}
\begin{verbatim}

> > > > val listA = [(0, "Alice"), (1, "Bob"), (3, "Carol"), (4, "Dan")]:
   (int * string) list
val elB = (0, "Alice"): int * string
val listB = [(1, "Bob"), (3, "Carol"), (4, "Dan")]: (int * string) list
val elC1 = 0: int
val elC2 = "Alice": string
val elC3 = (1, "Bob"): int * string
val elC4 = (3, "Carol"): int * string
val elC5 = (4, "Dan"): int * string
val it = (): unit
>
*** Emacs/HOL command completed ***

\end{verbatim}
\end{scriptsize}
\end{session}

\chapter{Exercise 3.4.2}
\label{cha:exercise-3.4.2}

\section{Problem Statement}
\label{sec:3.4.2-problem-statement}
In this problem, we will set serveral values in emacs, and evaluate them respectively under HOL environment. Finally we will check and analyze the results.

\section{Relevant Code}
\label{sec:3.4.2-relevant-code}

\lstset{frameround = ftttt, framexrightmargin = 0em}
\begin{lstlisting}[frame = trBL]

(****************************************************************************)
(*  Exercise: 3.4.2                                                         *)
(*  Author: Jinhao Wei                                                      *)
(*  Date: January 29, 2019                                                  *)
(****************************************************************************)

val (x1,x2,x3) = (1,true,"Alice");
val pair1 = (x1,x3);
val list1 = [0,x1,2];
val list2 = [x2,x1];
(*The line above should fail*)
(*x2 and x1 have different data type so they don't form a list*)

val list3 = (1 :: [x3]);
(*The line above should fail*)
(*int value can't be inserted to the front of a char list*)
\end{lstlisting}

\section{Test Results and Analysis}
\label{sec:3.4.2-test-results}

According to the requirement, we should evaluate the values one by one and check the results. Therefore, I did not send the whole region to HOL, I ran each of them one after another.

The first three evaluation was quite successful. The first case is just a simple pattern matching. The second case is a tuple which can receive any different data types. As for the third case, all items in the list have the same data type, so the evaluation was successful.
\setcounter{sessioncount}{0}
\begin{session}
\begin{scriptsize}
\begin{verbatim}

> > > > val (x1,x2,x3) = (1,true,"Alice");
val x1 = 1: int
val x2 = true: bool
val x3 = "Alice": string
>
> val pair1 = (x1,x3);
val pair1 = (1, "Alice"): int * string
>
> val list1 = [0,x1,2];
val list1 = [0, 1, 2]: int list
>

\end{verbatim}
\end{scriptsize}
\end{session}

\newpage
The following case failed to be evaluated, this is because all elements in a list should have the same data type. Howerver, from previous calculation we know that $x1$ is of type \emph{int} while $x2$ is \emph{bool}. So they can not make a list.
\begin{session}
\begin{scriptsize}
\begin{verbatim}

> val list2 = [x2,x1];
poly: : error: Elements in a list have different types.
   Item 1: x2 : bool
   Item 2: x1 : int
   Reason:
      Can't unify bool (*In Basis*) with int (*In Basis*)
         (Different type constructors)
Found near [x2, x1]

\end{verbatim}
\end{scriptsize}
\end{session}

The following case also failed, this is because $1$ is a data of type \emph{int} while $[x3]$ is a list of \emph{string}, and a \emph{int} type value can not be insert to the front of a \emph{string} list. Therefore the calculation failed.
\begin{session}
\begin{scriptsize}
\begin{verbatim}

>
> val list3 = (1 :: [x3]);
poly: : error: Type error in function application.
   Function: :: : int * int list -> int list
   Argument: (1, [x3]) : int * string list
   Reason:
      Can't unify int (*In Basis*) with string (*In Basis*)
         (Different type constructors)
Found near (1 :: [x3])
Static Errors

\end{verbatim}
\end{scriptsize}
\end{session}

\appendix{}
\chapter{Source Code for Exercise 2.5.1}
\label{appendix:A}
The following code is from \emph{ex-2-5-1.sml}
\lstinputlisting{../ML/ex-2-5-1.sml}
\chapter{Source Code for Exercise 3.4.1}
\label{appendix:B}
The following code is from \emph{ex-3-4-1.sml}
\lstinputlisting{../ML/ex-3-4-1.sml}
\chapter{Source Code for Exercise 3.4.2}
\label{appendix:C}
The following code is from \emph{ex-3-4-2.sml}
\lstinputlisting{../ML/ex-3-4-2.sml}
\end{document}